AWS Signature Version 4 request signer based on AWS Common Runtime for high-performance Node.js signing operations
npx @tessl/cli install tessl/npm-aws-sdk--signature-v4-crt@3.879.0AWS Signature V4 CRT provides high-performance AWS request signing using the AWS Common Runtime (CRT). This Node.js-only library implements AWS Signature Version 4 (SigV4) and SigV4A (asymmetric) algorithms for authenticating AWS API requests with enhanced performance through native CRT modules.
npm install @aws-sdk/signature-v4-crtimport { CrtSignerV4, AwsSigningAlgorithm } from "@aws-sdk/signature-v4-crt";
import { auth as crtAuth } from "@aws-sdk/crt-loader";For CommonJS:
const { CrtSignerV4 } = require("@aws-sdk/signature-v4-crt");
const { auth: crtAuth } = require("@aws-sdk/crt-loader");import { CrtSignerV4 } from "@aws-sdk/signature-v4-crt";
import { Sha256 } from "@aws-crypto/sha256-js";
// Create a signer instance
const signer = new CrtSignerV4({
credentials: {
accessKeyId: "AKIAIOSFODNN7EXAMPLE",
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
},
region: "us-east-1",
service: "s3",
sha256: Sha256
});
// Sign a request
const request = {
method: "GET",
protocol: "https:",
hostname: "s3.amazonaws.com",
path: "/my-bucket/my-object",
headers: {
host: "s3.amazonaws.com"
}
};
const signedRequest = await signer.sign(request);
// Or presign a URL
const presignedRequest = await signer.presign(request, {
expiresIn: 3600 // 1 hour
});AWS Signature V4 CRT is built around several key components:
RequestSigner, RequestPresigner)Core request signing functionality for AWS API authentication using headers.
class CrtSignerV4 {
constructor(init: CrtSignerV4Init & SignatureV4CryptoInit);
/**
* Signs HTTP requests with AWS Signature V4 using headers
* @param toSign - HTTP request to sign
* @param options - Optional signing configuration
* @returns Promise resolving to signed HTTP request
*/
sign(toSign: HttpRequest, options?: RequestSigningArguments): Promise<HttpRequest>;
/**
* Signs requests with alternate credentials different from constructor credentials
* @param toSign - HTTP request to sign
* @param credentials - AWS credentials to use for signing
* @param options - Optional signing configuration
* @returns Promise resolving to signed HTTP request
*/
signWithCredentials(
toSign: HttpRequest,
credentials: AwsCredentialIdentity,
options?: RequestSigningArguments
): Promise<HttpRequest>;
}
interface CrtSignerV4Init extends SignatureV4Init {
/**
* The Algorithm used for the signer. Includes: SigV4, SigV4Asymmetric.
* @default SigV4
*/
signingAlgorithm?: AwsSigningAlgorithm;
}Usage Example:
const signer = new CrtSignerV4({
credentials: myCredentials,
region: "us-west-2",
service: "dynamodb",
sha256: Sha256,
signingAlgorithm: crtAuth.AwsSigningAlgorithm.SigV4
});
const signedRequest = await signer.sign({
method: "POST",
protocol: "https:",
hostname: "dynamodb.us-west-2.amazonaws.com",
path: "/",
headers: {
"Content-Type": "application/x-amz-json-1.0",
"X-Amz-Target": "DynamoDB_20120810.ListTables"
},
body: "{}"
});Pre-signs HTTP requests for URL-based authentication, creating signed URLs that can be used later.
class CrtSignerV4 {
/**
* Presigns HTTP requests with AWS Signature V4 for URL-based authentication
* @param originalRequest - HTTP request to presign
* @param options - Optional presigning configuration including expiration
* @returns Promise resolving to presigned HTTP request with query parameters
*/
presign(
originalRequest: HttpRequest,
options?: RequestPresigningArguments
): Promise<HttpRequest>;
}Usage Example:
const presignedRequest = await signer.presign({
method: "GET",
protocol: "https:",
hostname: "s3.amazonaws.com",
path: "/my-bucket/document.pdf",
headers: {
host: "s3.amazonaws.com"
}
}, {
expiresIn: 7200, // 2 hours
signingDate: new Date()
});
// The presigned URL will be in presignedRequest.query
const url = `https://${presignedRequest.hostname}${presignedRequest.path}?${new URLSearchParams(presignedRequest.query)}`;Test-only verification methods for SigV4A signature validation with asymmetric keys.
class CrtSignerV4 {
/**
* Test-only API for verifying SigV4A signature validation
* @param request - The original request used for signing
* @param signature - The actual signature computed from previous signing
* @param expectedCanonicalRequest - Expected result when building canonical request
* @param eccPubKeyX - X coordinate of the public ECC key
* @param eccPubKeyY - Y coordinate of the public ECC key
* @param options - Request signing arguments used for signing
* @returns Promise resolving to true if verification succeeds
*/
verifySigv4aSigning(
request: HttpRequest,
signature: string,
expectedCanonicalRequest: string,
eccPubKeyX: string,
eccPubKeyY: string,
options?: RequestSigningArguments
): Promise<boolean>;
/**
* Test-only API for verifying SigV4A presigned URL validation
* @param request - The original request used for presigning
* @param signature - The signature from presigned URL
* @param expectedCanonicalRequest - Expected canonical request
* @param eccPubKeyX - X coordinate of the public ECC key
* @param eccPubKeyY - Y coordinate of the public ECC key
* @param options - Request presigning arguments used
* @returns Promise resolving to true if verification succeeds
*/
verifySigv4aPreSigning(
request: HttpRequest,
signature: string | Array<string> | null,
expectedCanonicalRequest: string,
eccPubKeyX: string,
eccPubKeyY: string,
options?: RequestPresigningArguments
): Promise<boolean>;
}type AwsSigningAlgorithm = crtAuth.AwsSigningAlgorithm;This type represents the signing algorithms supported by CRT. The available values are accessed through the imported CRT authentication module:
crtAuth.AwsSigningAlgorithm.SigV4 - Standard Signature Version 4crtAuth.AwsSigningAlgorithm.SigV4Asymmetric - Signature Version 4A (asymmetric)interface HttpRequest {
method: string;
protocol?: string;
hostname?: string;
port?: number;
path: string;
headers: HeaderBag;
body?: any;
query?: QueryParameterBag;
}
interface HeaderBag {
[name: string]: string;
}
interface QueryParameterBag {
[key: string]: string | Array<string> | null;
}
interface AwsCredentialIdentity {
accessKeyId: string;
secretAccessKey: string;
sessionToken?: string;
}
interface RequestSigningArguments {
signingDate?: Date;
signingRegion?: string;
signingService?: string;
signableHeaders?: Set<string>;
unsignableHeaders?: Set<string>;
}
interface RequestPresigningArguments extends RequestSigningArguments {
expiresIn?: number;
}
interface SignatureV4Init {
credentials: AwsCredentialIdentity | Provider<AwsCredentialIdentity>;
region: string | Provider<string>;
service: string;
applyChecksum?: boolean;
uriEscapePath?: boolean;
}
interface SignatureV4CryptoInit {
sha256: any; // Cryptographic hash function (e.g., from @aws-crypto/sha256-js)
}
type Provider<T> = T | (() => T) | (() => Promise<T>);The library throws errors in the following scenarios:
x-amzn-trace-id, user-agent)// Example error handling
try {
const signedRequest = await signer.sign(request, {
signableHeaders: new Set(["x-amzn-trace-id"]) // This will throw
});
} catch (error) {
console.error("Signing failed:", error.message);
// "internal check (x-amzn-trace-id, user-agent) is not supported to be included to sign with CRT."
}
try {
const presignedRequest = await signer.presign(request, {
expiresIn: 8 * 24 * 60 * 60 // 8 days - will throw
});
} catch (error) {
console.error("Presigning failed:", error.message);
// "Signature version 4 presigned URLs must have an expiration date less than one week in the future"
}