Skip to content

ai: add custom-header support to Bedrock provider#5178

Merged
badlogic merged 1 commit into
earendil-works:mainfrom
stephanmck:bedrock-custom-headers-pr
May 29, 2026
Merged

ai: add custom-header support to Bedrock provider#5178
badlogic merged 1 commit into
earendil-works:mainfrom
stephanmck:bedrock-custom-headers-pr

Conversation

@stephanmck

Copy link
Copy Markdown
Contributor

What

Honour StreamOptions.headers in the AWS Bedrock provider. d2be648 added headers to every provider except Bedrock, deferred with "Bedrock not supported (uses AWS SDK auth)". This closes that gap so headers is meaningful on all six routes.

Why

Corporate / proxy gateways fronting Bedrock often want per-request HTTP-header tagging for cost attribution, audit, or routing (e.g. an X-* tenant or cost tag on the wire). Today callers can attach those to Anthropic / OpenAI / OpenAI-Responses / Google / Google-Vertex via options.headers, but the Bedrock route is a blind spot. The "uses AWS SDK auth" note is accurate for the auth header itself; it does not preclude attaching additional custom headers alongside it.

How

  • In streamBedrock, after constructing BedrockRuntimeClient, attach a Smithy build-step middleware that merges options.headers into request.headers.
  • build step (not finalizeRequest) so the injected headers are covered by the SigV4 signature. Headers added after signing would be rejected by AWS.
  • Reserved-header guard: silently skip x-amz-*, authorization, and host (case-insensitive) so a caller can't desync SigV4 or strip the Bearer token from feat(bedrock): support Bearer token auth for Converse API #3125.
  • No-op when headers is empty/undefined — the middleware is only attached when there is at least one header, so there is zero overhead on the common path.
  • streamSimpleBedrock already forwards headers via buildBaseOptions; kept as-is and covered by a regression test.
  • Updated the StreamOptions.headers JSDoc to drop the Bedrock caveat and document the new behaviour and the reserved-header guard.

The middleware reuses the same BedrockRuntimeClient.middlewareStack injection pattern previously used on this client in #3125.

Tests

New packages/ai/test/bedrock-custom-headers.test.ts, mocking @aws-sdk/client-bedrock-runtime in the style of bedrock-endpoint-resolution.test.ts (no real AWS credentials):

  • happy path — a custom header reaches request.headers, registered on the build step with priority: "low";
  • reserved-header guard — authorization / x-amz-* left untouched (case-insensitive) while an allowed header is added;
  • no-op — no middleware registered when headers is undefined or {}, plus a structural pass-through when the request has no headers;
  • streamSimpleBedrock forwards headers end-to-end.

npm run check is clean.

Suggested changelog entry (for a maintainer to add under ### Added — I have not touched CHANGELOG.md)

Honour StreamOptions.headers in the AWS Bedrock provider via a Smithy build-step middleware, with a reserved-header guard (x-amz-* / authorization / host).

closes #5123

Honour StreamOptions.headers in the Bedrock provider by attaching a
Smithy build-step middleware that merges caller headers into the
request before SigV4 signing. Reserved headers (x-amz-*, authorization,
host) are silently skipped to preserve signing and the bearer-token
auth path. No-op when no headers are supplied. Updates the
StreamOptions.headers JSDoc to drop the Bedrock caveat.
@badlogic badlogic marked this pull request as ready for review May 29, 2026 09:15
@badlogic badlogic merged commit 3d1d18f into earendil-works:main May 29, 2026
2 checks passed
@seanamh420

Copy link
Copy Markdown

This is a great addition, I can maybe stop hand rolling my Bedrock provider! Will check it out and feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Honor options.headers in Amazon Bedrock provider

3 participants