refactor(attestation): return header values from provider

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Jiaming Zhang
2026-05-06 22:00:04 -07:00
parent bb55e050d7
commit 4e4e6b6114
4 changed files with 12 additions and 12 deletions

View File

@@ -38,6 +38,7 @@ use crate::thread_state::ThreadStateManager;
use crate::transport::AppServerTransport;
use crate::transport::RemoteControlHandle;
use async_trait::async_trait;
use axum::http::HeaderValue;
use codex_analytics::AnalyticsEventsClient;
use codex_analytics::AppServerRpcTransport;
use codex_app_server_protocol::AttestationGenerateParams;
@@ -181,7 +182,7 @@ impl std::fmt::Debug for AppServerAttestationProvider {
}
impl AttestationProvider for AppServerAttestationProvider {
fn generate_header_value(&self, context: AttestationContext) -> GenerateAttestationFuture<'_> {
fn header_for_request(&self, context: AttestationContext) -> GenerateAttestationFuture<'_> {
let outgoing = self.outgoing.clone();
let attestation_connection_ids = self.attestation_connection_ids.clone();
Box::pin(async move {
@@ -195,6 +196,7 @@ impl AttestationProvider for AppServerAttestationProvider {
ATTESTATION_GENERATE_TIMEOUT,
)
.await
.and_then(|value| HeaderValue::from_bytes(value.as_bytes()).ok())
})
}
}

View File

@@ -1,9 +1,12 @@
use std::future::Future;
use std::pin::Pin;
use http::HeaderValue;
pub(crate) const X_OAI_ATTESTATION_HEADER: &str = "x-oai-attestation";
pub type GenerateAttestationFuture<'a> = Pin<Box<dyn Future<Output = Option<String>> + Send + 'a>>;
pub type GenerateAttestationFuture<'a> =
Pin<Box<dyn Future<Output = Option<HeaderValue>> + Send + 'a>>;
/// Request context that host integrations can use when deciding whether to
/// generate an attestation header value.
@@ -15,8 +18,7 @@ pub struct AttestationContext {
/// Host integration boundary for just-in-time attestation header values.
///
/// Implementations own the policy for when attestation should be attempted and
/// return the opaque string expected by the upstream `x-oai-attestation`
/// header. Core only forwards valid HTTP header values returned by the host.
/// return the upstream `x-oai-attestation` header value when one should be sent.
pub trait AttestationProvider: std::fmt::Debug + Send + Sync {
fn generate_header_value(&self, context: AttestationContext) -> GenerateAttestationFuture<'_>;
fn header_for_request(&self, context: AttestationContext) -> GenerateAttestationFuture<'_>;
}

View File

@@ -657,11 +657,10 @@ impl ModelClient {
self.state
.attestation_provider
.as_ref()?
.generate_header_value(AttestationContext {
.header_for_request(AttestationContext {
uses_chatgpt_auth: provider.uses_chatgpt_auth,
})
.await
.and_then(|value| HeaderValue::from_str(&value).ok())
}
/// Builds request telemetry for unary API calls (e.g., Compact endpoint).

View File

@@ -502,10 +502,7 @@ fn model_client_with_counting_attestation() -> (ModelClient, Arc<AtomicUsize>) {
}
impl AttestationProvider for CountingAttestationProvider {
fn generate_header_value(
&self,
context: AttestationContext,
) -> GenerateAttestationFuture<'_> {
fn header_for_request(&self, context: AttestationContext) -> GenerateAttestationFuture<'_> {
let calls = self.calls.clone();
Box::pin(async move {
if !context.uses_chatgpt_auth {
@@ -513,7 +510,7 @@ fn model_client_with_counting_attestation() -> (ModelClient, Arc<AtomicUsize>) {
}
let call = calls.fetch_add(1, Ordering::Relaxed) + 1;
Some(format!("v1.header-{call}"))
Some(http::HeaderValue::from_bytes(format!("v1.header-{call}").as_bytes()).unwrap())
})
}
}