Skip to content

feat(bedrock): support AWS credentials files#761

Open
HAYDEN-OAI wants to merge 1 commit into
mainfrom
dev/hayden/sdk-80-support-for-aws-credentials-file-java
Open

feat(bedrock): support AWS credentials files#761
HAYDEN-OAI wants to merge 1 commit into
mainfrom
dev/hayden/sdk-80-support-for-aws-credentials-file-java

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown

Fixes SDK-80

Linear: SDK-80 — Support for aws credentials file - Java

Summary

  • add an optional openai-java-bedrock artifact for OpenAI-compatible APIs on Amazon Bedrock
  • resolve AWS credentials through explicit keys, named profiles, custom providers, or the standard AWS SDK v2 credential chain, including shared credentials and config files
  • sign every sync and async request attempt with SigV4 so retries use fresh credentials
  • retain Bedrock bearer-token authentication, with explicit precedence and validation across authentication modes
  • disable redirects for signed requests and redact AWS authorization/session headers from debug logs
  • add setup documentation, Java examples, cross-SDK signing fixtures, and focused unit/integration coverage

Why

Java users currently need to load AWS credentials themselves before using Bedrock's OpenAI-compatible endpoint. This adds first-class support for the standard AWS credentials workflow, including ~/.aws/credentials, named profiles, workload credentials, and runtime identities, while keeping AWS dependencies isolated to an optional module.

Implementation notes

  • introduces a full-request authentication hook immediately inside the retry boundary, before transport logging
  • resolves and signs credentials independently for each attempt
  • rejects non-replayable bodies, conflicting auth modes, cross-origin authentication, and canonical endpoint/region mismatches
  • keeps AWS SDK v2 and its optional STS/SSO provider-chain support out of the core artifact

Validation

  • 23 Bedrock unit and WireMock integration tests
  • 77 focused core tests covering client options, retries, and logging
  • Bedrock and core lint checks
  • example Java and Kotlin compilation
  • local Maven publication plus a Java 8 consumer smoke compile
  • ad hoc JaCoCo: 80.1% module line coverage, 87.9% branch coverage, and 96.3% line coverage for the authentication package

@HAYDEN-OAI HAYDEN-OAI requested a review from a team as a code owner June 22, 2026 18:34

@apcha-oai apcha-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[codex] Two non-blocking lifecycle comments from the requested review.

CompletableFuture.supplyAsync { authenticate(request) }

override fun close() {
(credentialsProvider as? AutoCloseable)?.close()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[codex] Non-blocking: what ownership semantics do we want for a caller-supplied AwsCredentialsProvider? This closes any provider implementing AutoCloseable, including one shared with another client, but awsCredentialsProvider(...) does not currently say that ownership transfers. Could we either close only providers created internally, or explicitly document that the Bedrock client takes ownership and closes the supplied provider?

}

override fun close() {
authenticator.close()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[codex] Non-blocking hardening: if authenticator.close() throws, delegate.close() is skipped and the underlying transport resources may remain open. Could we ensure the delegate is closed in a finally block (preserving/suppressing both exceptions as appropriate)?

@apcha-oai apcha-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[codex] Adding the missed P1 inline comment.

normalizedRegion
?: normalizeEnvironment(getenv("AWS_REGION"))
?: normalizeEnvironment(getenv("AWS_DEFAULT_REGION"))
?: regionProvider()?.id()

@apcha-oai apcha-oai Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[codex] [P2] Could we resolve the default AWS region lazily? With an explicit baseUrl(...) plus apiKey/bedrockTokenProvider, or baseUrl(...) plus skipAuth(true), this still invokes DefaultAwsRegionProviderChain. That chain may consult shared config and EC2 metadata even though these modes do not need a SigV4 region, adding unexpected I/O or startup delay. I’d only invoke it when deriving the regional default endpoint or constructing the SigV4 authenticator, and add a test with a throwing regionProvider for the explicit-base-URL bearer/skip-auth cases.

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.

2 participants