mirror of
https://github.com/openai/codex.git
synced 2026-05-29 15:30:22 +00:00
Rename agent identity login surface to access token (#21059)
## Why The external startup/login surface for this auth path should talk about an access token instead of exposing the internal Agent Identity terminology. Users should pass `CODEX_ACCESS_TOKEN` or pipe a token into `codex login --with-access-token`; the old external env/flag spellings are removed so there is only one supported user-facing path. ## What Changed - Added `CODEX_ACCESS_TOKEN` as the supported environment variable for this auth path. - Added `codex login --with-access-token` as the supported stdin-based login command. - Removed the legacy `CODEX_AGENT_IDENTITY` env-var fallback and hidden `--with-agent-identity` CLI alias. - Updated CLI error, status, and stdin prompts to use access-token language. - Added coverage for access-token env loading, CLI login failure behavior, and renamed login status text. ## Validation - `cargo test -p codex-login` - `cargo test -p codex-cli` - `just fix -p codex-login` - `just fix -p codex-cli`
This commit is contained in:
@@ -10,10 +10,10 @@ use std::path::PathBuf;
|
||||
pub use debug_sandbox::run_command_under_landlock;
|
||||
pub use debug_sandbox::run_command_under_seatbelt;
|
||||
pub use debug_sandbox::run_command_under_windows;
|
||||
pub use login::read_agent_identity_from_stdin;
|
||||
pub use login::read_access_token_from_stdin;
|
||||
pub use login::read_api_key_from_stdin;
|
||||
pub use login::run_login_status;
|
||||
pub use login::run_login_with_agent_identity;
|
||||
pub use login::run_login_with_access_token;
|
||||
pub use login::run_login_with_api_key;
|
||||
pub use login::run_login_with_chatgpt;
|
||||
pub use login::run_login_with_device_code;
|
||||
|
||||
@@ -13,7 +13,7 @@ use codex_core::config::Config;
|
||||
use codex_login::CLIENT_ID;
|
||||
use codex_login::CodexAuth;
|
||||
use codex_login::ServerOptions;
|
||||
use codex_login::login_with_agent_identity;
|
||||
use codex_login::login_with_access_token;
|
||||
use codex_login::login_with_api_key;
|
||||
use codex_login::logout_with_revoke;
|
||||
use codex_login::run_device_code_login;
|
||||
@@ -35,8 +35,8 @@ const CHATGPT_LOGIN_DISABLED_MESSAGE: &str =
|
||||
"ChatGPT login is disabled. Use API key login instead.";
|
||||
const API_KEY_LOGIN_DISABLED_MESSAGE: &str =
|
||||
"API key login is disabled. Use ChatGPT login instead.";
|
||||
const AGENT_IDENTITY_LOGIN_DISABLED_MESSAGE: &str =
|
||||
"Agent Identity login is disabled. Use API key login instead.";
|
||||
const ACCESS_TOKEN_LOGIN_DISABLED_MESSAGE: &str =
|
||||
"Access token login is disabled. Use API key login instead.";
|
||||
const LOGIN_SUCCESS_MESSAGE: &str = "Successfully logged in";
|
||||
|
||||
/// Installs a small file-backed tracing layer for direct `codex login` flows.
|
||||
@@ -190,22 +190,22 @@ pub async fn run_login_with_api_key(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run_login_with_agent_identity(
|
||||
pub async fn run_login_with_access_token(
|
||||
cli_config_overrides: CliConfigOverrides,
|
||||
agent_identity: String,
|
||||
access_token: String,
|
||||
) -> ! {
|
||||
let config = load_config_or_exit(cli_config_overrides).await;
|
||||
let _login_log_guard = init_login_file_logging(&config);
|
||||
tracing::info!("starting agent identity login flow");
|
||||
tracing::info!("starting access token login flow");
|
||||
|
||||
if matches!(config.forced_login_method, Some(ForcedLoginMethod::Api)) {
|
||||
eprintln!("{AGENT_IDENTITY_LOGIN_DISABLED_MESSAGE}");
|
||||
eprintln!("{ACCESS_TOKEN_LOGIN_DISABLED_MESSAGE}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
match login_with_agent_identity(
|
||||
match login_with_access_token(
|
||||
&config.codex_home,
|
||||
&agent_identity,
|
||||
&access_token,
|
||||
config.cli_auth_credentials_store_mode,
|
||||
Some(&config.chatgpt_base_url),
|
||||
)
|
||||
@@ -216,7 +216,7 @@ pub async fn run_login_with_agent_identity(
|
||||
std::process::exit(0);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error logging in with Agent Identity: {e}");
|
||||
eprintln!("Error logging in with access token: {e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
@@ -230,11 +230,11 @@ pub fn read_api_key_from_stdin() -> String {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn read_agent_identity_from_stdin() -> String {
|
||||
pub fn read_access_token_from_stdin() -> String {
|
||||
read_stdin_secret(
|
||||
"--with-agent-identity expects the Agent Identity token on stdin. Try piping it, e.g. `printenv CODEX_AGENT_IDENTITY | codex login --with-agent-identity`.",
|
||||
"Reading Agent Identity token from stdin...",
|
||||
"No Agent Identity token provided via stdin.",
|
||||
"--with-access-token expects the access token on stdin. Try piping it, e.g. `printenv CODEX_ACCESS_TOKEN | codex login --with-access-token`.",
|
||||
"Reading access token from stdin...",
|
||||
"No access token provided via stdin.",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ pub async fn run_login_status(cli_config_overrides: CliConfigOverrides) -> ! {
|
||||
std::process::exit(0);
|
||||
}
|
||||
AuthMode::AgentIdentity => {
|
||||
eprintln!("Logged in using Agent Identity");
|
||||
eprintln!("Logged in using access token");
|
||||
std::process::exit(0);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -10,10 +10,10 @@ use codex_chatgpt::apply_command::run_apply_command;
|
||||
use codex_cli::LandlockCommand;
|
||||
use codex_cli::SeatbeltCommand;
|
||||
use codex_cli::WindowsCommand;
|
||||
use codex_cli::read_agent_identity_from_stdin;
|
||||
use codex_cli::read_access_token_from_stdin;
|
||||
use codex_cli::read_api_key_from_stdin;
|
||||
use codex_cli::run_login_status;
|
||||
use codex_cli::run_login_with_agent_identity;
|
||||
use codex_cli::run_login_with_access_token;
|
||||
use codex_cli::run_login_with_api_key;
|
||||
use codex_cli::run_login_with_chatgpt;
|
||||
use codex_cli::run_login_with_device_code;
|
||||
@@ -364,10 +364,10 @@ struct LoginCommand {
|
||||
with_api_key: bool,
|
||||
|
||||
#[arg(
|
||||
long = "with-agent-identity",
|
||||
help = "Read the experimental Agent Identity token from stdin (e.g. `printenv CODEX_AGENT_IDENTITY | codex login --with-agent-identity`)"
|
||||
long = "with-access-token",
|
||||
help = "Read the access token from stdin (e.g. `printenv CODEX_ACCESS_TOKEN | codex login --with-access-token`)"
|
||||
)]
|
||||
with_agent_identity: bool,
|
||||
with_access_token: bool,
|
||||
|
||||
#[arg(
|
||||
long = "api-key",
|
||||
@@ -966,9 +966,9 @@ async fn cli_main(arg0_paths: Arg0DispatchPaths) -> anyhow::Result<()> {
|
||||
run_login_status(login_cli.config_overrides).await;
|
||||
}
|
||||
None => {
|
||||
if login_cli.with_api_key && login_cli.with_agent_identity {
|
||||
if login_cli.with_api_key && login_cli.with_access_token {
|
||||
eprintln!(
|
||||
"Choose one login credential source: --with-api-key or --with-agent-identity."
|
||||
"Choose one login credential source: --with-api-key or --with-access-token."
|
||||
);
|
||||
std::process::exit(1);
|
||||
} else if login_cli.use_device_code {
|
||||
@@ -986,10 +986,9 @@ async fn cli_main(arg0_paths: Arg0DispatchPaths) -> anyhow::Result<()> {
|
||||
} else if login_cli.with_api_key {
|
||||
let api_key = read_api_key_from_stdin();
|
||||
run_login_with_api_key(login_cli.config_overrides, api_key).await;
|
||||
} else if login_cli.with_agent_identity {
|
||||
let agent_identity = read_agent_identity_from_stdin();
|
||||
run_login_with_agent_identity(login_cli.config_overrides, agent_identity)
|
||||
.await;
|
||||
} else if login_cli.with_access_token {
|
||||
let access_token = read_access_token_from_stdin();
|
||||
run_login_with_access_token(login_cli.config_overrides, access_token).await;
|
||||
} else {
|
||||
run_login_with_chatgpt(login_cli.config_overrides).await;
|
||||
}
|
||||
|
||||
@@ -51,16 +51,16 @@ fn login_with_api_key_reads_stdin_and_writes_auth_json() -> Result<()> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn login_with_agent_identity_rejects_invalid_jwt() -> Result<()> {
|
||||
fn login_with_access_token_rejects_invalid_jwt() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
write_file_auth_config(codex_home.path())?;
|
||||
|
||||
let mut cmd = codex_command(codex_home.path())?;
|
||||
cmd.args(["login", "--with-agent-identity"])
|
||||
cmd.args(["login", "--with-access-token"])
|
||||
.write_stdin("not-a-jwt\n")
|
||||
.assert()
|
||||
.failure()
|
||||
.stderr(contains("Error logging in with Agent Identity"));
|
||||
.stderr(contains("Error logging in with access token"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ fn login_with_api_key_overwrites_existing_auth_json() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn login_with_agent_identity_writes_only_token() {
|
||||
async fn login_with_access_token_writes_only_token() {
|
||||
let dir = tempdir().unwrap();
|
||||
let auth_path = dir.path().join("auth.json");
|
||||
let record = agent_identity_record("account-123");
|
||||
@@ -99,14 +99,14 @@ async fn login_with_agent_identity_writes_only_token() {
|
||||
.await;
|
||||
let chatgpt_base_url = format!("{}/backend-api", server.uri());
|
||||
|
||||
super::login_with_agent_identity(
|
||||
super::login_with_access_token(
|
||||
dir.path(),
|
||||
&agent_identity,
|
||||
AuthCredentialsStoreMode::File,
|
||||
Some(&chatgpt_base_url),
|
||||
)
|
||||
.await
|
||||
.expect("login_with_agent_identity should succeed");
|
||||
.expect("login_with_access_token should succeed");
|
||||
|
||||
let storage = FileAuthStorage::new(dir.path().to_path_buf());
|
||||
let auth = storage
|
||||
@@ -123,27 +123,27 @@ async fn login_with_agent_identity_writes_only_token() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn login_with_agent_identity_rejects_invalid_jwt() {
|
||||
async fn login_with_access_token_rejects_invalid_jwt() {
|
||||
let dir = tempdir().unwrap();
|
||||
|
||||
let err = super::login_with_agent_identity(
|
||||
let err = super::login_with_access_token(
|
||||
dir.path(),
|
||||
"not-a-jwt",
|
||||
AuthCredentialsStoreMode::File,
|
||||
/*chatgpt_base_url*/ None,
|
||||
)
|
||||
.await
|
||||
.expect_err("invalid Agent Identity token should fail");
|
||||
.expect_err("invalid access token should fail");
|
||||
|
||||
assert_eq!(err.kind(), std::io::ErrorKind::Other);
|
||||
assert!(
|
||||
!get_auth_file(dir.path()).exists(),
|
||||
"invalid Agent Identity token should not write auth.json"
|
||||
"invalid access token should not write auth.json"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn login_with_agent_identity_rejects_unsigned_jwt() {
|
||||
async fn login_with_access_token_rejects_unsigned_jwt() {
|
||||
let dir = tempdir().unwrap();
|
||||
let record = agent_identity_record("account-123");
|
||||
let agent_identity = fake_agent_identity_jwt(&record).expect("fake agent identity");
|
||||
@@ -156,18 +156,18 @@ async fn login_with_agent_identity_rejects_unsigned_jwt() {
|
||||
.await;
|
||||
let chatgpt_base_url = format!("{}/backend-api", server.uri());
|
||||
|
||||
super::login_with_agent_identity(
|
||||
super::login_with_access_token(
|
||||
dir.path(),
|
||||
&agent_identity,
|
||||
AuthCredentialsStoreMode::File,
|
||||
Some(&chatgpt_base_url),
|
||||
)
|
||||
.await
|
||||
.expect_err("unsigned Agent Identity token should fail");
|
||||
.expect_err("unsigned access token should fail");
|
||||
|
||||
assert!(
|
||||
!get_auth_file(dir.path()).exists(),
|
||||
"unsigned Agent Identity token should not write auth.json"
|
||||
"unsigned access token should not write auth.json"
|
||||
);
|
||||
server.verify().await;
|
||||
}
|
||||
@@ -176,7 +176,7 @@ async fn login_with_agent_identity_rejects_unsigned_jwt() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn missing_auth_json_returns_none() {
|
||||
let dir = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let auth = CodexAuth::from_auth_storage(
|
||||
dir.path(),
|
||||
AuthCredentialsStoreMode::File,
|
||||
@@ -191,7 +191,7 @@ async fn missing_auth_json_returns_none() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn pro_account_with_no_api_key_uses_chatgpt_auth() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let fake_jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -250,7 +250,7 @@ async fn pro_account_with_no_api_key_uses_chatgpt_auth() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn loads_api_key_from_auth_json() {
|
||||
let dir = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let auth_file = dir.path().join("auth.json");
|
||||
std::fs::write(
|
||||
auth_file,
|
||||
@@ -324,7 +324,7 @@ async fn unauthorized_recovery_reports_mode_and_step_names() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn refresh_failure_is_scoped_to_the_matching_auth_snapshot() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -704,9 +704,13 @@ impl Drop for EnvVarGuard {
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_access_token_env_var() -> EnvVarGuard {
|
||||
EnvVarGuard::remove(CODEX_ACCESS_TOKEN_ENV_VAR)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(codex_auth_env)]
|
||||
async fn load_auth_reads_agent_identity_from_env() {
|
||||
async fn load_auth_reads_access_token_from_env() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let expected_record = agent_identity_record("account-123");
|
||||
let agent_identity =
|
||||
@@ -727,7 +731,7 @@ async fn load_auth_reads_agent_identity_from_env() {
|
||||
.expect(1)
|
||||
.mount(&server)
|
||||
.await;
|
||||
let _agent_guard = EnvVarGuard::set(CODEX_AGENT_IDENTITY_ENV_VAR, &agent_identity);
|
||||
let _access_token_guard = EnvVarGuard::set(CODEX_ACCESS_TOKEN_ENV_VAR, &agent_identity);
|
||||
|
||||
let chatgpt_base_url = format!("{}/backend-api", server.uri());
|
||||
let _authapi_guard =
|
||||
@@ -760,7 +764,7 @@ async fn load_auth_keeps_codex_api_key_env_precedence() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let record = agent_identity_record("account-123");
|
||||
let agent_identity = fake_agent_identity_jwt(&record).expect("fake agent identity");
|
||||
let _agent_guard = EnvVarGuard::set(CODEX_AGENT_IDENTITY_ENV_VAR, &agent_identity);
|
||||
let _access_token_guard = EnvVarGuard::set(CODEX_ACCESS_TOKEN_ENV_VAR, &agent_identity);
|
||||
let _api_key_guard = EnvVarGuard::set(CODEX_API_KEY_ENV_VAR, "sk-env");
|
||||
|
||||
let auth = super::load_auth(
|
||||
@@ -780,7 +784,7 @@ async fn load_auth_keeps_codex_api_key_env_precedence() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn enforce_login_restrictions_logs_out_for_method_mismatch() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
login_with_api_key(codex_home.path(), "sk-test", AuthCredentialsStoreMode::File)
|
||||
.expect("seed api key");
|
||||
|
||||
@@ -805,7 +809,7 @@ async fn enforce_login_restrictions_logs_out_for_method_mismatch() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn enforce_login_restrictions_logs_out_for_workspace_mismatch() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let _jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -837,7 +841,7 @@ async fn enforce_login_restrictions_logs_out_for_workspace_mismatch() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn enforce_login_restrictions_allows_matching_workspace() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let _jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -869,7 +873,7 @@ async fn enforce_login_restrictions_allows_matching_workspace() {
|
||||
async fn enforce_login_restrictions_allows_api_key_if_login_method_not_set_but_forced_chatgpt_workspace_id_is_set()
|
||||
{
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
login_with_api_key(codex_home.path(), "sk-test", AuthCredentialsStoreMode::File)
|
||||
.expect("seed api key");
|
||||
|
||||
@@ -893,7 +897,7 @@ async fn enforce_login_restrictions_allows_api_key_if_login_method_not_set_but_f
|
||||
#[serial(codex_auth_env)]
|
||||
async fn enforce_login_restrictions_blocks_env_api_key_when_chatgpt_required() {
|
||||
let _guard = EnvVarGuard::set(CODEX_API_KEY_ENV_VAR, "sk-env");
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let codex_home = tempdir().unwrap();
|
||||
|
||||
let config = build_config(
|
||||
@@ -1069,7 +1073,7 @@ async fn assert_agent_identity_plan_alias(
|
||||
#[serial(codex_auth_env)]
|
||||
async fn plan_type_maps_known_plan() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let _jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -1097,7 +1101,7 @@ async fn plan_type_maps_known_plan() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn plan_type_maps_self_serve_business_usage_based_plan() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let _jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -1128,7 +1132,7 @@ async fn plan_type_maps_self_serve_business_usage_based_plan() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn plan_type_maps_enterprise_cbp_usage_based_plan() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let _jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -1159,7 +1163,7 @@ async fn plan_type_maps_enterprise_cbp_usage_based_plan() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn plan_type_maps_unknown_to_unknown() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let _jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
@@ -1187,7 +1191,7 @@ async fn plan_type_maps_unknown_to_unknown() {
|
||||
#[serial(codex_auth_env)]
|
||||
async fn missing_plan_type_maps_to_unknown() {
|
||||
let codex_home = tempdir().unwrap();
|
||||
let _agent_guard = EnvVarGuard::remove(CODEX_AGENT_IDENTITY_ENV_VAR);
|
||||
let _access_token_guard = remove_access_token_env_var();
|
||||
let _jwt = write_auth_file(
|
||||
AuthFileParams {
|
||||
openai_api_key: None,
|
||||
|
||||
@@ -464,7 +464,7 @@ impl ChatgptAuth {
|
||||
|
||||
pub const OPENAI_API_KEY_ENV_VAR: &str = "OPENAI_API_KEY";
|
||||
pub const CODEX_API_KEY_ENV_VAR: &str = "CODEX_API_KEY";
|
||||
pub const CODEX_AGENT_IDENTITY_ENV_VAR: &str = "CODEX_AGENT_IDENTITY";
|
||||
pub const CODEX_ACCESS_TOKEN_ENV_VAR: &str = "CODEX_ACCESS_TOKEN";
|
||||
|
||||
pub fn read_openai_api_key_from_env() -> Option<String> {
|
||||
env::var(OPENAI_API_KEY_ENV_VAR)
|
||||
@@ -474,14 +474,15 @@ pub fn read_openai_api_key_from_env() -> Option<String> {
|
||||
}
|
||||
|
||||
pub fn read_codex_api_key_from_env() -> Option<String> {
|
||||
env::var(CODEX_API_KEY_ENV_VAR)
|
||||
.ok()
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
read_non_empty_env_var(CODEX_API_KEY_ENV_VAR)
|
||||
}
|
||||
|
||||
pub fn read_codex_agent_identity_from_env() -> Option<String> {
|
||||
env::var(CODEX_AGENT_IDENTITY_ENV_VAR)
|
||||
pub fn read_codex_access_token_from_env() -> Option<String> {
|
||||
read_non_empty_env_var(CODEX_ACCESS_TOKEN_ENV_VAR)
|
||||
}
|
||||
|
||||
fn read_non_empty_env_var(key: &str) -> Option<String> {
|
||||
env::var(key)
|
||||
.ok()
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
@@ -540,10 +541,10 @@ pub fn login_with_api_key(
|
||||
save_auth(codex_home, &auth_dot_json, auth_credentials_store_mode)
|
||||
}
|
||||
|
||||
/// Writes an `auth.json` that contains only the Agent Identity token.
|
||||
pub async fn login_with_agent_identity(
|
||||
/// Writes an `auth.json` that contains only the access token.
|
||||
pub async fn login_with_access_token(
|
||||
codex_home: &Path,
|
||||
agent_identity: &str,
|
||||
access_token: &str,
|
||||
auth_credentials_store_mode: AuthCredentialsStoreMode,
|
||||
chatgpt_base_url: Option<&str>,
|
||||
) -> std::io::Result<()> {
|
||||
@@ -551,13 +552,13 @@ pub async fn login_with_agent_identity(
|
||||
.unwrap_or(DEFAULT_CHATGPT_BACKEND_BASE_URL)
|
||||
.trim_end_matches('/')
|
||||
.to_string();
|
||||
verified_agent_identity_record(agent_identity, &base_url).await?;
|
||||
verified_agent_identity_record(access_token, &base_url).await?;
|
||||
let auth_dot_json = AuthDotJson {
|
||||
auth_mode: Some(ApiAuthMode::AgentIdentity),
|
||||
openai_api_key: None,
|
||||
tokens: None,
|
||||
last_refresh: None,
|
||||
agent_identity: Some(agent_identity.to_string()),
|
||||
agent_identity: Some(access_token.to_string()),
|
||||
};
|
||||
save_auth(codex_home, &auth_dot_json, auth_credentials_store_mode)
|
||||
}
|
||||
@@ -753,7 +754,7 @@ async fn load_auth(
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if let Some(agent_identity) = read_codex_agent_identity_from_env() {
|
||||
if let Some(agent_identity) = read_codex_access_token_from_env() {
|
||||
return CodexAuth::from_agent_identity_jwt(&agent_identity, chatgpt_base_url)
|
||||
.await
|
||||
.map(Some);
|
||||
|
||||
@@ -22,7 +22,7 @@ pub use auth::AuthDotJson;
|
||||
pub use auth::AuthManager;
|
||||
pub use auth::AuthManagerConfig;
|
||||
pub use auth::CLIENT_ID;
|
||||
pub use auth::CODEX_AGENT_IDENTITY_ENV_VAR;
|
||||
pub use auth::CODEX_ACCESS_TOKEN_ENV_VAR;
|
||||
pub use auth::CODEX_API_KEY_ENV_VAR;
|
||||
pub use auth::CodexAuth;
|
||||
pub use auth::ExternalAuth;
|
||||
@@ -38,11 +38,11 @@ pub use auth::UnauthorizedRecovery;
|
||||
pub use auth::default_client;
|
||||
pub use auth::enforce_login_restrictions;
|
||||
pub use auth::load_auth_dot_json;
|
||||
pub use auth::login_with_agent_identity;
|
||||
pub use auth::login_with_access_token;
|
||||
pub use auth::login_with_api_key;
|
||||
pub use auth::logout;
|
||||
pub use auth::logout_with_revoke;
|
||||
pub use auth::read_codex_agent_identity_from_env;
|
||||
pub use auth::read_codex_access_token_from_env;
|
||||
pub use auth::read_openai_api_key_from_env;
|
||||
pub use auth::save_auth;
|
||||
pub use auth_env_telemetry::AuthEnvTelemetry;
|
||||
|
||||
Reference in New Issue
Block a user