Menu
Open source RSS

SignatureV4

Caution

In some cases, using this library's operations might impact performance and skew your test results.

To ensure accurate results, consider executing these operations in the setup and teardown lifecycle functions. These functions run before and after the test run and have no impact on the test results.

With SignatureV4, you can produce authenticated HTTP requests to AWS services. Namely, it lets you sign and pre-sign requests to AWS services using the Signature V4 algorithm. The sign operation produces a signed request with authorization information stored in its headers. The presign operation produces a pre-signed request with authorization information stored in its query string parameters.

SignatureV4 is included in both the dedicated jslib signature.js bundle and the aws.js one, containing all the service’s clients.

Instantiating a new SignatureV4 requires a single options object argument with the following properties:

PropertyTypeDescription
servicestringthe AWS region to sign or pre-sign requests for. As described by Amazon AWS docs
regionstringthe AWS service to sign or pre-sign requests for. As described by Amazon AWS docs]
credentialsan object with accessKeyId, secretAccessKey, and optional sessionToken propertiesthe AWS credentials to sign or pre-sign requests with.
uriEscapePathbooleanWhether to uri-escape the request URI path as part of computing the canonical request string. As of late 2017, this is required for every AWS service except Amazon S3.
applyChecksumbooleanWhether to calculate a checksum of the request body and include it as either a request header (when signing) or as a query string parameter (when pre-signing). This is required for AWS Glacier and Amazon S3 and optional for every other AWS service as of late 2017.

Methods

MethodDescription
sign()Signs an authenticated HTTP request using the AWS signature v4 algorithm
presign()Produces an authenticated pre-signed URL using the AWS signature v4 algorithm

Throws

SignatureV4 methods throw errors on failure.

ErrorCondition
InvalidSignatureErrorwhen invalid credentials were provided.

Example

JavaScript
import http from 'k6/http';

import {
  AWSConfig,
  Endpoint,
  SignatureV4,
} from 'https://jslib.k6.io/aws/0.12.3/signature.js';

const awsConfig = new AWSConfig({
  region: __ENV.AWS_REGION,
  accessKeyId: __ENV.AWS_ACCESS_KEY_ID,
  secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY,
  sessionToken: __ENV.AWS_SESSION_TOKEN,
});

export default function () {
  /**
   * In order to be able to sign an HTTP request's,
   * we need to instantiate a SignatureV4 object.
   */
  const signer = new SignatureV4({
    service: 's3',
    region: awsConfig.region,
    credentials: {
      accessKeyId: awsConfig.accessKeyId,
      secretAccessKey: awsConfig.secretAccessKey,
      sessionToken: awsConfig.sessionToken,
    },

    /**
     * Whether the URI should be escaped or not.
     */
    uriEscapePath: false,

    /**
     * Whether or not the body's hash should be calculated and included
     * in the request.
     */
    applyChecksum: true,
  });

  /**
   * The sign operation will return a new HTTP request with the
   * AWS signature v4 protocol headers added. It returns an Object
   * implementing the SignedHTTPRequest interface, holding a `url` and a `headers`
   * properties, ready to use in the context of k6's http call.
   */
  const signedRequest = signer.sign(
    /**
     * HTTP request description
     */
    {
      /**
       * The HTTP method we will use in the request.
       */
      method: 'GET',

      /**
       * The endpoint of the service we will be making the request to.
       *
       * The endpoint is instantiated from a URL string, of the format: `{scheme}://{hostname}[:{port}]`
       */
      endpoint: new Endpoint('https://s3.us-east-1.amazonaws.com'),

      /**
       * The path of the request.
       */
      path: '/my-bucket/bonjour.txt',

      /**
       * The query parameters to include in the request.
       */
      query: {
        'abc': '123',
        'easy as': ['do', 're', 'mi'],
      },

      /**
       * The headers we will be sending in the request.
       */
      headers: {},

      /**
       * The body of the request.
       */
      body: null,
    },

    /**
     * (optional) Signature operation options allows to override the
     * SignatureV4's options in the context of this specific request.
     */
    {
      /**
       * The date and time to be used as signature metadata. This value should be
       * a Date object, a unix (epoch) timestamp, or a string that can be
       * understood by the JavaScript `Date` constructor.If not supplied, the
       * value returned by `new Date()` will be used.
       */
      signingDate: new Date(),

      /**
       * The service signing name. It will override the service name of the signer
       * in current invocation
       */
      signingService: 's3',

      /**
       * The region name to sign the request. It will override the signing region of the
       * signer in current invocation
       */
      signingRegion: 'us-east-1',
    }
  );

  http.get(signedRequest.url, { headers: signedRequest.headers });
}