diff --git a/codex-rs/app-server-protocol/schema/json/ClientRequest.json b/codex-rs/app-server-protocol/schema/json/ClientRequest.json index 2f39f821b6a8..dc4ad86b7c57 100644 --- a/codex-rs/app-server-protocol/schema/json/ClientRequest.json +++ b/codex-rs/app-server-protocol/schema/json/ClientRequest.json @@ -1529,6 +1529,31 @@ ], "title": "ChatgptAuthTokensLoginAccountParams", "type": "object" + }, + { + "description": "[UNSTABLE] Managed Amazon Bedrock login is experimental.", + "properties": { + "apiKey": { + "type": "string" + }, + "region": { + "type": "string" + }, + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockLoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "apiKey", + "region", + "type" + ], + "title": "AmazonBedrockLoginAccountParams", + "type": "object" } ] }, diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 0eedef903a09..75b5c15a64b1 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -11569,6 +11569,31 @@ ], "title": "ChatgptAuthTokensv2::LoginAccountParams", "type": "object" + }, + { + "description": "[UNSTABLE] Managed Amazon Bedrock login is experimental.", + "properties": { + "apiKey": { + "type": "string" + }, + "region": { + "type": "string" + }, + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "apiKey", + "region", + "type" + ], + "title": "AmazonBedrockv2::LoginAccountParams", + "type": "object" } ], "title": "LoginAccountParams" @@ -11662,6 +11687,22 @@ ], "title": "ChatgptAuthTokensv2::LoginAccountResponse", "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountResponseType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "AmazonBedrockv2::LoginAccountResponse", + "type": "object" } ], "title": "LoginAccountResponse" diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index b428f252586b..7fa21d15c128 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -7973,6 +7973,31 @@ ], "title": "ChatgptAuthTokensv2::LoginAccountParams", "type": "object" + }, + { + "description": "[UNSTABLE] Managed Amazon Bedrock login is experimental.", + "properties": { + "apiKey": { + "type": "string" + }, + "region": { + "type": "string" + }, + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "apiKey", + "region", + "type" + ], + "title": "AmazonBedrockv2::LoginAccountParams", + "type": "object" } ], "title": "LoginAccountParams" @@ -8066,6 +8091,22 @@ ], "title": "ChatgptAuthTokensv2::LoginAccountResponse", "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountResponseType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "AmazonBedrockv2::LoginAccountResponse", + "type": "object" } ], "title": "LoginAccountResponse" diff --git a/codex-rs/app-server-protocol/schema/json/v2/LoginAccountParams.json b/codex-rs/app-server-protocol/schema/json/v2/LoginAccountParams.json index ab7b852c9185..474b7666cf82 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/LoginAccountParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/LoginAccountParams.json @@ -89,6 +89,31 @@ ], "title": "ChatgptAuthTokensv2::LoginAccountParams", "type": "object" + }, + { + "description": "[UNSTABLE] Managed Amazon Bedrock login is experimental.", + "properties": { + "apiKey": { + "type": "string" + }, + "region": { + "type": "string" + }, + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "apiKey", + "region", + "type" + ], + "title": "AmazonBedrockv2::LoginAccountParams", + "type": "object" } ], "title": "LoginAccountParams" diff --git a/codex-rs/app-server-protocol/schema/json/v2/LoginAccountResponse.json b/codex-rs/app-server-protocol/schema/json/v2/LoginAccountResponse.json index a800bffccd94..802440d637bf 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/LoginAccountResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/LoginAccountResponse.json @@ -87,6 +87,22 @@ ], "title": "ChatgptAuthTokensv2::LoginAccountResponse", "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountResponseType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "AmazonBedrockv2::LoginAccountResponse", + "type": "object" } ], "title": "LoginAccountResponse" diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountParams.ts index e6f1e2ed4369..88ee4434cfe8 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountParams.ts @@ -18,4 +18,4 @@ chatgptAccountId: string, * When `null`, Codex attempts to derive the plan type from access-token * claims. If unavailable, the plan defaults to `unknown`. */ -chatgptPlanType?: string | null, }; +chatgptPlanType?: string | null, } | { "type": "amazonBedrock", apiKey: string, region: string, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountResponse.ts b/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountResponse.ts index 34bccd6578e1..5a9f34ead3c1 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountResponse.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/LoginAccountResponse.ts @@ -14,4 +14,4 @@ verificationUrl: string, /** * One-time code the user must enter after signing in. */ -userCode: string, } | { "type": "chatgptAuthTokens", }; +userCode: string, } | { "type": "chatgptAuthTokens", } | { "type": "amazonBedrock", }; diff --git a/codex-rs/app-server-protocol/src/protocol/common.rs b/codex-rs/app-server-protocol/src/protocol/common.rs index d8db99d4ffeb..a78be7ef41f8 100644 --- a/codex-rs/app-server-protocol/src/protocol/common.rs +++ b/codex-rs/app-server-protocol/src/protocol/common.rs @@ -2716,6 +2716,34 @@ mod tests { Ok(()) } + #[test] + fn serialize_account_login_amazon_bedrock() -> Result<()> { + let request = ClientRequest::LoginAccount { + request_id: RequestId::Integer(2), + params: v2::LoginAccountParams::AmazonBedrock { + api_key: "secret".to_string(), + region: "us-west-2".to_string(), + }, + }; + assert_eq!( + json!({ + "method": "account/login/start", + "id": 2, + "params": { + "type": "amazonBedrock", + "apiKey": "secret", + "region": "us-west-2" + } + }), + serde_json::to_value(&request)?, + ); + assert_eq!( + json!({"type": "amazonBedrock"}), + serde_json::to_value(v2::LoginAccountResponse::AmazonBedrock {})?, + ); + Ok(()) + } + #[test] fn serialize_account_login_chatgpt() -> Result<()> { let request = ClientRequest::LoginAccount { diff --git a/codex-rs/app-server-protocol/src/protocol/v2/account.rs b/codex-rs/app-server-protocol/src/protocol/v2/account.rs index 788c8f7aafda..5268c318a6e5 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/account.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/account.rs @@ -100,6 +100,11 @@ pub enum LoginAccountParams { #[ts(optional = nullable)] chatgpt_plan_type: Option, }, + /// [UNSTABLE] Managed Amazon Bedrock login is experimental. + #[experimental("account/login/start.amazonBedrock")] + #[serde(rename = "amazonBedrock", rename_all = "camelCase")] + #[ts(rename = "amazonBedrock", rename_all = "camelCase")] + AmazonBedrock { api_key: String, region: String }, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] @@ -133,6 +138,9 @@ pub enum LoginAccountResponse { #[serde(rename = "chatgptAuthTokens", rename_all = "camelCase")] #[ts(rename = "chatgptAuthTokens", rename_all = "camelCase")] ChatgptAuthTokens {}, + #[serde(rename = "amazonBedrock", rename_all = "camelCase")] + #[ts(rename = "amazonBedrock", rename_all = "camelCase")] + AmazonBedrock {}, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index a7986753ee27..c530590237aa 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -1919,16 +1919,17 @@ Codex supports these authentication modes. The current mode is surfaced in `acco - **API key (`apiKey`)**: Caller supplies an OpenAI API key via `account/login/start` with `type: "apiKey"`. The API key is saved and used for API requests. - **ChatGPT managed (`chatgpt`)** (recommended): Codex owns the ChatGPT OAuth flow and refresh tokens. Start via `account/login/start` with `type: "chatgpt"` for the browser flow or `type: "chatgptDeviceCode"` for device code; Codex persists tokens to disk and refreshes them automatically. +- **Codex managed Amazon Bedrock auth (`amazonBedrock`, experimental)**: Caller supplies an Amazon Bedrock API key and region via `account/login/start` with `type: "amazonBedrock"`. The client must enable the `experimentalApi` initialization capability for Codex-managed Amazon Bedrock login. Codex saves the credential and writes `model_provider = "amazon-bedrock"` to the user config. - **Personal access token (`personalAccessToken`)**: Codex uses a ChatGPT-backed personal access token loaded outside the app-server login RPCs, such as with `codex login --with-access-token` or `CODEX_ACCESS_TOKEN`. ### API Overview - `account/read` — fetch current account info; optionally refresh tokens. -- `account/login/start` — begin login (`apiKey`, `chatgpt`, `chatgptDeviceCode`). +- `account/login/start` — begin login (`apiKey`, `chatgpt`, `chatgptDeviceCode`, `amazonBedrock`). - `account/login/completed` (notify) — emitted when a login attempt finishes (success or error). - `account/login/cancel` — cancel a pending managed ChatGPT login by `loginId`. - `account/logout` — sign out; triggers `account/updated`. -- `account/updated` (notify) — emitted whenever auth mode changes (`authMode`: `apikey`, `chatgpt`, `personalAccessToken`, or `null`) and includes the current ChatGPT `planType` when available. +- `account/updated` (notify) — emitted whenever auth mode changes (`authMode`: `apikey`, `bedrockApiKey`, `chatgpt`, `personalAccessToken`, or `null`) and includes the current ChatGPT `planType` when available. - `account/rateLimits/read` — fetch ChatGPT rate limits, an optional effective monthly credit limit, and the earned rate-limit resets currently available, including expiry details when provided by the backend. Rate-limit updates arrive via `account/rateLimits/updated` (notify); reset-credit data is snapshot-only. - `account/rateLimitResetCredit/consume` — consume one earned reset using a caller-provided idempotency key, optionally selecting a reset-credit ID returned by `account/rateLimits/read`. - `account/usage/read` — fetch ChatGPT account token-activity summary and daily buckets. @@ -1999,6 +2000,30 @@ Field notes: { "method": "account/updated", "params": { "authMode": "chatgpt", "planType": "plus" } } ``` +### 3) Log in with an Amazon Bedrock API key + +This experimental flow requires the client to initialize with `experimentalApi: true`. + +1. Send: + ```json + { + "method": "account/login/start", + "id": 3, + "params": { "type": "amazonBedrock", "apiKey": "…", "region": "us-west-2" } + } + ``` +2. Expect: + ```json + { "id": 3, "result": { "type": "amazonBedrock" } } + ``` +3. Notifications: + ```json + { "method": "account/login/completed", "params": { "loginId": null, "success": true, "error": null } } + { "method": "account/updated", "params": { "authMode": "bedrockApiKey", "planType": null } } + ``` + +Codex stores the key and region in its configured auth store and writes `model_provider = "amazon-bedrock"` to the active user config. Existing loaded sessions keep their current provider; a new app-server process is required to pick up the persisted default. The auth and config writes are not transactional, so an error after the credential write can leave durable Bedrock auth for a later retry or explicit cleanup. + ### 4) Log in with ChatGPT (device code flow) 1. Start: