mirror of
https://github.com/openai/codex.git
synced 2026-10-25 07:55:34 +00:00
Protect workload identity auth in app-server account RPCs (#38426)
## Why Workload identity credentials are owned by the app-server host and must not be replaced, removed, or exported through client account operations. ## What changed - Reject account login and logout RPCs while workload identity is selected. - Continue reporting the active authentication method from `getAuthStatus`, but omit the host-owned token even when `includeToken` is requested. GitOrigin-RevId: 750c9d07ed2f4ba7007bbe75f188573e79749647
This commit is contained in:
@@ -284,6 +284,9 @@ impl AccountRequestProcessor {
|
||||
request_id: ConnectionRequestId,
|
||||
params: LoginAccountParams,
|
||||
) -> Result<(), JSONRPCErrorError> {
|
||||
if self.auth_manager.is_workload_identity_selected() {
|
||||
return Err(self.configured_auth_owned_by_host_error());
|
||||
}
|
||||
match params {
|
||||
LoginAccountParams::ApiKey { api_key } => {
|
||||
self.login_api_key_v2(request_id, LoginApiKeyParams { api_key })
|
||||
@@ -341,6 +344,12 @@ impl AccountRequestProcessor {
|
||||
)
|
||||
}
|
||||
|
||||
fn configured_auth_owned_by_host_error(&self) -> JSONRPCErrorError {
|
||||
invalid_request(
|
||||
"Configured external authentication is owned by the app-server host and cannot be changed through account RPCs.",
|
||||
)
|
||||
}
|
||||
|
||||
async fn login_api_key_common(
|
||||
&self,
|
||||
params: &LoginApiKeyParams,
|
||||
@@ -868,6 +877,9 @@ impl AccountRequestProcessor {
|
||||
}
|
||||
|
||||
async fn logout_common(&self) -> std::result::Result<Option<AuthMode>, JSONRPCErrorError> {
|
||||
if self.auth_manager.is_workload_identity_selected() {
|
||||
return Err(self.configured_auth_owned_by_host_error());
|
||||
}
|
||||
let managed_bedrock_auth = matches!(
|
||||
self.auth_manager.auth_cached(),
|
||||
Some(CodexAuth::BedrockApiKey(_))
|
||||
@@ -986,30 +998,31 @@ impl AccountRequestProcessor {
|
||||
let permanent_refresh_failure =
|
||||
self.auth_manager.refresh_failure_for_auth(&auth).is_some();
|
||||
let auth_mode = auth_mode_to_api(auth.api_auth_mode());
|
||||
let (reported_auth_method, token_opt) = if matches!(
|
||||
auth,
|
||||
CodexAuth::Headers(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_)
|
||||
) || include_token
|
||||
&& permanent_refresh_failure
|
||||
{
|
||||
// This response cannot represent the metadata needed to reuse these
|
||||
// credentials.
|
||||
(Some(auth_mode), None)
|
||||
} else {
|
||||
match auth.get_token() {
|
||||
Ok(token) if !token.is_empty() => {
|
||||
let tok = if include_token { Some(token) } else { None };
|
||||
(Some(auth_mode), tok)
|
||||
let (reported_auth_method, token_opt) =
|
||||
if self.auth_manager.is_workload_identity_selected()
|
||||
|| matches!(
|
||||
auth,
|
||||
CodexAuth::Headers(_)
|
||||
| CodexAuth::AgentIdentity(_)
|
||||
| CodexAuth::PersonalAccessToken(_)
|
||||
)
|
||||
|| include_token && permanent_refresh_failure
|
||||
{
|
||||
// Host-owned and metadata-bearing credentials are never exported.
|
||||
(Some(auth_mode), None)
|
||||
} else {
|
||||
match auth.get_token() {
|
||||
Ok(token) if !token.is_empty() => {
|
||||
let tok = if include_token { Some(token) } else { None };
|
||||
(Some(auth_mode), tok)
|
||||
}
|
||||
Ok(_) => (None, None),
|
||||
Err(err) => {
|
||||
tracing::warn!("failed to get token for auth status: {err}");
|
||||
(None, None)
|
||||
}
|
||||
}
|
||||
Ok(_) => (None, None),
|
||||
Err(err) => {
|
||||
tracing::warn!("failed to get token for auth status: {err}");
|
||||
(None, None)
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
GetAuthStatusResponse {
|
||||
auth_method: reported_auth_method,
|
||||
auth_token: token_opt,
|
||||
|
||||
@@ -2612,6 +2612,10 @@ impl AuthManager {
|
||||
self.external_auth_provider().is_some()
|
||||
}
|
||||
|
||||
pub fn is_workload_identity_selected(&self) -> bool {
|
||||
self.workload_identity_selected
|
||||
}
|
||||
|
||||
pub fn is_external_chatgpt_auth_active(&self) -> bool {
|
||||
self.auth_cached()
|
||||
.as_ref()
|
||||
|
||||
Reference in New Issue
Block a user