From fe2aee1632a0fc2bdc3b939aab841daef72dd4df Mon Sep 17 00:00:00 2001 From: Cooper Gamble Date: Wed, 3 Jun 2026 03:20:55 +0000 Subject: [PATCH] [codex] wire per-surface integrity state transport [ci changed_files] --- codex-rs/Cargo.lock | 2 + codex-rs/codex-client/src/chatgpt_hosts.rs | 33 +++++++++++++ codex-rs/codex-client/src/default_client.rs | 47 +++++++++++++++++- codex-rs/codex-client/src/lib.rs | 4 ++ codex-rs/core/Cargo.toml | 1 + codex-rs/core/src/agent/control.rs | 4 +- codex-rs/core/src/agent/control_tests.rs | 8 +-- codex-rs/core/src/client.rs | 48 +++++++++--------- codex-rs/core/src/codex_delegate.rs | 8 +-- codex-rs/core/src/codex_delegate_tests.rs | 14 ++---- codex-rs/core/src/mcp_openai_file.rs | 22 ++++----- codex-rs/model-provider/Cargo.toml | 1 + codex-rs/model-provider/src/auth.rs | 4 +- .../src/bearer_auth_provider.rs | 49 +++++++++---------- 14 files changed, 158 insertions(+), 87 deletions(-) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index ef4ed0970f..892e2ee09a 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -2539,6 +2539,7 @@ dependencies = [ "codex-feedback", "codex-git-utils", "codex-hooks", + "codex-http-state", "codex-install-context", "codex-login", "codex-mcp", @@ -3311,6 +3312,7 @@ dependencies = [ "codex-aws-auth", "codex-client", "codex-feedback", + "codex-http-state", "codex-login", "codex-model-provider-info", "codex-models-manager", diff --git a/codex-rs/codex-client/src/chatgpt_hosts.rs b/codex-rs/codex-client/src/chatgpt_hosts.rs index dd0b99589c..7ab6819e79 100644 --- a/codex-rs/codex-client/src/chatgpt_hosts.rs +++ b/codex-rs/codex-client/src/chatgpt_hosts.rs @@ -10,6 +10,18 @@ pub fn is_allowed_chatgpt_host(host: &str) -> bool { .any(|suffix| host.ends_with(suffix)) } +/// Returns whether `url` is an HTTPS or secure WebSocket ChatGPT URL that Codex +/// may treat as first-party traffic. +pub fn is_allowed_chatgpt_request_url(url: &str) -> bool { + let Ok(url) = reqwest::Url::parse(url) else { + return false; + }; + if !matches!(url.scheme(), "https" | "wss") { + return false; + } + url.host_str().is_some_and(is_allowed_chatgpt_host) +} + #[cfg(test)] mod tests { use super::*; @@ -36,4 +48,25 @@ mod tests { assert!(!is_allowed_chatgpt_host(host)); } } + + #[test] + fn recognizes_secure_chatgpt_request_urls() { + for url in [ + "https://chatgpt.com/backend-api/codex/responses", + "https://preview.chatgpt.com/backend-api/codex/models", + "wss://chatgpt-staging.com/backend-api/codex/responses", + ] { + assert!(is_allowed_chatgpt_request_url(url)); + } + + for url in [ + "http://chatgpt.com/backend-api/codex/responses", + "ws://chatgpt.com/backend-api/codex/responses", + "https://api.openai.com/v1/responses", + "https://chatgpt.com.evil.example/backend-api", + "not a url", + ] { + assert!(!is_allowed_chatgpt_request_url(url)); + } + } } diff --git a/codex-rs/codex-client/src/default_client.rs b/codex-rs/codex-client/src/default_client.rs index 56b3ce4b16..a57b1dc338 100644 --- a/codex-rs/codex-client/src/default_client.rs +++ b/codex-rs/codex-client/src/default_client.rs @@ -1,3 +1,5 @@ +use crate::INTEGRITY_STATE_HEADER_NAME; +use crate::INTEGRITY_STATE_UPDATE_HEADER_NAME; use http::Error as HttpError; use http::HeaderMap; use http::HeaderName; @@ -115,11 +117,12 @@ impl CodexRequestBuilder { match self.builder.headers(headers).send().await { Ok(response) => { + let headers = redacted_headers_for_logging(response.headers()); tracing::debug!( method = %self.method, url = %self.url, status = %response.status(), - headers = ?response.headers(), + headers = ?headers, version = ?response.version(), "Request completed" ); @@ -141,6 +144,19 @@ impl CodexRequestBuilder { } } +fn redacted_headers_for_logging(headers: &HeaderMap) -> HeaderMap { + let mut headers = headers.clone(); + for name in [ + INTEGRITY_STATE_HEADER_NAME, + INTEGRITY_STATE_UPDATE_HEADER_NAME, + ] { + if headers.contains_key(name) { + headers.insert(name, HeaderValue::from_static("")); + } + } + headers +} + struct HeaderMapInjector<'a>(&'a mut HeaderMap); impl<'a> Injector for HeaderMapInjector<'a> { @@ -174,10 +190,39 @@ mod tests { use opentelemetry::trace::TracerProvider; use opentelemetry_sdk::propagation::TraceContextPropagator; use opentelemetry_sdk::trace::SdkTracerProvider; + use pretty_assertions::assert_eq; use tracing::trace_span; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; + #[test] + fn redacted_headers_for_logging_hides_integrity_state() { + let mut headers = HeaderMap::new(); + headers.insert( + INTEGRITY_STATE_HEADER_NAME, + HeaderValue::from_static("ois1.request.nonce.ciphertext"), + ); + headers.insert( + INTEGRITY_STATE_UPDATE_HEADER_NAME, + HeaderValue::from_static("ois1.response.nonce.ciphertext"), + ); + headers.insert("x-request-id", HeaderValue::from_static("request-id")); + + let redacted = redacted_headers_for_logging(&headers); + + let mut expected = HeaderMap::new(); + expected.insert( + INTEGRITY_STATE_HEADER_NAME, + HeaderValue::from_static(""), + ); + expected.insert( + INTEGRITY_STATE_UPDATE_HEADER_NAME, + HeaderValue::from_static(""), + ); + expected.insert("x-request-id", HeaderValue::from_static("request-id")); + assert_eq!(redacted, expected); + } + #[test] fn inject_trace_headers_uses_current_span_context() { global::set_text_map_propagator(TraceContextPropagator::new()); diff --git a/codex-rs/codex-client/src/lib.rs b/codex-rs/codex-client/src/lib.rs index 0f503fb3e2..a8eea88922 100644 --- a/codex-rs/codex-client/src/lib.rs +++ b/codex-rs/codex-client/src/lib.rs @@ -11,6 +11,7 @@ mod transport; pub use crate::chatgpt_cloudflare_cookies::with_chatgpt_cloudflare_cookie_store; pub use crate::chatgpt_hosts::is_allowed_chatgpt_host; +pub use crate::chatgpt_hosts::is_allowed_chatgpt_request_url; pub use crate::custom_ca::BuildCustomCaTransportError; /// Test-only subprocess hook for custom CA coverage. /// @@ -40,3 +41,6 @@ pub use crate::transport::ByteStream; pub use crate::transport::HttpTransport; pub use crate::transport::ReqwestTransport; pub use crate::transport::StreamResponse; + +pub const INTEGRITY_STATE_HEADER_NAME: &str = "x-oai-is"; +pub const INTEGRITY_STATE_UPDATE_HEADER_NAME: &str = "x-oai-is-update"; diff --git a/codex-rs/core/Cargo.toml b/codex-rs/core/Cargo.toml index 88cd61ce37..9139f394a1 100644 --- a/codex-rs/core/Cargo.toml +++ b/codex-rs/core/Cargo.toml @@ -48,6 +48,7 @@ codex-shell-command = { workspace = true } codex-execpolicy = { workspace = true } codex-git-utils = { workspace = true } codex-hooks = { workspace = true } +codex-http-state = { workspace = true } codex-install-context = { workspace = true } codex-network-proxy = { workspace = true } codex-otel = { workspace = true } diff --git a/codex-rs/core/src/agent/control.rs b/codex-rs/core/src/agent/control.rs index 06c93cbbb0..36fdb91a86 100644 --- a/codex-rs/core/src/agent/control.rs +++ b/codex-rs/core/src/agent/control.rs @@ -312,7 +312,7 @@ impl AgentControl { .session .services .model_client - .native_integrity_surface() + .http_state_surface() { new_thread .thread @@ -320,7 +320,7 @@ impl AgentControl { .session .services .model_client - .set_native_integrity_surface(surface); + .set_http_state_surface(surface); } parent_thread .codex diff --git a/codex-rs/core/src/agent/control_tests.rs b/codex-rs/core/src/agent/control_tests.rs index c2bbbaf10f..3971434c08 100644 --- a/codex-rs/core/src/agent/control_tests.rs +++ b/codex-rs/core/src/agent/control_tests.rs @@ -10,8 +10,8 @@ use crate::context::ContextualUserFragment; use crate::context::SubagentNotification; use crate::init_state_db; use assert_matches::assert_matches; -use codex_client::NativeIntegritySurface; use codex_features::Feature; +use codex_http_state::HttpStateSurface; use codex_login::CodexAuth; use codex_protocol::AgentPath; use codex_protocol::config_types::ModeKind; @@ -1586,7 +1586,7 @@ async fn spawn_child_completion_notifies_parent_history() { } #[tokio::test] -async fn spawn_thread_subagent_inherits_parent_native_integrity_surface() { +async fn spawn_thread_subagent_inherits_parent_http_state_surface() { let harness = AgentControlHarness::new().await; let (parent_thread_id, parent_thread) = harness.start_thread().await; parent_thread @@ -1625,8 +1625,8 @@ async fn spawn_thread_subagent_inherits_parent_native_integrity_surface() { .session .services .model_client - .native_integrity_surface(), - Some(NativeIntegritySurface::CodexDesktop) + .http_state_surface(), + Some(HttpStateSurface::CodexDesktop) ); } diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs index 6327fda059..74dd9860d7 100644 --- a/codex-rs/core/src/client.rs +++ b/codex-rs/core/src/client.rs @@ -62,8 +62,8 @@ use codex_api::build_session_headers; use codex_api::create_text_param_for_request; use codex_api::response_create_client_metadata; use codex_app_server_protocol::AuthMode; -use codex_client::NativeIntegrityStateContext; -use codex_client::NativeIntegritySurface; +use codex_http_state::HttpStateContext; +use codex_http_state::HttpStateSurface; use codex_login::AuthManager; use codex_login::CodexAuth; use codex_login::RefreshTokenError; @@ -183,7 +183,7 @@ struct ModelClientState { beta_features_header: Option, include_attestation: bool, attestation_provider: Option>, - native_integrity_state: Option, + http_state: Option, disable_websockets: AtomicBool, cached_websocket_session: StdMutex, } @@ -333,10 +333,10 @@ impl ModelClient { beta_features_header: Option, attestation_provider: Option>, ) -> Self { - let native_integrity_state = auth_manager.as_ref().map(|auth_manager| { - NativeIntegrityStateContext::new( + let http_state = auth_manager.as_ref().map(|auth_manager| { + HttpStateContext::new( auth_manager.codex_home().to_path_buf(), - native_integrity_surface_for_session_source(&session_source), + http_state_surface_for_session_source(&session_source), ) }); let model_provider = create_model_provider(provider_info, auth_manager); @@ -363,7 +363,7 @@ impl ModelClient { beta_features_header, include_attestation, attestation_provider, - native_integrity_state, + http_state, disable_websockets: AtomicBool::new(false), cached_websocket_session: StdMutex::new(WebsocketSession::default()), }), @@ -403,26 +403,26 @@ impl ModelClient { pub(crate) fn set_app_server_client_name(&self, client_name: Option<&str>) { let surface = client_name - .map(NativeIntegritySurface::from_app_server_client_name) - .unwrap_or(NativeIntegritySurface::CodexCli); - self.set_native_integrity_surface(surface); + .map(HttpStateSurface::from_app_server_client_name) + .unwrap_or(HttpStateSurface::CodexCli); + self.set_http_state_surface(surface); } - pub(crate) fn native_integrity_surface(&self) -> Option { + pub(crate) fn http_state_surface(&self) -> Option { self.state - .native_integrity_state + .http_state .as_ref() - .map(NativeIntegrityStateContext::surface) + .map(HttpStateContext::surface) } - pub(crate) fn native_integrity_state_context(&self) -> Option { - self.state.native_integrity_state.clone() + pub(crate) fn http_state_context(&self) -> Option { + self.state.http_state.clone() } - pub(crate) fn set_native_integrity_surface(&self, surface: NativeIntegritySurface) { + pub(crate) fn set_http_state_surface(&self, surface: HttpStateSurface) { if self .state - .native_integrity_state + .http_state .as_ref() .is_some_and(|state| state.set_surface(surface)) { @@ -855,7 +855,7 @@ impl ModelClient { let api_auth = with_native_integrity_state( self.state.provider.api_auth().await?, auth.as_ref(), - self.state.native_integrity_state.clone(), + self.state.http_state.clone(), ); Ok(CurrentClientSetup { auth, @@ -1780,18 +1780,16 @@ fn subagent_header_value(session_source: &SessionSource) -> Option { } } -fn native_integrity_surface_for_session_source( - session_source: &SessionSource, -) -> NativeIntegritySurface { +fn http_state_surface_for_session_source(session_source: &SessionSource) -> HttpStateSurface { match session_source { - SessionSource::Cli => NativeIntegritySurface::CodexTui, - SessionSource::Exec => NativeIntegritySurface::CodexExec, - SessionSource::VSCode => NativeIntegritySurface::CodexVscode, + SessionSource::Cli => HttpStateSurface::CodexTui, + SessionSource::Exec => HttpStateSurface::CodexExec, + SessionSource::VSCode => HttpStateSurface::CodexVscode, SessionSource::SubAgent(_) | SessionSource::Internal(_) | SessionSource::Mcp | SessionSource::Custom(_) - | SessionSource::Unknown => NativeIntegritySurface::CodexCli, + | SessionSource::Unknown => HttpStateSurface::CodexCli, } } diff --git a/codex-rs/core/src/codex_delegate.rs b/codex-rs/core/src/codex_delegate.rs index 0b13959cc7..88f85b0b11 100644 --- a/codex-rs/core/src/codex_delegate.rs +++ b/codex-rs/core/src/codex_delegate.rs @@ -110,16 +110,12 @@ pub(crate) async fn run_codex_thread_interactive( })) .or_cancel(&cancel_token) .await??; - if let Some(surface) = parent_session - .services - .model_client - .native_integrity_surface() - { + if let Some(surface) = parent_session.services.model_client.http_state_surface() { codex .session .services .model_client - .set_native_integrity_surface(surface); + .set_http_state_surface(surface); } let thread_config = codex.thread_config_snapshot().await; let client_metadata = parent_session.app_server_client_metadata().await; diff --git a/codex-rs/core/src/codex_delegate_tests.rs b/codex-rs/core/src/codex_delegate_tests.rs index f62d9d4c1a..0cdb91a06b 100644 --- a/codex-rs/core/src/codex_delegate_tests.rs +++ b/codex-rs/core/src/codex_delegate_tests.rs @@ -2,7 +2,7 @@ use super::*; use crate::mcp_tool_call::MCP_TOOL_APPROVAL_DECLINE_SYNTHETIC; use crate::mcp_tool_call::MCP_TOOL_APPROVAL_QUESTION_ID_PREFIX; use async_channel::bounded; -use codex_client::NativeIntegritySurface; +use codex_http_state::HttpStateSurface; use codex_mcp::CODEX_APPS_MCP_SERVER_NAME; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::models::NetworkPermissions; @@ -183,13 +183,13 @@ async fn run_codex_thread_interactive_respects_pre_cancelled_spawn() { } #[tokio::test] -async fn run_codex_thread_interactive_inherits_parent_native_integrity_surface() { +async fn run_codex_thread_interactive_inherits_parent_http_state_surface() { let (parent_session, parent_ctx, _rx_events) = crate::session::tests::make_session_and_context_with_rx().await; parent_session .services .model_client - .set_native_integrity_surface(NativeIntegritySurface::CodexDesktop); + .set_http_state_surface(HttpStateSurface::CodexDesktop); let cancel_token = CancellationToken::new(); let delegated = run_codex_thread_interactive( @@ -206,12 +206,8 @@ async fn run_codex_thread_interactive_inherits_parent_native_integrity_surface() .expect("delegate should spawn"); assert_eq!( - delegated - .session - .services - .model_client - .native_integrity_surface(), - Some(NativeIntegritySurface::CodexDesktop) + delegated.session.services.model_client.http_state_surface(), + Some(HttpStateSurface::CodexDesktop) ); cancel_token.cancel(); } diff --git a/codex-rs/core/src/mcp_openai_file.rs b/codex-rs/core/src/mcp_openai_file.rs index a322389368..821cab7de9 100644 --- a/codex-rs/core/src/mcp_openai_file.rs +++ b/codex-rs/core/src/mcp_openai_file.rs @@ -13,7 +13,7 @@ use crate::session::session::Session; use crate::session::turn_context::TurnContext; use codex_api::upload_local_file; -use codex_client::NativeIntegrityStateContext; +use codex_http_state::HttpStateContext; use codex_login::CodexAuth; use serde_json::Value as JsonValue; @@ -34,7 +34,7 @@ pub(crate) async fn rewrite_mcp_tool_arguments_for_openai_files( return Ok(Some(arguments_value)); }; let auth = sess.services.auth_manager.auth().await; - let native_integrity_state = sess.services.model_client.native_integrity_state_context(); + let http_state = sess.services.model_client.http_state_context(); let mut rewritten_arguments = arguments.clone(); for field_name in openai_file_input_params { @@ -44,7 +44,7 @@ pub(crate) async fn rewrite_mcp_tool_arguments_for_openai_files( let Some(uploaded_value) = rewrite_argument_value_for_openai_files( turn_context, auth.as_ref(), - native_integrity_state.clone(), + http_state.clone(), field_name, value, ) @@ -65,7 +65,7 @@ pub(crate) async fn rewrite_mcp_tool_arguments_for_openai_files( async fn rewrite_argument_value_for_openai_files( turn_context: &TurnContext, auth: Option<&CodexAuth>, - native_integrity_state: Option, + http_state: Option, field_name: &str, value: &JsonValue, ) -> Result, String> { @@ -74,7 +74,7 @@ async fn rewrite_argument_value_for_openai_files( let rewritten = build_uploaded_local_argument_value( turn_context, auth, - native_integrity_state, + http_state, field_name, /*index*/ None, path_or_file_ref, @@ -91,7 +91,7 @@ async fn rewrite_argument_value_for_openai_files( let rewritten = build_uploaded_local_argument_value( turn_context, auth, - native_integrity_state.clone(), + http_state.clone(), field_name, Some(index), path_or_file_ref, @@ -108,7 +108,7 @@ async fn rewrite_argument_value_for_openai_files( async fn build_uploaded_local_argument_value( turn_context: &TurnContext, auth: Option<&CodexAuth>, - native_integrity_state: Option, + http_state: Option, field_name: &str, index: Option, file_path: &str, @@ -128,7 +128,7 @@ async fn build_uploaded_local_argument_value( let upload_auth = codex_model_provider::with_native_integrity_state( codex_model_provider::auth_provider_from_auth(auth), Some(auth), - native_integrity_state, + http_state, ); let uploaded = upload_local_file( turn_context.config.chatgpt_base_url.trim_end_matches('/'), @@ -244,7 +244,7 @@ mod tests { let rewritten = build_uploaded_local_argument_value( &turn_context, Some(&auth), - /*native_integrity_state*/ None, + /*http_state*/ None, "file", /*index*/ None, "file_report.csv", @@ -328,7 +328,7 @@ mod tests { let rewritten = rewrite_argument_value_for_openai_files( &turn_context, Some(&auth), - /*native_integrity_state*/ None, + /*http_state*/ None, "file", &serde_json::json!("file_report.csv"), ) @@ -446,7 +446,7 @@ mod tests { let rewritten = rewrite_argument_value_for_openai_files( &turn_context, Some(&auth), - /*native_integrity_state*/ None, + /*http_state*/ None, "files", &serde_json::json!(["one.csv", "two.csv"]), ) diff --git a/codex-rs/model-provider/Cargo.toml b/codex-rs/model-provider/Cargo.toml index 0bcf17cd97..965b118431 100644 --- a/codex-rs/model-provider/Cargo.toml +++ b/codex-rs/model-provider/Cargo.toml @@ -19,6 +19,7 @@ codex-agent-identity = { workspace = true } codex-aws-auth = { workspace = true } codex-client = { workspace = true } codex-feedback = { workspace = true } +codex-http-state = { workspace = true } codex-login = { workspace = true } codex-model-provider-info = { workspace = true } codex-models-manager = { workspace = true } diff --git a/codex-rs/model-provider/src/auth.rs b/codex-rs/model-provider/src/auth.rs index c2b01673ef..34f480b861 100644 --- a/codex-rs/model-provider/src/auth.rs +++ b/codex-rs/model-provider/src/auth.rs @@ -5,7 +5,7 @@ use codex_agent_identity::AgentTaskAuthorizationTarget; use codex_agent_identity::authorization_header_for_agent_task; use codex_api::AuthProvider; use codex_api::SharedAuthProvider; -use codex_client::NativeIntegrityStateContext; +use codex_http_state::HttpStateContext; use codex_login::AuthManager; use codex_login::CodexAuth; use codex_model_provider_info::ModelProviderInfo; @@ -125,7 +125,7 @@ pub fn auth_provider_from_auth(auth: &CodexAuth) -> SharedAuthProvider { pub fn with_native_integrity_state( auth_provider: SharedAuthProvider, auth: Option<&CodexAuth>, - state: Option, + state: Option, ) -> SharedAuthProvider { let Some(state) = state else { return auth_provider; diff --git a/codex-rs/model-provider/src/bearer_auth_provider.rs b/codex-rs/model-provider/src/bearer_auth_provider.rs index 7ccbfd8346..f971b18473 100644 --- a/codex-rs/model-provider/src/bearer_auth_provider.rs +++ b/codex-rs/model-provider/src/bearer_auth_provider.rs @@ -2,9 +2,9 @@ use codex_api::AuthProvider; use codex_api::SharedAuthProvider; use codex_client::INTEGRITY_STATE_HEADER_NAME; use codex_client::INTEGRITY_STATE_UPDATE_HEADER_NAME; -use codex_client::NativeIntegrityStateContext; -use codex_client::NativeIntegritySurface; use codex_client::is_allowed_chatgpt_request_url; +use codex_http_state::HttpStateContext; +use codex_http_state::HttpStateSurface; use http::HeaderMap; use http::HeaderValue; @@ -55,12 +55,12 @@ impl AuthProvider for BearerAuthProvider { #[derive(Clone)] pub(crate) struct NativeIntegrityAuthProvider { auth: SharedAuthProvider, - state: NativeIntegrityStateContext, - surface: NativeIntegritySurface, + state: HttpStateContext, + surface: HttpStateSurface, } impl NativeIntegrityAuthProvider { - pub(crate) fn new(auth: SharedAuthProvider, state: NativeIntegrityStateContext) -> Self { + pub(crate) fn new(auth: SharedAuthProvider, state: HttpStateContext) -> Self { let surface = state.surface(); Self { auth, @@ -81,9 +81,9 @@ impl AuthProvider for NativeIntegrityAuthProvider { return; } - match self.state.load_for_surface(self.surface) { - Ok(Some(state_file)) => { - if let Ok(header) = HeaderValue::from_str(&state_file.state) { + match self.state.get_for_surface(self.surface) { + Ok(Some(state)) => { + if let Ok(header) = HeaderValue::from_str(&state) { let _ = headers.insert(INTEGRITY_STATE_HEADER_NAME, header); } } @@ -119,7 +119,7 @@ impl AuthProvider for NativeIntegrityAuthProvider { return; }; - if let Err(error) = self.state.compare_and_store_for_surface( + if let Err(error) = self.state.compare_and_set_for_surface( self.surface, expected_state, next_state.to_string(), @@ -132,8 +132,7 @@ impl AuthProvider for NativeIntegrityAuthProvider { #[cfg(test)] mod tests { use super::*; - use codex_client::NativeIntegrityStateFile; - use codex_client::NativeIntegrityStateStore; + use codex_http_state::HttpStateStore; use pretty_assertions::assert_eq; use std::sync::Arc; use tempfile::TempDir; @@ -198,14 +197,14 @@ mod tests { #[test] fn native_integrity_provider_scopes_and_rotates_surface_state() { let codex_home = TempDir::new().expect("tempdir"); - let context = NativeIntegrityStateContext::new( + let context = HttpStateContext::new( codex_home.path().to_path_buf(), - NativeIntegritySurface::CodexDesktop, + HttpStateSurface::CodexDesktop, ); - let store = NativeIntegrityStateStore::new(codex_home.path().to_path_buf()); + let store = HttpStateStore::new(codex_home.path().to_path_buf()); store - .replace( - NativeIntegritySurface::CodexDesktop, + .set( + HttpStateSurface::CodexDesktop, "ois1.initial.nonce.ciphertext".to_string(), ) .expect("state should store"); @@ -213,10 +212,10 @@ mod tests { Arc::new(BearerAuthProvider::new("access-token".to_string())), context.clone(), ); - context.set_surface(NativeIntegritySurface::CodexCli); + context.set_surface(HttpStateSurface::CodexCli); store - .replace( - NativeIntegritySurface::CodexCli, + .set( + HttpStateSurface::CodexCli, "ois1.cli.nonce.ciphertext".to_string(), ) .expect("CLI state should store"); @@ -245,21 +244,17 @@ mod tests { ); assert_eq!( store - .load(NativeIntegritySurface::CodexDesktop) + .get(HttpStateSurface::CodexDesktop) .expect("state should load") .expect("state should exist"), - NativeIntegrityStateFile { - state: "ois1.rotated.nonce.ciphertext".to_string(), - } + "ois1.rotated.nonce.ciphertext" ); assert_eq!( store - .load(NativeIntegritySurface::CodexCli) + .get(HttpStateSurface::CodexCli) .expect("CLI state should load") .expect("CLI state should exist"), - NativeIntegrityStateFile { - state: "ois1.cli.nonce.ciphertext".to_string(), - } + "ois1.cli.nonce.ciphertext" ); let mut external_headers = HeaderMap::new();