Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,35 @@ ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
ChatCompletion chatCompletion = client.chat().completions().create(params);
```

## Amazon Bedrock

Use the optional `openai-java-bedrock` artifact to call OpenAI-compatible APIs on Amazon Bedrock
with normal AWS credentials:

<!-- x-release-please-start-version -->

```kotlin
implementation("com.openai:openai-java-bedrock:4.41.0")
```

<!-- x-release-please-end -->

```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.BedrockOpenAIOkHttpClient;

// Uses the standard AWS credential chain, including environment credentials,
// ~/.aws/credentials, AWS_PROFILE, workload roles, and instance metadata.
OpenAIClient client = BedrockOpenAIOkHttpClient.builder()
.awsRegion("us-east-1")
.build();
```

Requests are signed with fresh AWS credentials on every attempt. Existing
`AWS_BEARER_TOKEN_BEDROCK` bearer credentials remain supported as a compatibility fallback. See
the [Amazon Bedrock guide](bedrock.md) for named profiles, temporary credentials, custom credential
providers, async streaming, precedence rules, and security guidance.

## Client configuration

Configure the client using system properties or environment variables:
Expand Down
128 changes: 128 additions & 0 deletions bedrock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# OpenAI on Amazon Bedrock

The optional `openai-java-bedrock` artifact configures the standard OpenAI Java client for the
OpenAI-compatible Amazon Bedrock Mantle endpoint. It uses the AWS SDK for Java 2.x credential chain
and signs the final HTTP request with SigV4 on every attempt.

## Installation

Use this artifact instead of adding AWS dependencies to the base OpenAI package yourself.

<!-- x-release-please-start-version -->

```kotlin
implementation("com.openai:openai-java-bedrock:4.41.0")
```

```xml
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java-bedrock</artifactId>
<version>4.41.0</version>
</dependency>
```

<!-- x-release-please-end -->

## Standard AWS credentials

Configure AWS credentials as you normally would, then provide the region:

```java
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.BedrockOpenAIOkHttpClient;

OpenAIClient client = BedrockOpenAIOkHttpClient.builder()
.awsRegion("us-east-1")
.build();
```

The default AWS chain supports system properties, `AWS_ACCESS_KEY_ID`,
`AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`, `~/.aws/credentials`, `~/.aws/config`,
`AWS_PROFILE`, IAM Identity Center (SSO), assume-role and web-identity profiles, container
credentials, and instance-profile credentials. The SDK resolves fresh credentials and signs again
before every retry.

Region resolution follows this order:

1. `awsRegion(...)`
2. `AWS_REGION`
3. `AWS_DEFAULT_REGION`
4. the AWS SDK's default region provider chain

Base URL resolution follows this order:

1. `baseUrl(...)`
2. `AWS_BEDROCK_BASE_URL`
3. `https://bedrock-mantle.{region}.api.aws/openai/v1`

The `/openai/v1` route and the `bedrock-mantle` SigV4 service name are intentional.

## Named profile

```java
OpenAIClient client = BedrockOpenAIOkHttpClient.builder()
.awsRegion("us-east-1")
.awsProfile("production")
.build();
```

## Explicit temporary credentials

Prefer profiles and workload roles in production. Explicit credentials are useful for tests and
short-lived credentials obtained elsewhere:

```java
OpenAIClient client = BedrockOpenAIOkHttpClient.builder()
.awsRegion("us-east-1")
.awsAccessKeyId(accessKeyId)
.awsSecretAccessKey(secretAccessKey)
.awsSessionToken(sessionToken)
.build();
```

For refreshable credentials, pass an AWS SDK `AwsCredentialsProvider`:

```java
OpenAIClient client = BedrockOpenAIOkHttpClient.builder()
.awsRegion("us-east-1")
.awsCredentialsProvider(credentialsProvider)
.build();
```

## Bearer-token compatibility

`AWS_BEARER_TOKEN_BEDROCK` remains supported for compatibility and takes precedence over the
default AWS chain. An explicit AWS credential mode takes precedence over that environment
variable. You can also provide a bearer credential directly:

```java
OpenAIClient client = BedrockOpenAIOkHttpClient.builder()
.awsRegion("us-east-1")
.apiKey(bedrockBearerToken)
.build();
```

Explicit bearer and AWS credential modes are mutually exclusive.

## Async and streaming responses

The same client configuration supports asynchronous and streaming calls:

```java
OpenAIClientAsync client = BedrockOpenAIOkHttpClient.builder()
.awsRegion("us-east-1")
.build()
.async();
```

Response streaming is supported. SigV4 request bodies must be replayable so the SDK can hash them
and safely retry; one-shot streaming request bodies are rejected before network I/O.

## Security

- Do not ship AWS credentials in browser or untrusted client applications.
- Prefer temporary credentials, roles, profiles, and workload identities over long-lived keys.
- Do not log access keys, secret keys, session tokens, bearer tokens, or signed authorization
headers. The SDK redacts `Authorization` and `X-Amz-Security-Token` from its HTTP logs.
- OpenAI workload identity federation and AWS Bedrock SigV4 are separate authentication systems.
40 changes: 40 additions & 0 deletions openai-java-bedrock/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
plugins {
id("openai.kotlin")
id("openai.publish")
}

dependencies {
api(project(":openai-java-client-okhttp"))

// Keep AWS dependencies isolated to this optional Bedrock artifact.
api(platform("software.amazon.awssdk:bom:2.46.8"))
api("software.amazon.awssdk:auth")
api("software.amazon.awssdk:regions")

implementation("software.amazon.awssdk:http-client-spi")
implementation("com.squareup.okhttp3:okhttp:4.12.0")

// Optional provider-chain branches loaded by the AWS SDK at runtime for web identity,
// assume-role, and IAM Identity Center profiles.
runtimeOnly("software.amazon.awssdk:sts") {
exclude(group = "software.amazon.awssdk", module = "apache5-client")
exclude(group = "software.amazon.awssdk", module = "netty-nio-client")
}
runtimeOnly("software.amazon.awssdk:sso") {
exclude(group = "software.amazon.awssdk", module = "apache5-client")
exclude(group = "software.amazon.awssdk", module = "netty-nio-client")
}
runtimeOnly("software.amazon.awssdk:ssooidc") {
exclude(group = "software.amazon.awssdk", module = "apache5-client")
exclude(group = "software.amazon.awssdk", module = "netty-nio-client")
}
runtimeOnly("software.amazon.awssdk:url-connection-client")

testImplementation(kotlin("test"))
testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2")
testImplementation("org.assertj:assertj-core:3.27.7")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
testImplementation("org.junit-pioneer:junit-pioneer:1.9.1")
testImplementation("org.mockito:mockito-core:5.14.2")
testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
}
Loading
Loading