Skip to content

[codex] request desktop attestation from app#20619

Merged
jiamingz42 merged 23 commits into
mainfrom
dev/jm/devicecheck-codex-app
May 8, 2026
Merged

[codex] request desktop attestation from app#20619
jiamingz42 merged 23 commits into
mainfrom
dev/jm/devicecheck-codex-app

Conversation

@jiamingz42
Copy link
Copy Markdown
Contributor

@jiamingz42 jiamingz42 commented May 1, 2026

Summary

TL;DR: teaches codex-rs / app-server to request a desktop-provided attestation token and attach it as x-oai-attestation on the scoped ChatGPT Codex request paths.

DeviceCheck attestation interface

Details

This PR teaches the Codex app-server runtime how to request and attach an attestation token. It does not generate DeviceCheck tokens directly; instead, it relies on the connected desktop app to advertise that it can generate attestation and then asks that app for a fresh header value when needed.

The flow is:

  1. The Codex desktop app connects to app-server.
  2. During initialize, the app can advertise that it supports requestAttestation.
  3. Before app-server calls selected ChatGPT Codex endpoints, it sends the internal server request attestation/generate to the app.
  4. app-server receives a pre-encoded header value back.
  5. app-server forwards that value as x-oai-attestation on the scoped outbound requests.

The code in this repo is mostly protocol and runtime plumbing: it adds the app-server request/response shape, introduces an attestation provider in core, wires that provider into Responses / compaction / realtime setup paths, and covers the intended scoping with tests. The signed macOS DeviceCheck generation remains owned by the desktop app PR.

Related PR

Validation

Tests run
cargo test -p codex-app-server-protocol
cargo test -p codex-core attestation --lib
cargo test -p codex-app-server --lib attestation

Also ran:

just fix -p codex-core
just fix -p codex-app-server
just fix -p codex-app-server-protocol
just fmt
just write-app-server-schema
E2E DeviceCheck validation

First validated the signed desktop app boundary directly: launched a packaged signed Codex.app, sent attestation/generate, decoded the returned v1. attestation header, and validated the extracted DeviceCheck token with personal/jm/verify_devicecheck_token.py using bundle ID com.openai.codex. Apple returned status_code: 200 and is_ok: true.

Then ran the fuller app + app-server flow. The packaged Codex.app launched a current-branch app-server via CODEX_CLI_PATH, and a local MITM proxy intercepted outbound chatgpt.com traffic. The app-server requested attestation/generate from the real Electron app process, and the intercepted /backend-api/codex/responses traffic included x-oai-attestation on both routes:

GET  /backend-api/codex/responses  Upgrade: websocket  x-oai-attestation: present
POST /backend-api/codex/responses  Upgrade: none       x-oai-attestation: present

The captured header decoded to a DeviceCheck token that also validated with Apple for com.openai.codex (status_code: 200, is_ok: true, team 2DC432GLL2).

chatgpt-codex-connector[bot]

This comment was marked as outdated.

@jiamingz42
Copy link
Copy Markdown
Contributor Author

Addressed in 3cbcba1: websocket handshake headers now go through the same scoped AttestationPurpose::Response path as HTTP /responses, and I added a regression test covering x-oai-attestation on the websocket handshake. (Reply by Codex)

@jiamingz42 jiamingz42 marked this pull request as draft May 6, 2026 06:25
@jiamingz42 jiamingz42 force-pushed the dev/jm/devicecheck-codex-app branch from 3cbcba1 to 698e598 Compare May 6, 2026 06:37
@jiamingz42 jiamingz42 marked this pull request as ready for review May 6, 2026 06:45
@jiamingz42
Copy link
Copy Markdown
Contributor Author

Just did a rebase and resolved some conflicts. Need to double check it does not break anything. (Reply by Codex)

Comment thread codex-rs/app-server/tests/suite/v2/initialize.rs
Comment thread codex-rs/app-server/src/message_processor.rs Outdated
Comment thread codex-rs/core/src/thread_manager.rs Outdated
Comment thread codex-rs/core/src/client.rs Outdated
Comment thread codex-rs/core/src/client.rs Outdated
Comment thread codex-rs/core/src/client.rs Outdated
Comment thread codex-rs/core/src/client.rs Outdated
Comment thread codex-rs/core/src/attestation.rs Outdated
Comment thread codex-rs/core/src/client_tests.rs Outdated
Comment thread codex-rs/app-server/src/message_processor.rs Outdated
Comment thread codex-rs/app-server/src/message_processor.rs Outdated
Comment thread codex-rs/app-server/src/message_processor.rs Outdated
@jiamingz42 jiamingz42 force-pushed the dev/jm/devicecheck-codex-app branch from aa60c6e to a996616 Compare May 7, 2026 19:13
Comment thread codex-rs/app-server-protocol/src/protocol/v2/attestation.rs Outdated
Comment thread codex-rs/core/src/client.rs
Comment thread codex-rs/core/src/client.rs Outdated
Copy link
Copy Markdown
Collaborator

@pakrym-oai pakrym-oai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try and drop uses_chatgpt_auth from ApiProvider. ApiProvider is an abstraction that should know about details of the provider implementation.

Comment thread codex-rs/core/src/client.rs Outdated
@jiamingz42
Copy link
Copy Markdown
Contributor Author

🙏 @euroelessar @pakrym-oai it's green now. taking a last pass and then merging it.

@jiamingz42 jiamingz42 merged commit 5f4d0ec into main May 8, 2026
37 of 38 checks passed
@jiamingz42 jiamingz42 deleted the dev/jm/devicecheck-codex-app branch May 8, 2026 19:36
@github-actions github-actions Bot locked and limited conversation to collaborators May 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants