mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
5882f3f95e
## Summary This PR moves Codex backend request authentication from direct bearer-token handling to `AuthProvider`. The new `codex-auth-provider` crate defines the shared request-auth trait. `CodexAuth::provider()` returns a provider that can apply all headers needed for the selected auth mode. This lets ChatGPT token auth and AgentIdentity auth share the same callsite path: - ChatGPT token auth applies bearer auth plus account/FedRAMP headers where needed. - AgentIdentity auth applies AgentAssertion plus account/FedRAMP headers where needed. Reference old stack: https://github.com/openai/codex/pull/17387/changes ## Callsite Migration | Area | Change | | --- | --- | | backend-client | accepts an `AuthProvider` instead of a raw token/header | | chatgpt client/connectors | applies auth through `CodexAuth::provider()` | | cloud tasks | keeps Codex-backend gating, applies auth through provider | | cloud requirements | uses Codex-backend auth checks and provider headers | | app-server remote control | applies provider headers for backend calls | | MCP Apps/connectors | gates on `uses_codex_backend()` and keys caches from generic account getters | | model refresh | treats AgentIdentity as Codex-backend auth | | OpenAI file upload path | rejects non-Codex-backend auth before applying headers | | core client setup | keeps model-provider auth flow and allows AgentIdentity through provider-backed OpenAI auth | ## Stack 1. https://github.com/openai/codex/pull/18757: full revert 2. https://github.com/openai/codex/pull/18871: isolated Agent Identity crate 3. https://github.com/openai/codex/pull/18785: explicit AgentIdentity auth mode and startup task allocation 4. This PR: migrate Codex backend auth callsites through AuthProvider 5. https://github.com/openai/codex/pull/18904: accept AgentIdentity JWTs and load `CODEX_AGENT_IDENTITY` ## Testing Tests: targeted Rust checks, cargo-shear, Bazel lock check, and CI.
111 lines
3.1 KiB
Rust
111 lines
3.1 KiB
Rust
use codex_api::AuthProvider;
|
|
use http::HeaderMap;
|
|
use http::HeaderValue;
|
|
|
|
/// Bearer-token auth provider for OpenAI-compatible model-provider requests.
|
|
#[derive(Clone, Default)]
|
|
pub struct BearerAuthProvider {
|
|
pub token: Option<String>,
|
|
pub account_id: Option<String>,
|
|
pub is_fedramp_account: bool,
|
|
}
|
|
|
|
impl BearerAuthProvider {
|
|
pub fn new(token: String) -> Self {
|
|
Self {
|
|
token: Some(token),
|
|
account_id: None,
|
|
is_fedramp_account: false,
|
|
}
|
|
}
|
|
|
|
pub fn for_test(token: Option<&str>, account_id: Option<&str>) -> Self {
|
|
Self {
|
|
token: token.map(str::to_string),
|
|
account_id: account_id.map(str::to_string),
|
|
is_fedramp_account: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AuthProvider for BearerAuthProvider {
|
|
fn add_auth_headers(&self, headers: &mut HeaderMap) {
|
|
if let Some(token) = self.token.as_ref()
|
|
&& let Ok(header) = HeaderValue::from_str(&format!("Bearer {token}"))
|
|
{
|
|
let _ = headers.insert(http::header::AUTHORIZATION, header);
|
|
}
|
|
if let Some(account_id) = self.account_id.as_ref()
|
|
&& let Ok(header) = HeaderValue::from_str(account_id)
|
|
{
|
|
let _ = headers.insert("ChatGPT-Account-ID", header);
|
|
}
|
|
if self.is_fedramp_account {
|
|
let _ = headers.insert("X-OpenAI-Fedramp", HeaderValue::from_static("true"));
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn bearer_auth_provider_reports_when_auth_header_will_attach() {
|
|
let auth = BearerAuthProvider {
|
|
token: Some("access-token".to_string()),
|
|
account_id: None,
|
|
is_fedramp_account: false,
|
|
};
|
|
|
|
assert_eq!(
|
|
codex_api::auth_header_telemetry(&auth),
|
|
codex_api::AuthHeaderTelemetry {
|
|
attached: true,
|
|
name: Some("authorization"),
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn bearer_auth_provider_adds_auth_headers() {
|
|
let auth = BearerAuthProvider::for_test(Some("access-token"), Some("workspace-123"));
|
|
let mut headers = HeaderMap::new();
|
|
|
|
auth.add_auth_headers(&mut headers);
|
|
|
|
assert_eq!(
|
|
headers
|
|
.get(http::header::AUTHORIZATION)
|
|
.and_then(|value| value.to_str().ok()),
|
|
Some("Bearer access-token")
|
|
);
|
|
assert_eq!(
|
|
headers
|
|
.get("ChatGPT-Account-ID")
|
|
.and_then(|value| value.to_str().ok()),
|
|
Some("workspace-123")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn bearer_auth_provider_adds_fedramp_routing_header_for_fedramp_accounts() {
|
|
let auth = BearerAuthProvider {
|
|
token: Some("access-token".to_string()),
|
|
account_id: Some("workspace-123".to_string()),
|
|
is_fedramp_account: true,
|
|
};
|
|
let mut headers = HeaderMap::new();
|
|
|
|
auth.add_auth_headers(&mut headers);
|
|
|
|
assert_eq!(
|
|
headers
|
|
.get("X-OpenAI-Fedramp")
|
|
.and_then(|value| value.to_str().ok()),
|
|
Some("true")
|
|
);
|
|
}
|
|
}
|