Fail closed when workload identity initialization fails (#38424)

## What changed

- Treat workload identity environment markers as an explicit authentication selection, even when another process credential is present.
- Return initialization errors from `AuthManager` and propagate them through commands and services instead of continuing with an unusable authentication state.
- Make `codex login status` validate workload identity, keep the TUI on an embedded app server for local workload identity, and reject workload identity in `codex mcp-server`, where it is unsupported.

## Testing

- Cover workload identity precedence and partial configuration errors.
- Verify login status reports an unreadable identity assertion and app-server routing enforces the supported workload identity topology.

GitOrigin-RevId: efc6b6b4cd4d61652617de82aaa3d7ffc75d6618
This commit is contained in:
cooper-oai
2026-08-13 19:35:22 +00:00
committed by copyberry
parent 781445f7c6
commit 990218bbbd
33 changed files with 368 additions and 212 deletions
+21
View File
@@ -9,7 +9,10 @@ use app_test_support::ChatGptAuthFixture;
use app_test_support::write_chatgpt_auth;
use codex_config::types::AuthCredentialsStoreMode;
use codex_login::CLIENT_ID;
use codex_login::CODEX_ACCESS_TOKEN_ENV_VAR;
use codex_login::REVOKE_TOKEN_URL_OVERRIDE_ENV_VAR;
use codex_protocol::shell_environment::OPENAI_FEDERATION_RULE_ID_ENV_VAR;
use codex_protocol::shell_environment::OPENAI_IDENTITY_TOKEN_FILE_ENV_VAR;
use predicates::str::contains;
use pretty_assertions::assert_eq;
use serde_json::Value;
@@ -81,6 +84,24 @@ fn login_status_reports_auth_storage_errors() -> Result<()> {
Ok(())
}
#[test]
fn login_status_validates_configured_workload_identity() -> Result<()> {
let codex_home = TempDir::new()?;
write_file_auth_config(codex_home.path())?;
let missing_assertion = codex_home.path().join("missing-identity-token");
codex_command(codex_home.path())?
.env_remove(CODEX_ACCESS_TOKEN_ENV_VAR)
.env(OPENAI_FEDERATION_RULE_ID_ENV_VAR, "rule-test")
.env(OPENAI_IDENTITY_TOKEN_FILE_ENV_VAR, &missing_assertion)
.args(["login", "status"])
.assert()
.failure()
.stderr(contains("could not read workload identity assertion file"));
Ok(())
}
#[test]
fn login_with_access_token_rejects_invalid_jwt() -> Result<()> {
let codex_home = TempDir::new()?;