feat(signer): add SigV4 request signing utility#5344
Draft
dreamorosi wants to merge 4 commits into
Draft
Conversation
Add a new `@aws-lambda-powertools/signer` package that signs HTTP requests using the AWS Signature Version 4 (SigV4) signing process. - `SigV4Signer` (/sigv4): signs web-standard `Request` objects, reading credentials and region from the Lambda runtime by default - `createSignedFetcher` (/fetch): drop-in signed `fetch` that consumes a signer - structural `Signer` interface so future variants (e.g. SigV4a) compose without breaking changes - typed errors (/errors): `SignerError`, `SignerConfigError`, `RequestSigningError` - only depends on `@smithy/signature-v4` and `@smithy/types`; uses `node:crypto` for hashing - unit tests with 100% coverage, docs feature page, README, and snippets Closes #2146
- Sha256: use positive condition in ternary (S7735) - fetch: remove unnecessary type assertion (S4325)
- add e2e suite: caller Lambda signs requests against an IAM-protected REST API (mock integration), asserting unsigned->403 and signed->200 across the signing entry points, body/query signing, signer reuse, drop-in fetch, region and credentials options, and the RequestSigningError path for an unreadable body - wire test:e2e* scripts, testing-utils devDep, and vitest e2e timeouts - add packages/signer to the e2e CI matrix - correct the RequestSigningError message and docs: finite streams are buffered and signed fine; only unreadable/non-replayable bodies fail
|
svozza
reviewed
Jun 13, 2026
| this.#hash = | ||
| secret === undefined | ||
| ? createHash('sha256') | ||
| : createHmac('sha256', secret as Uint8Array | string); |
Contributor
There was a problem hiding this comment.
How come we need these casts?
Contributor
Author
There was a problem hiding this comment.
Good question - let me investigate
| const ENVIRONMENT_VARIABLES = process.env; | ||
|
|
||
| beforeEach(() => { | ||
| process.env = { |
Contributor
There was a problem hiding this comment.
Let's use the vitest stubEnv/unstubEnv fucntions
|
|
||
| Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://docs.aws.amazon.com/powertools/typescript/latest/#features). | ||
|
|
||
| You can use the package in both TypeScript and JavaScript code bases. |
Contributor
There was a problem hiding this comment.
Is this necessary? JavaScript is valid TypeScript.
Contributor
Author
There was a problem hiding this comment.
Yes fair, this is a copy of other readme files that used to do this type of statement but agreed I'll remove it
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Changes
This PR introduces a new
@aws-lambda-powertools/signerpackage that signs HTTP requests to AWS services using the AWS Signature Version 4 (SigV4) signing process, so customers can call IAM-authenticated endpoints (API Gateway, Lambda function URLs, AppSync) from within their Lambda functions.The design intentionally splits signing from sending:
SigV4Signer(/sigv4) — signs web-standardRequestobjects and returns a signedRequest. Performs no network I/O. Reads credentials and region from the Lambda runtime environment variables by default (no extra dependencies, no cold-start cost from the credential provider chain).createSignedFetcher(/fetch) — a drop-in signedfetchthat consumes a signer instance and signs each request before sending it. Composes with libraries that accept a customfetch.Requestexposesurl,method, andheadersfor use with any HTTP client (axios, got, interceptors, generated SDK clients).Design decisions worth highlighting for review:
Signerinterface is defined, and the fetcher depends on it (not the concrete class), so a futureSigV4aSignercan be added at a/sigv4asubpath as a non-breaking change with its heavier dependencies isolated to that entry point./sigv4,/fetch,/errors,/types) — no root export — to keep import-level isolation and make future signer variants additive.AWS_SESSION_TOKEN), avoiding a dependency on@aws-sdk/credential-provider-node. Customers can pass explicitcredentials(e.g.fromNodeProviderChain()) for non-Lambda environments.@smithy/signature-v4and@smithy/types; hashing usesnode:crypto(no@aws-crypto/sha256-js). We do not depend on@smithy/protocol-http— the signing process accepts a plain object typed via@smithy/types, and a guard test protects that contract./errors): baseSignerError, plusSignerConfigError(missing region at construction / unresolvable credentials) andRequestSigningError(signing failures, including non-bufferable streaming bodies). Transport errors from the underlyingfetchpropagate untouched.Out of scope / deferred (accommodated by the design): SigV4a, streaming/
UNSIGNED-PAYLOADbodies (would arrive as additive options or a futuresignStreammethod), service auto-detection from the URL, anduriEscapePath/payload-signing knobs.Includes: unit tests with 100% coverage, a feature page (
docs/features/signer.md), package README, doc snippets, navigation/index updates, and thesignersemantic-commit scope.Issue number: closes #2146
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.