Tesla AWS Signer
A Tesla plug for signing HTTP requests with AWS Signature Version 4.
Installation
def deps do
[
{:aws_signer, "~> 1.0"}
]
end
Usage
defmodule MyHttpClient do
use Tesla
plug Tesla.Middleware.BaseUrl, "https://my-aws-elasticsearch.eu-central-1.es.amazonaws.com"
plug Tesla.Middleware.JSON
plug AwsSigner.TeslaMiddleware, options
adapter Tesla.Adapter.Hackney, path_encode_fun: &AwsSigner.Util.encode_rfc3986/1
end
where options is a keyword list:
[
auth_method: :assume_role # (required) see below for possible values
region: "eu-central-1", # (required)
service: "es", # (required)
arn: "arn:aws:iam::123..." # (required)
session_name: "..." # (optional) aws session name
access_key_id: "...", # required if auth_method is :assume_role
secret_access_key: "...", # required if auth_method is :assume_role
web_identity_token: "..." # required if auth_method is :assume_role_with_web_identity
]
auth_method can be one of:
:instance_profile:assume_role:assume_role_with_web_identity
You can read more about AWS STS and AWS Instance Profiles in the AWS official docs.
Logging
For debugging purposes, you can enable logging all requests to AWS STS service (made when issuing tokens). Do so with caution, AWS keys are not something you want in your logs (you know, security).
In you app's config:
config :aws_signer, logging: true
Caching
AWS keys will be re-used on subsequent requests to avoid unnecessary network round-trips.
Caveats
HTTP adapter
Make sure your HTTP adapter's path encoding follows the RFC3986 standard as expected by AWS. If you use hackney, you must instruct it to use an external function for that purpose (as shown above in the Usage example):
adapter Tesla.Adapter.Hackney, path_encode_fun: &AwsSigner.Util.encode_rfc3986/1
Supported auth methods
This library provides basic support for AWS AssumeRole, AssumeRoleWithWebIdentity and InstanceProfile credential providers. More providers should be straightforward to add, pull requests are welcome.
Supported AWS services
This has been tested with es service only (the AWS keyword for Elasticsearch service).
It should work for other AWS services, but there may be exceptions -- like the s3 service, which according to the AWS docs expects double-encoded path segments. Support for this should be easy to add, pull requests are welcome.
Also, keep in mind I have not personally tested the assume_role_with_web_identity auth method in production yet, I'd appreciate any feedback.
Contributing
Everyone is welcome to contribute. When submitting a Pull Request, please make sure to:
- Put a clear, concise reasoning for your change in the PR
- Use
mix formatfor code formatting - Cover new/changed functionality with tests
- Ensure all tests pass