feat: add Bedrock API key as a managed auth mode (#27443)

## Why

Codex needs to manage Amazon Bedrock API key credentials through the
existing auth lifecycle instead of introducing a separate auth manager
or provider-specific credential file. Treating Bedrock API key login as
a primary auth mode gives it the same persistence, keyring, reload, and
logout behavior as the existing OpenAI API key and ChatGPT modes.

The credential is valid only for the `amazon-bedrock` model provider.
OpenAI-compatible providers must reject this auth mode rather than
treating the Bedrock key as an OpenAI bearer token.

## What changed

- Added `bedrockApiKey` as an app-server `AuthMode` and
`CodexAuth::BedrockApiKey` as a primary `AuthManager` mode.
- Added `BedrockApiKeyAuth`, containing the API key and AWS region, to
the existing `AuthDotJson` payload stored in `$CODEX_HOME/auth.json` or
the configured keyring backend.
- Added `login_with_bedrock_api_key(...)`, parallel to
`login_with_api_key(...)`, which replaces the current stored login with
Bedrock credentials.
- Reused generic auth reload and logout behavior instead of adding a
Bedrock-specific auth manager or logout path.
- Updated login restrictions, status reporting, diagnostics, telemetry
classification, generated app-server schemas, and auth fixtures for the
new mode.
- Added explicit errors when Bedrock API key auth is selected with an
OpenAI-compatible model provider.

This PR establishes managed storage and auth-mode behavior. Routing the
managed key and region into Amazon Bedrock requests will be in follow-up
PRs.
This commit is contained in:
Celia Chen authored and GitHub committed 2026-06-10 20:42:38 -07:00
1 parent 87ab01834a
commit 06afd63f4a
30 files changed
+426 -15

No files matched your search

+31
View File
@@ -51,6 +51,7 @@ pub struct ProviderAccountState {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProviderAccountError {
MissingChatgptAccountDetails,
UnsupportedBedrockApiKeyAuth,
}
impl fmt::Display for ProviderAccountError {
@@ -62,6 +63,12 @@ impl fmt::Display for ProviderAccountError {
"email and plan type are required for chatgpt authentication"
)
}
Self::UnsupportedBedrockApiKeyAuth => {
write!(
f,
"Bedrock API key auth is only supported by the Amazon Bedrock model provider"
)
}
}
}
}
@@ -232,6 +239,9 @@ impl ModelProvider for ConfiguredModelProvider {
})
.map(|auth| match &auth {
CodexAuth::ApiKey(_) => Ok(ProviderAccount::ApiKey),
CodexAuth::BedrockApiKey(_) => {
Err(ProviderAccountError::UnsupportedBedrockApiKeyAuth)
}
CodexAuth::Chatgpt(_)
| CodexAuth::ChatgptAuthTokens(_)
| CodexAuth::AgentIdentity(_)
@@ -287,6 +297,7 @@ impl ModelProvider for ConfiguredModelProvider {
mod tests {
use std::num::NonZeroU64;
use codex_login::auth::BedrockApiKeyAuth;
use codex_model_provider_info::ModelProviderAwsAuthInfo;
use codex_model_provider_info::WireApi;
use codex_models_manager::manager::RefreshStrategy;
@@ -374,6 +385,13 @@ mod tests {
.expect("valid model")
}
fn bedrock_api_key_auth() -> CodexAuth {
CodexAuth::BedrockApiKey(BedrockApiKeyAuth {
api_key: "bedrock-api-key-test".to_string(),
region: "us-east-1".to_string(),
})
}
#[test]
fn configured_provider_uses_default_capabilities() {
let provider = create_model_provider(
@@ -491,6 +509,19 @@ mod tests {
);
}
#[test]
fn openai_provider_rejects_bedrock_api_key_account_state() {
let provider = create_model_provider(
ModelProviderInfo::create_openai_provider(/*base_url*/ None),
Some(AuthManager::from_auth_for_testing(bedrock_api_key_auth())),
);
assert_eq!(
provider.account_state(),
Err(ProviderAccountError::UnsupportedBedrockApiKeyAuth)
);
}
#[test]
fn custom_non_openai_provider_returns_no_account_state() {
let provider = create_model_provider(