Isolate Codex auth and provider transport

This commit is contained in:
Meta Vens 2026-08-24 16:09:55 +02:00
commit f64a52b6aa
6 changed files with 1460 additions and 16 deletions

View file

@ -7,11 +7,18 @@ owner, tool executor, decision store, or consumer runtime.
Keep one Cargo package and one production daemon entrypoint. Add another target
only when an independent lifecycle or privilege invariant requires it.
The daemon may own credential loading and refresh, upstream client identity,
authenticated caller admission, bounded concurrency/replay, provider transport,
typed events, and transport receipts. Consumers own native requests, provider
lowering, prompts, schemas, tool execution, retry between passes, interpretation,
decisions, and state admission.
The public daemon owns upstream client identity, authenticated caller admission,
bounded concurrency/replay, provider transport, typed events, and transport
receipts. A private pinned official `codex app-server` child is the sole
credential-store writer and refresh authority. The daemon may read its
credential only after their private auth RPC completes; it may never write or
repair the store. Consumers own native requests, provider lowering, prompts,
schemas, tool execution, retry between passes, interpretation, decisions, and
state admission.
Do not link upstream Codex crates into this package. Idunn freezes the official
Codex binary as an exact package input. The child receives auth RPC only, never
consumer identity, prompts, tools, provider requests, or model output.
Use typed Rust contracts, CultCache state, CultNet transport, and CultMesh/Eve
projection. JSON is permitted only at the upstream provider boundary or for

248
Cargo.lock generated
View file

@ -43,6 +43,12 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
name = "base64"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
[[package]]
name = "block-buffer"
version = "0.10.4"
@ -52,6 +58,22 @@ dependencies = [
"generic-array",
]
[[package]]
name = "bytes"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
[[package]]
name = "cc"
version = "1.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
@ -73,12 +95,15 @@ name = "codex-connector"
version = "0.1.0"
dependencies = [
"aes-gcm",
"base64",
"rand_core",
"rmp-serde",
"serde",
"serde_json",
"sha2",
"thiserror",
"ureq",
"zeroize",
]
[[package]]
@ -120,6 +145,12 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890"
[[package]]
name = "generic-array"
version = "0.14.7"
@ -151,6 +182,22 @@ dependencies = [
"polyval",
]
[[package]]
name = "http"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
dependencies = [
"bytes",
"itoa",
]
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "inout"
version = "0.1.4"
@ -172,6 +219,12 @@ version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]]
name = "log"
version = "0.4.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
[[package]]
name = "memchr"
version = "2.8.3"
@ -187,12 +240,24 @@ dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "opaque-debug"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "polyval"
version = "0.6.2"
@ -232,6 +297,20 @@ dependencies = [
"getrandom",
]
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"untrusted",
"windows-sys",
]
[[package]]
name = "rmp"
version = "0.8.15"
@ -251,6 +330,41 @@ dependencies = [
"serde",
]
[[package]]
name = "rustls"
version = "0.23.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
dependencies = [
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pki-types"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
dependencies = [
"zeroize",
]
[[package]]
name = "rustls-webpki"
version = "0.103.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "serde"
version = "1.0.229"
@ -305,6 +419,12 @@ dependencies = [
"digest",
]
[[package]]
name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "subtle"
version = "2.6.1"
@ -364,6 +484,46 @@ dependencies = [
"subtle",
]
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "ureq"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d"
dependencies = [
"base64",
"log",
"percent-encoding",
"rustls",
"rustls-pki-types",
"ureq-proto",
"utf8-zero",
"webpki-roots",
]
[[package]]
name = "ureq-proto"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da5f78b09e6941e1a0f2e30e695e4b120377b54d5e0aec11b594bb57b3971613"
dependencies = [
"base64",
"http",
"httparse",
"log",
]
[[package]]
name = "utf8-zero"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
[[package]]
name = "version_check"
version = "0.9.5"
@ -376,6 +536,94 @@ version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "webpki-roots"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zeroize"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
[[package]]
name = "zmij"
version = "1.0.23"

View file

@ -13,9 +13,12 @@ path = "src/lib.rs"
[dependencies]
aes-gcm = "0.10"
base64 = "0.23"
rand_core = { version = "0.6", features = ["getrandom"] }
rmp-serde = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = "0.10"
thiserror = "2"
ureq = { version = "3.4", default-features = false, features = ["rustls"] }
zeroize = "1"

View file

@ -5,17 +5,27 @@ subscription inference. Epiphany and Ghostlight remain separate minds. They
derive their own exact provider requests, execute their own tools, interpret
their own results, and admit their own state.
The connector owns one writable credential/refresh store, authenticated caller
admission, bounded transport physiology, exact provider-request receipts, and
redacted CultMesh health. It owns no prompt policy or decision authority.
The service owns authenticated caller admission, bounded transport physiology,
exact provider-request receipts, and redacted CultMesh health. A private pinned
official `codex app-server` child is the sole writer and refresh authority for
one credential store. The public connector reads the credential only after the
child's private auth RPC completes, then performs the exact Responses request.
It owns no prompt policy or decision authority.
The current source establishes the v2 typed contract and its transport-neutral
service core before adding the daemon shell. The core admits distinct caller
keys and policies, returns an exact cached response for byte-identical retries,
refuses conflicting or concurrent reuse of one caller/request identity, and
leaves provider execution outside its lock. The existing Yggdrasil connector
already proves the process seam, but its single-caller, fixed-model, stateless,
no-tools wire law cannot become the shared contract by inertia.
The current source establishes the v2 typed contract, its transport-neutral
service core, and the private Codex-auth/provider backend before adding the
public listener shell. The core admits distinct caller keys and policies,
returns an exact cached response for byte-identical retries, refuses conflicting
or concurrent reuse of one caller/request identity, and leaves provider
execution outside its lock. The backend verifies the exact child binary and
reported Codex home, limits child RPC to authentication, reads API-key or
ChatGPT credentials without publishing their identity, retries one ChatGPT 401
only after the official writer advances the credential store, and lowers raw
SSE into typed text, tool-call, usage, and failure receipts.
No upstream Codex crate is linked into the package. The official binary is a
pinned deployment input, keeping Codex's application build graph outside both
consumers and this small daemon.
## Contract invariant

View file

@ -7,6 +7,14 @@ use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use thiserror::Error;
mod provider_backend;
pub use provider_backend::CodexAppServerConfig;
pub use provider_backend::CodexAuthMode;
pub use provider_backend::CodexAuthReadiness;
pub use provider_backend::CodexProviderBackend;
pub use provider_backend::CodexProviderBackendError;
pub const PROVIDER_REQUEST_SCHEMA_ID: &str = "gamecult.codex.provider_request.v2";
pub const INVOCATION_SCHEMA_ID: &str = "gamecult.codex.transport_invocation.v2";
pub const RESULT_SCHEMA_ID: &str = "gamecult.codex.transport_result.v2";

1168
src/provider_backend.rs Normal file

File diff suppressed because it is too large Load diff