mirror of
https://github.com/openai/codex.git
synced 2026-10-27 18:48:37 +00:00
[codex] Rename host-provided auth
This commit is contained in:
@@ -537,9 +537,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "[UNSTABLE] Host-provided backend auth for embedded Codex runtimes.\n\nRequest headers are supplied by the process embedding Codex.",
|
||||
"description": "[UNSTABLE] Backend auth supplied programmatically by the caller.\n\nRequest headers are kept in memory and are not persisted or refreshed by Codex.",
|
||||
"enum": [
|
||||
"hostProvided"
|
||||
"callerProvided"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
+2
-2
@@ -6951,9 +6951,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "[UNSTABLE] Host-provided backend auth for embedded Codex runtimes.\n\nRequest headers are supplied by the process embedding Codex.",
|
||||
"description": "[UNSTABLE] Backend auth supplied programmatically by the caller.\n\nRequest headers are kept in memory and are not persisted or refreshed by Codex.",
|
||||
"enum": [
|
||||
"hostProvided"
|
||||
"callerProvided"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
+2
-2
@@ -1077,9 +1077,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "[UNSTABLE] Host-provided backend auth for embedded Codex runtimes.\n\nRequest headers are supplied by the process embedding Codex.",
|
||||
"description": "[UNSTABLE] Backend auth supplied programmatically by the caller.\n\nRequest headers are kept in memory and are not persisted or refreshed by Codex.",
|
||||
"enum": [
|
||||
"hostProvided"
|
||||
"callerProvided"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
+2
-2
@@ -26,9 +26,9 @@
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "[UNSTABLE] Host-provided backend auth for embedded Codex runtimes.\n\nRequest headers are supplied by the process embedding Codex.",
|
||||
"description": "[UNSTABLE] Backend auth supplied programmatically by the caller.\n\nRequest headers are kept in memory and are not persisted or refreshed by Codex.",
|
||||
"enum": [
|
||||
"hostProvided"
|
||||
"callerProvided"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
+1
-1
@@ -5,4 +5,4 @@
|
||||
/**
|
||||
* Authentication mode for OpenAI-backed providers.
|
||||
*/
|
||||
export type AuthMode = "apikey" | "chatgpt" | "chatgptAuthTokens" | "hostProvided" | "agentIdentity" | "personalAccessToken" | "bedrockApiKey";
|
||||
export type AuthMode = "apikey" | "chatgpt" | "chatgptAuthTokens" | "callerProvided" | "agentIdentity" | "personalAccessToken" | "bedrockApiKey";
|
||||
|
||||
@@ -31,13 +31,13 @@ pub enum AuthMode {
|
||||
#[ts(rename = "chatgptAuthTokens")]
|
||||
#[strum(serialize = "chatgptAuthTokens")]
|
||||
ChatgptAuthTokens,
|
||||
/// [UNSTABLE] Host-provided backend auth for embedded Codex runtimes.
|
||||
/// [UNSTABLE] Backend auth supplied programmatically by the caller.
|
||||
///
|
||||
/// Request headers are supplied by the process embedding Codex.
|
||||
#[serde(rename = "hostProvided")]
|
||||
#[ts(rename = "hostProvided")]
|
||||
#[strum(serialize = "hostProvided")]
|
||||
HostProvided,
|
||||
/// Request headers are kept in memory and are not persisted or refreshed by Codex.
|
||||
#[serde(rename = "callerProvided")]
|
||||
#[ts(rename = "callerProvided")]
|
||||
#[strum(serialize = "callerProvided")]
|
||||
CallerProvided,
|
||||
/// Programmatic Codex auth backed by a registered Agent Identity.
|
||||
#[serde(rename = "agentIdentity")]
|
||||
#[ts(rename = "agentIdentity")]
|
||||
@@ -60,7 +60,9 @@ impl AuthMode {
|
||||
pub fn has_chatgpt_account(self) -> bool {
|
||||
match self {
|
||||
Self::Chatgpt | Self::ChatgptAuthTokens | Self::PersonalAccessToken => true,
|
||||
Self::ApiKey | Self::HostProvided | Self::AgentIdentity | Self::BedrockApiKey => false,
|
||||
Self::ApiKey | Self::CallerProvided | Self::AgentIdentity | Self::BedrockApiKey => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +71,7 @@ impl AuthMode {
|
||||
match self {
|
||||
Self::Chatgpt
|
||||
| Self::ChatgptAuthTokens
|
||||
| Self::HostProvided
|
||||
| Self::CallerProvided
|
||||
| Self::AgentIdentity
|
||||
| Self::PersonalAccessToken => true,
|
||||
Self::ApiKey | Self::BedrockApiKey => false,
|
||||
|
||||
@@ -12,7 +12,7 @@ pub(crate) fn auth_mode_to_api(auth_mode: AuthMode) -> ApiAuthMode {
|
||||
AuthMode::ApiKey => ApiAuthMode::ApiKey,
|
||||
AuthMode::Chatgpt => ApiAuthMode::Chatgpt,
|
||||
AuthMode::ChatgptAuthTokens => ApiAuthMode::ChatgptAuthTokens,
|
||||
AuthMode::HostProvided => ApiAuthMode::HostProvided,
|
||||
AuthMode::CallerProvided => ApiAuthMode::CallerProvided,
|
||||
AuthMode::AgentIdentity => ApiAuthMode::AgentIdentity,
|
||||
AuthMode::PersonalAccessToken => ApiAuthMode::PersonalAccessToken,
|
||||
AuthMode::BedrockApiKey => ApiAuthMode::BedrockApiKey,
|
||||
|
||||
@@ -812,7 +812,7 @@ impl AccountRequestProcessor {
|
||||
let auth_mode = auth_mode_to_api(auth.api_auth_mode());
|
||||
let (reported_auth_method, token_opt) = if matches!(
|
||||
auth,
|
||||
CodexAuth::HostProvided(_)
|
||||
CodexAuth::CallerProvided(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_)
|
||||
) || include_token
|
||||
|
||||
@@ -1327,7 +1327,7 @@ fn stored_auth_mode(auth: &codex_login::AuthDotJson) -> &'static str {
|
||||
AuthMode::ApiKey => "api_key",
|
||||
AuthMode::Chatgpt => "chatgpt",
|
||||
AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
|
||||
AuthMode::HostProvided => "host_provided",
|
||||
AuthMode::CallerProvided => "caller_provided",
|
||||
AuthMode::AgentIdentity => "agent_identity",
|
||||
AuthMode::PersonalAccessToken => "personal_access_token",
|
||||
AuthMode::BedrockApiKey => "bedrock_api_key",
|
||||
@@ -1398,8 +1398,8 @@ fn stored_auth_issues(
|
||||
issues.push("external ChatGPT auth is missing refresh metadata");
|
||||
}
|
||||
}
|
||||
AuthMode::HostProvided => {
|
||||
issues.push("host-provided auth cannot be loaded from auth storage");
|
||||
AuthMode::CallerProvided => {
|
||||
issues.push("caller-provided auth cannot be loaded from auth storage");
|
||||
}
|
||||
AuthMode::AgentIdentity => {
|
||||
if auth
|
||||
@@ -2470,7 +2470,7 @@ fn auth_mode_name(auth: &CodexAuth) -> &'static str {
|
||||
AuthMode::ApiKey => "api_key",
|
||||
AuthMode::Chatgpt => "chatgpt",
|
||||
AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
|
||||
AuthMode::HostProvided => "host_provided",
|
||||
AuthMode::CallerProvided => "caller_provided",
|
||||
AuthMode::AgentIdentity => "agent_identity",
|
||||
AuthMode::PersonalAccessToken => "personal_access_token",
|
||||
AuthMode::BedrockApiKey => "bedrock_api_key",
|
||||
@@ -2610,7 +2610,7 @@ fn provider_auth_reachability_mode_from_auth(
|
||||
Some(
|
||||
AuthMode::Chatgpt
|
||||
| AuthMode::ChatgptAuthTokens
|
||||
| AuthMode::HostProvided
|
||||
| AuthMode::CallerProvided
|
||||
| AuthMode::AgentIdentity
|
||||
| AuthMode::PersonalAccessToken,
|
||||
)
|
||||
|
||||
@@ -449,8 +449,8 @@ pub async fn run_login_status(cli_config_overrides: CliConfigOverrides) -> ! {
|
||||
eprintln!("Logged in using ChatGPT");
|
||||
std::process::exit(0);
|
||||
}
|
||||
AuthMode::HostProvided => {
|
||||
eprintln!("Logged in using host-provided auth");
|
||||
AuthMode::CallerProvided => {
|
||||
eprintln!("Logged in using caller-provided auth");
|
||||
std::process::exit(0);
|
||||
}
|
||||
AuthMode::AgentIdentity => {
|
||||
|
||||
@@ -26,8 +26,8 @@ use codex_config::McpServerToolConfig;
|
||||
use codex_config::types::AuthKeyringBackendKind;
|
||||
use codex_config::types::OAuthCredentialsStoreMode;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_login::CallerProvidedAuth;
|
||||
use codex_login::CodexAuth;
|
||||
use codex_login::HostProvidedAuth;
|
||||
use codex_protocol::ToolName;
|
||||
use codex_protocol::mcp::McpServerInfo;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
@@ -71,9 +71,9 @@ fn create_test_tool(server_name: &str, tool_name: &str) -> ToolInfo {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn host_provided_auth_scopes_codex_apps_cache() {
|
||||
let auth = CodexAuth::HostProvided(
|
||||
HostProvidedAuth::new([], "user-123").with_account_id("account-123"),
|
||||
fn caller_provided_auth_scopes_codex_apps_cache() {
|
||||
let auth = CodexAuth::CallerProvided(
|
||||
CallerProvidedAuth::new([], "user-123").with_account_id("account-123"),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
|
||||
@@ -70,7 +70,7 @@ pub use codex_features::Feature;
|
||||
pub use codex_features::Features;
|
||||
pub use codex_home::CodexHomeUserInstructionsProvider;
|
||||
pub use codex_login::AuthManager;
|
||||
pub use codex_login::HostProvidedAuth;
|
||||
pub use codex_login::CallerProvidedAuth;
|
||||
pub use codex_login::default_client::set_default_originator;
|
||||
pub use codex_model_provider_info::OPENAI_PROVIDER_ID;
|
||||
pub use codex_model_provider_info::built_in_model_providers;
|
||||
|
||||
@@ -2088,7 +2088,7 @@ impl AuthRequestTelemetryContext {
|
||||
AuthMode::ApiKey | AuthMode::BedrockApiKey => "ApiKey",
|
||||
AuthMode::Chatgpt
|
||||
| AuthMode::ChatgptAuthTokens
|
||||
| AuthMode::HostProvided
|
||||
| AuthMode::CallerProvided
|
||||
| AuthMode::AgentIdentity
|
||||
| AuthMode::PersonalAccessToken => "Chatgpt",
|
||||
}),
|
||||
|
||||
@@ -9,8 +9,8 @@ use codex_extension_api::ExtensionRegistryBuilder;
|
||||
use codex_extension_api::McpServerContribution;
|
||||
use codex_extension_api::McpServerContributionContext;
|
||||
use codex_extension_api::McpServerContributor;
|
||||
use codex_login::CallerProvidedAuth;
|
||||
use codex_login::CodexAuth;
|
||||
use codex_login::HostProvidedAuth;
|
||||
use codex_mcp::CODEX_APPS_MCP_SERVER_NAME;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
@@ -148,7 +148,7 @@ async fn hosted_apps_mcp_requires_chatgpt_auth() -> TestResult {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn hosted_apps_mcp_accepts_host_provided_codex_auth() -> TestResult {
|
||||
async fn hosted_apps_mcp_accepts_caller_provided_codex_auth() -> TestResult {
|
||||
let codex_home = tempfile::tempdir()?;
|
||||
let config = ConfigBuilder::default()
|
||||
.codex_home(codex_home.path().to_path_buf())
|
||||
@@ -156,7 +156,7 @@ async fn hosted_apps_mcp_accepts_host_provided_codex_auth() -> TestResult {
|
||||
.cli_overrides(vec![("features.apps".to_string(), true.into())])
|
||||
.build()
|
||||
.await?;
|
||||
let auth = CodexAuth::HostProvided(HostProvidedAuth::new([], "user-123"));
|
||||
let auth = CodexAuth::CallerProvided(CallerProvidedAuth::new([], "user-123"));
|
||||
let manager = installed_manager(&config);
|
||||
|
||||
let servers = manager.effective_servers(&config, Some(&auth)).await;
|
||||
|
||||
@@ -85,7 +85,7 @@ async fn login_with_bedrock_api_key_replaces_openai_auth() -> anyhow::Result<()>
|
||||
CodexAuth::ApiKey(_)
|
||||
| CodexAuth::Chatgpt(_)
|
||||
| CodexAuth::ChatgptAuthTokens(_)
|
||||
| CodexAuth::HostProvided(_)
|
||||
| CodexAuth::CallerProvided(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_) => None,
|
||||
}),
|
||||
@@ -149,7 +149,7 @@ async fn bedrock_only_auth_storage_creates_primary_auth() -> anyhow::Result<()>
|
||||
CodexAuth::ApiKey(_)
|
||||
| CodexAuth::Chatgpt(_)
|
||||
| CodexAuth::ChatgptAuthTokens(_)
|
||||
| CodexAuth::HostProvided(_)
|
||||
| CodexAuth::CallerProvided(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_) => None,
|
||||
}),
|
||||
|
||||
+11
-11
@@ -1,20 +1,20 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
|
||||
/// Codex backend authentication supplied by the process embedding Codex.
|
||||
/// Backend authentication supplied programmatically by the caller.
|
||||
///
|
||||
/// The embedding process owns credential validation, rotation, and persistence.
|
||||
/// The caller owns credential validation, rotation, and persistence.
|
||||
/// Codex keeps this snapshot in memory and uses its headers for backend requests.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct HostProvidedAuth {
|
||||
pub struct CallerProvidedAuth {
|
||||
headers: BTreeMap<String, String>,
|
||||
account_id: Option<String>,
|
||||
user_id: String,
|
||||
}
|
||||
|
||||
impl fmt::Debug for HostProvidedAuth {
|
||||
impl fmt::Debug for CallerProvidedAuth {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("HostProvidedAuth")
|
||||
f.debug_struct("CallerProvidedAuth")
|
||||
.field("headers", &"<redacted>")
|
||||
.field("account_id", &self.account_id)
|
||||
.field("user_id", &self.user_id)
|
||||
@@ -22,8 +22,8 @@ impl fmt::Debug for HostProvidedAuth {
|
||||
}
|
||||
}
|
||||
|
||||
impl HostProvidedAuth {
|
||||
/// Creates host-provided auth with backend request headers and a stable user identity.
|
||||
impl CallerProvidedAuth {
|
||||
/// Creates caller-provided auth with backend request headers and a stable user identity.
|
||||
pub fn new(
|
||||
headers: impl IntoIterator<Item = (String, String)>,
|
||||
user_id: impl Into<String>,
|
||||
@@ -35,23 +35,23 @@ impl HostProvidedAuth {
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds the account selected by the embedding process.
|
||||
/// Adds the account selected by the caller.
|
||||
pub fn with_account_id(mut self, account_id: impl Into<String>) -> Self {
|
||||
self.account_id = Some(account_id.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns the request headers supplied by the embedding process.
|
||||
/// Returns the request headers supplied by the caller.
|
||||
pub fn headers(&self) -> &BTreeMap<String, String> {
|
||||
&self.headers
|
||||
}
|
||||
|
||||
/// Returns the selected account ID, when the embedding process supplied one.
|
||||
/// Returns the selected account ID, when the caller supplied one.
|
||||
pub fn account_id(&self) -> Option<&str> {
|
||||
self.account_id.as_deref()
|
||||
}
|
||||
|
||||
/// Returns the stable user ID supplied by the embedding process.
|
||||
/// Returns the stable user ID supplied by the caller.
|
||||
pub fn user_id(&self) -> &str {
|
||||
&self.user_id
|
||||
}
|
||||
@@ -41,7 +41,7 @@ use super::revoke::revoke_auth_tokens;
|
||||
pub use crate::auth::agent_identity::AgentIdentityAuth;
|
||||
pub use crate::auth::agent_identity::AgentIdentityAuthError;
|
||||
pub use crate::auth::bedrock_api_key::BedrockApiKeyAuth;
|
||||
use crate::auth::host_provided::HostProvidedAuth;
|
||||
use crate::auth::caller_provided::CallerProvidedAuth;
|
||||
pub use crate::auth::personal_access_token::PersonalAccessTokenAuth;
|
||||
pub use crate::auth::storage::AgentIdentityAuthRecord;
|
||||
pub use crate::auth::storage::AgentIdentityStorage;
|
||||
@@ -72,7 +72,7 @@ pub enum CodexAuth {
|
||||
ApiKey(ApiKeyAuth),
|
||||
Chatgpt(ChatgptAuth),
|
||||
ChatgptAuthTokens(ChatgptAuthTokens),
|
||||
HostProvided(HostProvidedAuth),
|
||||
CallerProvided(CallerProvidedAuth),
|
||||
AgentIdentity(AgentIdentityAuth),
|
||||
PersonalAccessToken(PersonalAccessTokenAuth),
|
||||
BedrockApiKey(BedrockApiKeyAuth),
|
||||
@@ -147,7 +147,7 @@ impl AgentIdentityBootstrapCooldown {
|
||||
impl PartialEq for CodexAuth {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Self::HostProvided(a), Self::HostProvided(b)) => a == b,
|
||||
(Self::CallerProvided(a), Self::CallerProvided(b)) => a == b,
|
||||
(Self::PersonalAccessToken(a), Self::PersonalAccessToken(b)) => a == b,
|
||||
(Self::BedrockApiKey(a), Self::BedrockApiKey(b)) => a == b,
|
||||
_ => self.api_auth_mode() == other.api_auth_mode(),
|
||||
@@ -360,9 +360,9 @@ impl CodexAuth {
|
||||
};
|
||||
return Ok(Self::BedrockApiKey(auth));
|
||||
}
|
||||
if auth_mode == AuthMode::HostProvided {
|
||||
if auth_mode == AuthMode::CallerProvided {
|
||||
return Err(std::io::Error::other(
|
||||
"host-provided auth cannot be loaded from auth storage.",
|
||||
"caller-provided auth cannot be loaded from auth storage.",
|
||||
));
|
||||
}
|
||||
|
||||
@@ -384,8 +384,8 @@ impl CodexAuth {
|
||||
}
|
||||
AuthMode::ChatgptAuthTokens => Ok(Self::ChatgptAuthTokens(ChatgptAuthTokens { state })),
|
||||
AuthMode::ApiKey => unreachable!("api key mode is handled above"),
|
||||
AuthMode::HostProvided => {
|
||||
unreachable!("host-provided auth is never loaded from auth storage")
|
||||
AuthMode::CallerProvided => {
|
||||
unreachable!("caller-provided auth is never loaded from auth storage")
|
||||
}
|
||||
AuthMode::AgentIdentity => unreachable!("agent identity mode is handled above"),
|
||||
AuthMode::PersonalAccessToken => {
|
||||
@@ -469,7 +469,7 @@ impl CodexAuth {
|
||||
match self {
|
||||
Self::ApiKey(_) => AuthMode::ApiKey,
|
||||
Self::Chatgpt(_) | Self::ChatgptAuthTokens(_) => AuthMode::Chatgpt,
|
||||
Self::HostProvided(_) => AuthMode::HostProvided,
|
||||
Self::CallerProvided(_) => AuthMode::CallerProvided,
|
||||
Self::AgentIdentity(_) => AuthMode::AgentIdentity,
|
||||
Self::PersonalAccessToken(_) => AuthMode::PersonalAccessToken,
|
||||
Self::BedrockApiKey(_) => AuthMode::BedrockApiKey,
|
||||
@@ -482,7 +482,7 @@ impl CodexAuth {
|
||||
Self::ApiKey(_) => AuthMode::ApiKey,
|
||||
Self::Chatgpt(_) => AuthMode::Chatgpt,
|
||||
Self::ChatgptAuthTokens(_) => AuthMode::ChatgptAuthTokens,
|
||||
Self::HostProvided(_) => AuthMode::HostProvided,
|
||||
Self::CallerProvided(_) => AuthMode::CallerProvided,
|
||||
Self::AgentIdentity(_) => AuthMode::AgentIdentity,
|
||||
Self::PersonalAccessToken(_) => AuthMode::PersonalAccessToken,
|
||||
Self::BedrockApiKey(_) => AuthMode::BedrockApiKey,
|
||||
@@ -519,7 +519,7 @@ impl CodexAuth {
|
||||
Self::ApiKey(auth) => Some(auth.api_key.as_str()),
|
||||
Self::Chatgpt(_)
|
||||
| Self::ChatgptAuthTokens(_)
|
||||
| Self::HostProvided(_)
|
||||
| Self::CallerProvided(_)
|
||||
| Self::AgentIdentity(_)
|
||||
| Self::PersonalAccessToken(_)
|
||||
| Self::BedrockApiKey(_) => None,
|
||||
@@ -550,8 +550,8 @@ impl CodexAuth {
|
||||
Self::AgentIdentity(_) => Err(std::io::Error::other(
|
||||
"agent identity auth does not expose a bearer token",
|
||||
)),
|
||||
Self::HostProvided(_) => Err(std::io::Error::other(
|
||||
"host-provided auth does not expose a bearer token",
|
||||
Self::CallerProvided(_) => Err(std::io::Error::other(
|
||||
"caller-provided auth does not expose a bearer token",
|
||||
)),
|
||||
Self::PersonalAccessToken(auth) => Ok(auth.access_token().to_string()),
|
||||
Self::BedrockApiKey(_) => Err(std::io::Error::other(
|
||||
@@ -563,7 +563,7 @@ impl CodexAuth {
|
||||
/// Returns `None` if Codex backend auth does not expose an account id.
|
||||
pub fn get_account_id(&self) -> Option<String> {
|
||||
match self {
|
||||
Self::HostProvided(auth) => auth.account_id().map(str::to_string),
|
||||
Self::CallerProvided(auth) => auth.account_id().map(str::to_string),
|
||||
Self::AgentIdentity(auth) => Some(auth.account_id().to_string()),
|
||||
Self::PersonalAccessToken(auth) => Some(auth.account_id().to_string()),
|
||||
_ => self.get_current_token_data().and_then(|t| t.account_id),
|
||||
@@ -573,7 +573,7 @@ impl CodexAuth {
|
||||
/// Returns false if Codex backend auth omits the FedRAMP claim.
|
||||
pub fn is_fedramp_account(&self) -> bool {
|
||||
match self {
|
||||
Self::HostProvided(_) => false,
|
||||
Self::CallerProvided(_) => false,
|
||||
Self::AgentIdentity(auth) => auth.is_fedramp_account(),
|
||||
Self::PersonalAccessToken(auth) => auth.is_fedramp_account(),
|
||||
_ => self
|
||||
@@ -585,7 +585,7 @@ impl CodexAuth {
|
||||
/// Returns `None` if Codex backend auth does not expose an account email.
|
||||
pub fn get_account_email(&self) -> Option<String> {
|
||||
match self {
|
||||
Self::HostProvided(_) => None,
|
||||
Self::CallerProvided(_) => None,
|
||||
Self::AgentIdentity(auth) => auth.email().map(str::to_string),
|
||||
Self::PersonalAccessToken(auth) => auth.email().map(str::to_string),
|
||||
_ => self.get_current_token_data().and_then(|t| t.id_token.email),
|
||||
@@ -595,7 +595,7 @@ impl CodexAuth {
|
||||
/// Returns `None` if Codex backend auth does not expose a ChatGPT user id.
|
||||
pub fn get_chatgpt_user_id(&self) -> Option<String> {
|
||||
match self {
|
||||
Self::HostProvided(auth) => Some(auth.user_id().to_string()),
|
||||
Self::CallerProvided(auth) => Some(auth.user_id().to_string()),
|
||||
Self::AgentIdentity(auth) => Some(auth.chatgpt_user_id().to_string()),
|
||||
Self::PersonalAccessToken(auth) => Some(auth.chatgpt_user_id().to_string()),
|
||||
_ => self
|
||||
@@ -608,7 +608,7 @@ impl CodexAuth {
|
||||
/// Returns a high-level `AccountPlanType` (e.g., Free/Plus/Pro/Team/…)
|
||||
/// for UI or product decisions based on the user's subscription.
|
||||
pub fn account_plan_type(&self) -> Option<AccountPlanType> {
|
||||
if matches!(self, Self::HostProvided(_)) {
|
||||
if matches!(self, Self::CallerProvided(_)) {
|
||||
return Some(AccountPlanType::Unknown);
|
||||
}
|
||||
if let Self::AgentIdentity(auth) = self {
|
||||
@@ -637,7 +637,7 @@ impl CodexAuth {
|
||||
Self::Chatgpt(auth) => &auth.state,
|
||||
Self::ChatgptAuthTokens(auth) => &auth.state,
|
||||
Self::ApiKey(_)
|
||||
| Self::HostProvided(_)
|
||||
| Self::CallerProvided(_)
|
||||
| Self::AgentIdentity(_)
|
||||
| Self::PersonalAccessToken(_)
|
||||
| Self::BedrockApiKey(_) => return None,
|
||||
@@ -683,7 +683,7 @@ impl CodexAuth {
|
||||
Self::AgentIdentity(auth) => Ok(Some(auth.clone())),
|
||||
Self::ApiKey(_)
|
||||
| Self::ChatgptAuthTokens(_)
|
||||
| Self::HostProvided(_)
|
||||
| Self::CallerProvided(_)
|
||||
| Self::PersonalAccessToken(_)
|
||||
| Self::BedrockApiKey(_) => Ok(None),
|
||||
Self::Chatgpt(_) => {
|
||||
@@ -1112,12 +1112,12 @@ async fn enforce_login_restrictions_with_agent_identity_authapi_base_url(
|
||||
| (ForcedLoginMethod::Api, AuthMode::BedrockApiKey) => None,
|
||||
(ForcedLoginMethod::Chatgpt, AuthMode::Chatgpt)
|
||||
| (ForcedLoginMethod::Chatgpt, AuthMode::ChatgptAuthTokens)
|
||||
| (ForcedLoginMethod::Chatgpt, AuthMode::HostProvided)
|
||||
| (ForcedLoginMethod::Chatgpt, AuthMode::CallerProvided)
|
||||
| (ForcedLoginMethod::Chatgpt, AuthMode::AgentIdentity)
|
||||
| (ForcedLoginMethod::Chatgpt, AuthMode::PersonalAccessToken) => None,
|
||||
(ForcedLoginMethod::Api, AuthMode::Chatgpt)
|
||||
| (ForcedLoginMethod::Api, AuthMode::ChatgptAuthTokens)
|
||||
| (ForcedLoginMethod::Api, AuthMode::HostProvided)
|
||||
| (ForcedLoginMethod::Api, AuthMode::CallerProvided)
|
||||
| (ForcedLoginMethod::Api, AuthMode::AgentIdentity)
|
||||
| (ForcedLoginMethod::Api, AuthMode::PersonalAccessToken) => Some(
|
||||
"API key login is required, but ChatGPT is currently being used. Logging out."
|
||||
@@ -1143,7 +1143,7 @@ async fn enforce_login_restrictions_with_agent_identity_authapi_base_url(
|
||||
if let Some(expected_account_ids) = config.forced_chatgpt_workspace_id.as_deref() {
|
||||
let chatgpt_account_id = match &auth {
|
||||
CodexAuth::ApiKey(_) | CodexAuth::BedrockApiKey(_) => return Ok(()),
|
||||
CodexAuth::HostProvided(_)
|
||||
CodexAuth::CallerProvided(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_) => auth.get_account_id(),
|
||||
CodexAuth::Chatgpt(_) | CodexAuth::ChatgptAuthTokens(_) => {
|
||||
@@ -2200,7 +2200,7 @@ impl AuthManager {
|
||||
| (AuthMode::ChatgptAuthTokens, AuthMode::ChatgptAuthTokens) => {
|
||||
a.get_current_auth_json() == b.get_current_auth_json()
|
||||
}
|
||||
(AuthMode::HostProvided, AuthMode::HostProvided) => a == b,
|
||||
(AuthMode::CallerProvided, AuthMode::CallerProvided) => a == b,
|
||||
(AuthMode::AgentIdentity, AuthMode::AgentIdentity) => match (a, b) {
|
||||
(CodexAuth::AgentIdentity(a), CodexAuth::AgentIdentity(b)) => {
|
||||
a.record() == b.record()
|
||||
@@ -2285,9 +2285,9 @@ impl AuthManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Replaces the current auth snapshot with Codex backend auth supplied by the host.
|
||||
pub fn set_host_provided_auth(&self, auth: HostProvidedAuth) {
|
||||
let _ = self.set_cached_auth(Some(CodexAuth::HostProvided(auth)));
|
||||
/// Replaces the current auth snapshot with Codex backend auth supplied by the caller.
|
||||
pub fn set_caller_provided_auth(&self, auth: CallerProvidedAuth) {
|
||||
let _ = self.set_cached_auth(Some(CodexAuth::CallerProvided(auth)));
|
||||
}
|
||||
|
||||
pub fn clear_external_auth(&self) {
|
||||
@@ -2486,7 +2486,7 @@ impl AuthManager {
|
||||
.await
|
||||
}
|
||||
CodexAuth::ApiKey(_)
|
||||
| CodexAuth::HostProvided(_)
|
||||
| CodexAuth::CallerProvided(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_)
|
||||
| CodexAuth::BedrockApiKey(_) => Ok(()),
|
||||
|
||||
@@ -7,14 +7,14 @@ mod personal_access_token;
|
||||
mod storage;
|
||||
mod util;
|
||||
|
||||
mod caller_provided;
|
||||
mod external_bearer;
|
||||
mod host_provided;
|
||||
mod manager;
|
||||
mod revoke;
|
||||
|
||||
pub use bedrock_api_key::BedrockApiKeyAuth;
|
||||
pub use bedrock_api_key::login_with_bedrock_api_key;
|
||||
pub use caller_provided::CallerProvidedAuth;
|
||||
pub use error::RefreshTokenFailedError;
|
||||
pub use error::RefreshTokenFailedReason;
|
||||
pub use host_provided::HostProvidedAuth;
|
||||
pub use manager::*;
|
||||
|
||||
@@ -28,6 +28,7 @@ pub use auth::CLIENT_ID;
|
||||
pub use auth::CLIENT_ID_OVERRIDE_ENV_VAR;
|
||||
pub use auth::CODEX_ACCESS_TOKEN_ENV_VAR;
|
||||
pub use auth::CODEX_API_KEY_ENV_VAR;
|
||||
pub use auth::CallerProvidedAuth;
|
||||
pub use auth::CodexAuth;
|
||||
pub use auth::ExternalAuth;
|
||||
pub use auth::ExternalAuthChatgptMetadata;
|
||||
@@ -35,7 +36,6 @@ pub use auth::ExternalAuthFuture;
|
||||
pub use auth::ExternalAuthRefreshContext;
|
||||
pub use auth::ExternalAuthRefreshReason;
|
||||
pub use auth::ExternalAuthTokens;
|
||||
pub use auth::HostProvidedAuth;
|
||||
pub use auth::OPENAI_API_KEY_ENV_VAR;
|
||||
pub use auth::REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR;
|
||||
pub use auth::REVOKE_TOKEN_URL_OVERRIDE_ENV_VAR;
|
||||
|
||||
@@ -244,7 +244,7 @@ impl ModelProviderInfo {
|
||||
Some(
|
||||
AuthMode::Chatgpt
|
||||
| AuthMode::ChatgptAuthTokens
|
||||
| AuthMode::HostProvided
|
||||
| AuthMode::CallerProvided
|
||||
| AuthMode::AgentIdentity
|
||||
| AuthMode::PersonalAccessToken
|
||||
)
|
||||
|
||||
@@ -69,7 +69,7 @@ impl AmazonBedrockModelProvider {
|
||||
CodexAuth::ApiKey(_)
|
||||
| CodexAuth::Chatgpt(_)
|
||||
| CodexAuth::ChatgptAuthTokens(_)
|
||||
| CodexAuth::HostProvided(_)
|
||||
| CodexAuth::CallerProvided(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_) => None,
|
||||
})
|
||||
|
||||
@@ -8,8 +8,8 @@ use codex_api::AgentIdentityTelemetry;
|
||||
use codex_api::AuthProvider;
|
||||
use codex_api::SharedAuthProvider;
|
||||
use codex_login::AuthManager;
|
||||
use codex_login::CallerProvidedAuth;
|
||||
use codex_login::CodexAuth;
|
||||
use codex_login::HostProvidedAuth;
|
||||
use codex_login::auth::AgentIdentityAuth;
|
||||
use codex_login::auth::AgentIdentityAuthError;
|
||||
use codex_login::auth::AgentIdentityAuthPolicy;
|
||||
@@ -112,11 +112,11 @@ impl AuthProvider for AgentIdentityAuthProvider {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct HostProvidedAuthProvider {
|
||||
auth: HostProvidedAuth,
|
||||
struct CallerProvidedAuthProvider {
|
||||
auth: CallerProvidedAuth,
|
||||
}
|
||||
|
||||
impl AuthProvider for HostProvidedAuthProvider {
|
||||
impl AuthProvider for CallerProvidedAuthProvider {
|
||||
fn add_auth_headers(&self, headers: &mut HeaderMap) {
|
||||
for (name, value) in self.auth.headers() {
|
||||
let Ok(name) = HeaderName::from_bytes(name.as_bytes()) else {
|
||||
@@ -266,8 +266,8 @@ fn bearer_auth_for_provider(
|
||||
/// Builds request-header auth for a first-party Codex auth snapshot.
|
||||
pub fn auth_provider_from_auth(auth: &CodexAuth) -> SharedAuthProvider {
|
||||
match auth {
|
||||
CodexAuth::HostProvided(auth) => {
|
||||
Arc::new(HostProvidedAuthProvider { auth: auth.clone() })
|
||||
CodexAuth::CallerProvided(auth) => {
|
||||
Arc::new(CallerProvidedAuthProvider { auth: auth.clone() })
|
||||
}
|
||||
CodexAuth::AgentIdentity(auth) => {
|
||||
Arc::new(AgentIdentityAuthProvider { auth: auth.clone() })
|
||||
@@ -435,9 +435,9 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn host_provided_auth_provider_uses_host_headers() {
|
||||
let auth = CodexAuth::HostProvided(
|
||||
HostProvidedAuth::new(
|
||||
fn caller_provided_auth_provider_uses_caller_headers() {
|
||||
let auth = CodexAuth::CallerProvided(
|
||||
CallerProvidedAuth::new(
|
||||
[(
|
||||
"x-openai-actor-authorization".to_string(),
|
||||
"actor-token".to_string(),
|
||||
|
||||
@@ -286,7 +286,7 @@ impl ModelProvider for ConfiguredModelProvider {
|
||||
}
|
||||
CodexAuth::Chatgpt(_)
|
||||
| CodexAuth::ChatgptAuthTokens(_)
|
||||
| CodexAuth::HostProvided(_)
|
||||
| CodexAuth::CallerProvided(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_) => {
|
||||
let email = auth.get_account_email();
|
||||
|
||||
@@ -59,7 +59,7 @@ impl From<AuthMode> for TelemetryAuthMode {
|
||||
AuthMode::ApiKey | AuthMode::BedrockApiKey => Self::ApiKey,
|
||||
AuthMode::Chatgpt
|
||||
| AuthMode::ChatgptAuthTokens
|
||||
| AuthMode::HostProvided
|
||||
| AuthMode::CallerProvided
|
||||
| AuthMode::AgentIdentity
|
||||
| AuthMode::PersonalAccessToken => Self::Chatgpt,
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@ pub enum AuthMode {
|
||||
#[serde(rename = "chatgptAuthTokens")]
|
||||
#[strum(serialize = "chatgptAuthTokens")]
|
||||
ChatgptAuthTokens,
|
||||
/// Codex backend request headers supplied by the process embedding Codex.
|
||||
#[serde(rename = "hostProvided")]
|
||||
#[strum(serialize = "hostProvided")]
|
||||
HostProvided,
|
||||
/// Backend auth supplied programmatically by the caller.
|
||||
///
|
||||
/// Request headers are kept in memory and are not persisted or refreshed by Codex.
|
||||
#[serde(rename = "callerProvided")]
|
||||
#[strum(serialize = "callerProvided")]
|
||||
CallerProvided,
|
||||
/// Programmatic Codex auth backed by a registered Agent Identity.
|
||||
#[serde(rename = "agentIdentity")]
|
||||
#[strum(serialize = "agentIdentity")]
|
||||
@@ -38,7 +40,9 @@ impl AuthMode {
|
||||
pub fn has_chatgpt_account(self) -> bool {
|
||||
match self {
|
||||
Self::Chatgpt | Self::ChatgptAuthTokens | Self::PersonalAccessToken => true,
|
||||
Self::ApiKey | Self::HostProvided | Self::AgentIdentity | Self::BedrockApiKey => false,
|
||||
Self::ApiKey | Self::CallerProvided | Self::AgentIdentity | Self::BedrockApiKey => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +51,7 @@ impl AuthMode {
|
||||
match self {
|
||||
Self::Chatgpt
|
||||
| Self::ChatgptAuthTokens
|
||||
| Self::HostProvided
|
||||
| Self::CallerProvided
|
||||
| Self::AgentIdentity
|
||||
| Self::PersonalAccessToken => true,
|
||||
Self::ApiKey | Self::BedrockApiKey => false,
|
||||
|
||||
@@ -86,7 +86,7 @@ impl App {
|
||||
Some(
|
||||
AuthMode::Chatgpt
|
||||
| AuthMode::ChatgptAuthTokens
|
||||
| AuthMode::HostProvided
|
||||
| AuthMode::CallerProvided
|
||||
| AuthMode::AgentIdentity
|
||||
| AuthMode::PersonalAccessToken
|
||||
)
|
||||
|
||||
@@ -1202,7 +1202,7 @@ pub(crate) fn status_account_display_from_auth_mode(
|
||||
Some(AuthMode::ApiKey) => Some(StatusAccountDisplay::ApiKey),
|
||||
Some(AuthMode::Chatgpt)
|
||||
| Some(AuthMode::ChatgptAuthTokens)
|
||||
| Some(AuthMode::HostProvided)
|
||||
| Some(AuthMode::CallerProvided)
|
||||
| Some(AuthMode::AgentIdentity)
|
||||
| Some(AuthMode::PersonalAccessToken) => Some(StatusAccountDisplay::ChatGpt {
|
||||
email: None,
|
||||
|
||||
@@ -950,7 +950,7 @@ impl AuthModeWidget {
|
||||
ApiAuthMode::ApiKey => AuthMode::ApiKey,
|
||||
ApiAuthMode::Chatgpt => AuthMode::Chatgpt,
|
||||
ApiAuthMode::ChatgptAuthTokens => AuthMode::ChatgptAuthTokens,
|
||||
ApiAuthMode::HostProvided => AuthMode::HostProvided,
|
||||
ApiAuthMode::CallerProvided => AuthMode::CallerProvided,
|
||||
ApiAuthMode::AgentIdentity => AuthMode::AgentIdentity,
|
||||
ApiAuthMode::PersonalAccessToken => AuthMode::PersonalAccessToken,
|
||||
ApiAuthMode::BedrockApiKey => AuthMode::BedrockApiKey,
|
||||
|
||||
Reference in New Issue
Block a user