auth: move domain mode below app wire types (#29721)

## Why

Authentication mode is a domain concept used by login, model selection,
telemetry, and transports. Keeping the canonical type in app-server
protocol forces those lower-level crates to depend on an unrelated wire
API.

## What changed

- Added canonical `codex_protocol::auth::AuthMode` domain values.
- Kept the app-server wire DTO unchanged and added an explicit app-side
conversion.
- Removed production app-server-protocol dependencies from login,
model-provider-info, models-manager, and otel call paths.

## Stack

This is PR 2 of 6, stacked on [PR
#29714](https://github.com/openai/codex/pull/29714). Review only the
delta from `codex/split-json-rpc-protocols`. Next: [PR
#29722](https://github.com/openai/codex/pull/29722).

## Validation

- Auth and login coverage passed in the focused protocol/domain test
run.
- App-server account and auth conversion coverage passed.
This commit is contained in:
Adam Perry @ OpenAI
2026-06-24 03:10:20 +00:00
committed by GitHub
parent 806a4b66c9
commit 31372078d1
47 changed files with 224 additions and 146 deletions
+32 -34
View File
@@ -53,6 +53,7 @@ use codex_login::default_client::build_reqwest_client;
use codex_login::default_client::default_headers;
use codex_login::load_auth_dot_json;
use codex_model_provider::create_model_provider;
use codex_protocol::auth::AuthMode;
use codex_protocol::protocol::AskForApproval;
use codex_terminal_detection::Multiplexer;
use codex_terminal_detection::TerminalInfo;
@@ -1323,27 +1324,27 @@ fn provider_specific_auth_check(
fn stored_auth_mode(auth: &codex_login::AuthDotJson) -> &'static str {
match stored_auth_mode_value(auth) {
codex_app_server_protocol::AuthMode::ApiKey => "api_key",
codex_app_server_protocol::AuthMode::Chatgpt => "chatgpt",
codex_app_server_protocol::AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
codex_app_server_protocol::AuthMode::AgentIdentity => "agent_identity",
codex_app_server_protocol::AuthMode::PersonalAccessToken => "personal_access_token",
codex_app_server_protocol::AuthMode::BedrockApiKey => "bedrock_api_key",
AuthMode::ApiKey => "api_key",
AuthMode::Chatgpt => "chatgpt",
AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
AuthMode::AgentIdentity => "agent_identity",
AuthMode::PersonalAccessToken => "personal_access_token",
AuthMode::BedrockApiKey => "bedrock_api_key",
}
}
fn stored_auth_mode_value(auth: &AuthDotJson) -> codex_app_server_protocol::AuthMode {
fn stored_auth_mode_value(auth: &AuthDotJson) -> AuthMode {
if let Some(mode) = auth.auth_mode {
return mode;
}
if auth.personal_access_token.is_some() {
codex_app_server_protocol::AuthMode::PersonalAccessToken
AuthMode::PersonalAccessToken
} else if auth.bedrock_api_key.is_some() {
codex_app_server_protocol::AuthMode::BedrockApiKey
AuthMode::BedrockApiKey
} else if auth.openai_api_key.is_some() {
codex_app_server_protocol::AuthMode::ApiKey
AuthMode::ApiKey
} else {
codex_app_server_protocol::AuthMode::Chatgpt
AuthMode::Chatgpt
}
}
@@ -1353,7 +1354,7 @@ fn stored_auth_issues(
) -> Vec<&'static str> {
let mut issues = Vec::new();
match stored_auth_mode_value(auth) {
codex_app_server_protocol::AuthMode::ApiKey => {
AuthMode::ApiKey => {
let stored_key_present = auth
.openai_api_key
.as_deref()
@@ -1364,7 +1365,7 @@ fn stored_auth_issues(
issues.push("API key auth is missing an API key");
}
}
codex_app_server_protocol::AuthMode::Chatgpt => {
AuthMode::Chatgpt => {
match auth.tokens.as_ref() {
Some(tokens) => {
if tokens.access_token.trim().is_empty() {
@@ -1380,7 +1381,7 @@ fn stored_auth_issues(
issues.push("ChatGPT auth is missing refresh metadata");
}
}
codex_app_server_protocol::AuthMode::ChatgptAuthTokens => {
AuthMode::ChatgptAuthTokens => {
match auth.tokens.as_ref() {
Some(tokens) => {
if tokens.access_token.trim().is_empty() {
@@ -1396,7 +1397,7 @@ fn stored_auth_issues(
issues.push("external ChatGPT auth is missing refresh metadata");
}
}
codex_app_server_protocol::AuthMode::AgentIdentity => {
AuthMode::AgentIdentity => {
if auth
.agent_identity
.as_ref()
@@ -1405,7 +1406,7 @@ fn stored_auth_issues(
issues.push("agent identity auth is missing an agent identity token");
}
}
codex_app_server_protocol::AuthMode::PersonalAccessToken => {
AuthMode::PersonalAccessToken => {
if auth
.personal_access_token
.as_deref()
@@ -1414,7 +1415,7 @@ fn stored_auth_issues(
issues.push("personal access token auth is missing a personal access token");
}
}
codex_app_server_protocol::AuthMode::BedrockApiKey => {
AuthMode::BedrockApiKey => {
if auth.bedrock_api_key.is_none() {
issues.push("Bedrock API key auth is missing a Bedrock API key");
}
@@ -2462,12 +2463,12 @@ fn websocket_error_detail(err: &ApiError) -> String {
fn auth_mode_name(auth: &CodexAuth) -> &'static str {
match auth.auth_mode() {
codex_app_server_protocol::AuthMode::ApiKey => "api_key",
codex_app_server_protocol::AuthMode::Chatgpt => "chatgpt",
codex_app_server_protocol::AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
codex_app_server_protocol::AuthMode::AgentIdentity => "agent_identity",
codex_app_server_protocol::AuthMode::PersonalAccessToken => "personal_access_token",
codex_app_server_protocol::AuthMode::BedrockApiKey => "bedrock_api_key",
AuthMode::ApiKey => "api_key",
AuthMode::Chatgpt => "chatgpt",
AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
AuthMode::AgentIdentity => "agent_identity",
AuthMode::PersonalAccessToken => "personal_access_token",
AuthMode::BedrockApiKey => "bedrock_api_key",
}
}
@@ -2600,15 +2601,12 @@ fn provider_auth_reachability_mode_from_auth(
return ProviderAuthReachabilityMode::Chatgpt;
}
match stored_auth.map(stored_auth_mode_value) {
Some(AuthMode::ApiKey | AuthMode::BedrockApiKey) => ProviderAuthReachabilityMode::ApiKey,
Some(
codex_app_server_protocol::AuthMode::ApiKey
| codex_app_server_protocol::AuthMode::BedrockApiKey,
) => ProviderAuthReachabilityMode::ApiKey,
Some(
codex_app_server_protocol::AuthMode::Chatgpt
| codex_app_server_protocol::AuthMode::ChatgptAuthTokens
| codex_app_server_protocol::AuthMode::AgentIdentity
| codex_app_server_protocol::AuthMode::PersonalAccessToken,
AuthMode::Chatgpt
| AuthMode::ChatgptAuthTokens
| AuthMode::AgentIdentity
| AuthMode::PersonalAccessToken,
)
| None => ProviderAuthReachabilityMode::Chatgpt,
}
@@ -3502,7 +3500,7 @@ mod tests {
#[test]
fn stored_auth_validation_rejects_missing_api_key() {
let auth = AuthDotJson {
auth_mode: Some(codex_app_server_protocol::AuthMode::ApiKey),
auth_mode: Some(AuthMode::ApiKey),
openai_api_key: None,
tokens: None,
last_refresh: None,
@@ -3554,7 +3552,7 @@ mod tests {
assert_eq!(stored_auth_mode(&auth), "personal_access_token");
assert!(stored_auth_issues(&auth, |_| false).is_empty());
auth.auth_mode = Some(codex_app_server_protocol::AuthMode::PersonalAccessToken);
auth.auth_mode = Some(AuthMode::PersonalAccessToken);
auth.personal_access_token = None;
assert_eq!(
stored_auth_issues(&auth, |_| false),
@@ -3565,7 +3563,7 @@ mod tests {
#[test]
fn provider_reachability_mode_uses_api_key_auth() {
let api_key_auth = AuthDotJson {
auth_mode: Some(codex_app_server_protocol::AuthMode::ApiKey),
auth_mode: Some(AuthMode::ApiKey),
openai_api_key: Some("sk-test".to_string()),
tokens: None,
last_refresh: None,
+1 -1
View File
@@ -7,7 +7,6 @@
//! into a one-shot CLI command while still producing a durable `codex-login.log` artifact that
//! support can request from users.
use codex_app_server_protocol::AuthMode;
use codex_config::types::AuthCredentialsStoreMode;
use codex_core::config::Config;
use codex_login::AuthKeyringBackendKind;
@@ -20,6 +19,7 @@ use codex_login::login_with_api_key;
use codex_login::logout_with_revoke;
use codex_login::run_device_code_login;
use codex_login::run_login_server;
use codex_protocol::auth::AuthMode;
use codex_protocol::config_types::ForcedLoginMethod;
use codex_utils_cli::CliConfigOverrides;
use std::fs::OpenOptions;
+1 -1
View File
@@ -2,7 +2,6 @@ use anyhow::Context;
use anyhow::Result;
use anyhow::bail;
use clap::Parser;
use codex_app_server_protocol::AuthMode;
use codex_core::config::Config;
use codex_core::config::find_codex_home;
use codex_core_plugins::ConfiguredMarketplace;
@@ -22,6 +21,7 @@ use codex_login::CodexAuth;
use codex_login::auth::read_codex_api_key_from_env;
use codex_plugin::PluginId;
use codex_plugin::validate_plugin_segment;
use codex_protocol::auth::AuthMode;
use codex_utils_cli::CliConfigOverrides;
use serde::Serialize;
use std::collections::HashMap;