Aws Sigv4

The AWS Sigv4 request signature, described here, is what all of the AWS tools (awscli, and also the AWS SDKs) use to authenticate requests and grant access to private resources via the AWS service APIs.

The :aws_sigv4 plugin allows you to use AWS Sigv4 signatures to perform httpx requests to servers which require this authentication method (for example, upload a file to S3).

This is how you can use it:

# downloading a file to the S3 movies bucket

HTTPX.plugin(:aws_sigv4)
     .aws_sigv4_authentication(
       service: "s3",
       region: "eu-west-1",
       username: "YOUR_ACCESS_KEY_ID",
       password: "YOUR_ACCESS_SECRET_KEY"
     ).get("https://movies.s3.eu-west-1.amazonaws.com/movie.mp4")

Session#aws_sigv4_authentication

The #aws_sigv4_authentication will give the session all the data necessary to sign subsequent requests. You can therefore pass the following keyword arguments:

  • :service (required): the service to authenticate the requests in (ex: “s3”);
  • :region (required): the region to authenticate the requests in (ex: “eu-west-1”);
  • :username (default: nil): identifies the user to authenticate (in the case of AWS, that’s the access key id);
  • :password (default: nil): password of the user to authennticate (in the case of AWS, that’s the access secret key);
  • :security_token (default: nil): additional token that is usually sent along with temporary credentials;
  • :credentials (default: nil): can be provided as an alternative to the above, provided that it responds to #username, #password and optionally :security_token;
  • :provider_prefix (default: "aws"): Provider tag used in the signature verification (i.e. "aws_request");
  • :header_provider_field (default: "amz"): The provider field used in the sigv4-related HTTP headers (example: "x-amz-security-token");
  • :unsigned_headers (default: []): HTTP headers that should be excluded from the request signing process (besides the ones ignored by default, like "expect" or "authorization";
  • :apply_checksum_header (default: true): whether to share the content hash in an HTTP header;
  • :algorithm (default: "SHA256") the hashing algorithm used in several steps of the signature;

:aws_sdk_authentication plugin

The :aws_sdk_authentication plugin is a convenience plugin, which requires the aws-sdk-core gem and builds on top of some of its primitives and the :aws_sigv4 plugin to help you manage your AWS resources.

MOVIE = "path/to/movie.mp4"

BUCKET_URL = "https:/movies.s3.eu-west-1.amazonaws.com"

aws_httpx = HTTPX.with(headers: { "content-encoding" => "gzip" })
                 .plugin(:aws_sdk_authentication)
                 .aws_sdk_authentication(service: "s3")

response = aws_httpx.put(BUCKET_URL + "/movie", body: File.new(MOVIE))

This plugin will use aws-sdk-core primitives under-the-hood to get credentials and region information from the environment, and is particularly helpful if your host rotates access keys periodically (ex: AWS STS-generated tokens).

Session#aws_sdk_authentication

Session#aws_sdk_authentication builds on top of aws_sigv4_authentication, and uses the same method signature, with the advantage of having a single required keyword argument: :service.

FAQs

What services use AWS-sigv4 besides AWS?

Both Google Cloud and Outscale support AWS sigv4 authentication method.

Is this supposed to replace “aws-sdk” and “fog” gems?

No. If you use both of those gems and they work for you, keep using them (but consider using aws-sdk, as it’s supported by AWS itself).

But for contained use-cases, such as downloading/uploading to S3, do consider httpx. Those gems are quite heavy and bring with it a lot of dependencies, compared to what you need when using httpx.

Also, multicloud FTW.

Does AWS support HTTP/2?

At the time of editing this wiki, no. AWS supports HTTP/2 only via Cloudfront, so if you’re accessing S3 directly from your backend, it’ll use HTTP/1.1 . GCP does support HTTP/2 though.

Next: GRPC