Repository navigation
feat(ai): resolve Bedrock credentials through the AWS default chain - #47436
Merged
Merged
Conversation
Bedrock routes only accepted static SigV4 credentials or a bearer apiKey, so SSO, shared-config profiles, web identity, and instance credentials were unusable and STS-vended credentials could not refresh. - SigV4 auth accepts an Effect credential source resolved per request - BedrockAuth.defaultChain lazily loads @aws-sdk/credential-providers and memoizes fromNodeProviderChain so the SDK owns caching and refresh - Facades fall back to AWS_BEARER_TOKEN_BEDROCK, then static credentials, then the default chain; region falls back to AWS_REGION and AWS_DEFAULT_REGION and is applied to the SigV4 scope - Settings accept profile for the default chain; auth: sigv4 ignores an ambient bearer token
Memoizing fromNodeProviderChain per model pinned shared-config credentials without an expiration for the process lifetime, so keys rotated on disk by SSO tooling were never re-read. Build the chain per request instead so the default chain always reflects the current on-disk and environment state.
rekram1-node
force-pushed
the
bedrock-auth
branch
from
September 5, 2026 05:29
560063f to
1306934
Compare
Browser conditions resolve @smithy/core/config to its browser build, which stubs node-only exports and breaks the AWS credential chain with "parseKnownFiles is not a function". The release build already uses the default node conditions.
Only Settings could request sigv4 to ignore an ambient AWS_BEARER_TOKEN_BEDROCK, leaving programmatic configure callers without a way to opt out. Move the mode and its validation onto Config so both paths share one constructor.
This was referenced Sep 6, 2026
jinhuang712
pushed a commit
to jinhuang712/opencode
that referenced
this pull request
Sep 26, 2026
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.
Problem
The native Bedrock routes in
packages/aionly accepted a static{ accessKeyId, secretAccessKey, sessionToken }struct or a bearerapiKey. Nothing readAWS_PROFILE,~/.awsshared config, the SSO cache, web identity tokens, or instance/container metadata, and STS-vended credentials could not refresh because they were captured once atconfigure(). V1 delegated all of this to the AI SDK'scredentialProvider; V2 dropped the AI SDK for Bedrock but never replaced that layer.Changes
BedrockAuth.sigV4accepts aCredentialSource(static orEffect<Credentials>) resolved before every request.BedrockAuth.defaultChain({ region, profile? })lazily imports@aws-sdk/credential-providersand runs a freshfromNodeProviderChainon every request. The SDK memoizes credentials that carry noexpirationfor the life of the provider, which pinned shared-config keys rotated on disk by SSO tooling (fix(core): Bedrock SDK/language model cache has no TTL — STS tokens expire mid-session #30940); a per-request chain always re-reads them. Mirrors the Vertex ADC pattern ingoogle-vertex-shared.ts.BedrockAuth.resolveAuthcentralizes precedence for Converse and Mantle:apiKey ?? AWS_BEARER_TOKEN_BEDROCK(bearer) → explicit static credentials → default chain.auth: "sigv4"in settings ignores an ambient bearer token.BedrockAuth.resolveRegion:region ?? credentials.region ?? AWS_REGION ?? AWS_DEFAULT_REGION ?? us-east-1, applied to both the endpoint host and the SigV4 scope (Converse previously let them diverge).Settings/Configgainprofile;auth: "bearer" | "sigv4"moves ontoConfigso programmatic callers can also opt out of the ambient bearer token.model(id, settings)is now justconfigure(settings).model(id).devscript drops--conditions=browser: it resolves@smithy/core/configto a browser build that stubs node-only exports and breaks the credential chain (parseKnownFiles is not a function). The release build already uses node conditions.@aws-sdk/credential-providersadded topackages/ai.Chain failures surface as
AIErrorwith anAuthenticationreason.Tests
Authenticationerror (uses a missing profile with IMDS disabled so it is deterministic on any machine).AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKENfor Converse and Mantle, asserting the SigV4 credential scope andx-amz-security-token.AWS_BEARER_TOKEN_BEDROCKprecedence,auth: "sigv4"ignoring it, region env fallbacks, and static credentials taking the configured region for the scope.test/lib/env.tshelper scopesprocess.envoverrides (needed because the AWS SDK readsprocess.envdirectly).Follow-up (separate PR,
packages/core)Wire discovery into
AmazonBedrockPlugin: narrow the models.dev env method toAWS_BEARER_TOKEN_BEDROCKsoAWS_ACCESS_KEY_IDstops being sent as a bearer token, flipactivationtoenabledwhen chain-style env is present, forwardprofilethroughmapBedrockSettings, and delete the dead AI SDK hooks plus the@ai-sdk/amazon-bedrockdependency.