docs(reason): record auth scheme design loop output (round 1)#35
Merged
Conversation
Capture the /autoresearch reason loop output for the ccxray auth scheme under reason/260525-0055-ccxray-auth-design/. Round 1 ran two adversarial candidates (A: bearer + cookie redemption + in-memory session set; B: path-segregated domains + stateless HMAC + fragment bootstrap + Unix-socket hub IPC), generated an adversarial critique of A, and synthesized AB which three blind judges (architect / threat auditor / ops reviewer) unanimously preferred. Winning stance (read candidate-AB.md to implement): - Two domains: upstream (/v1/*) accepts only X-Ccxray-Auth header; dashboard accepts cookie + Bearer + X-Ccxray-Auth. - Stateless HMAC cookie derived via HKDF from AUTH_TOKEN so sessions survive hub idle-shutdown / crash-recovery. - One-time bootstrap via URL fragment (#k=…) redeemed by POST to /_auth/redeem; CLI subcommand "ccxray open" mints it. - Universal Host allowlist + Sec-Fetch-Site primary CSRF gate; no per-domain carve-out. - Hub IPC moves off HTTP onto a 0600 Unix domain socket gated by peer-UID. - Permanent Authorization: Bearer back-compat on the dashboard for existing curl / CI scripts. Migration is staged warn-only → enforce → cleanup; an 8-commit breakdown is being tracked separately as it lands. HANDOFF.md stays gitignored (matches the existing handoff.md rule — scratch session-bridging notes are not durable docs). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
External codex review of PR #35 flagged three blocking issues in candidate-AB.md, all confirmed empirically: 1. HttpOnly cookie cannot be probed via document.cookie — the inline bootstrap script's "no session" detection is broken as designed. Fix: GET /_auth/status probe instead. 2. net.Socket._handle.getpeereid does not exist on Node v22.22.2/darwin (and is not in the public Node API). Fix: filesystem 0600 socket + 0700 parent dir is the real gate; peer-UID check downgrades to "out of scope (would require native addon)." 3. Codex CLI key is model_providers.<name>.http_headers, not the request_headers in the doc. Verified by spy-server test that X-Ccxray-Auth does propagate when configured correctly. Open question on ChatGPT-OAuth-bypass surfaces a spike needed before Commit 1.4. Plus two non-blocking corrections (threat-table residuals overstated, cookie name inconsistency overview vs candidate-AB) and one out-of-scope upstream finding (Codex leaks ChatGPT OAuth JWT to arbitrary base_urls; file separately). candidate-AB.md itself is unchanged — it is the historical record of the reason loop's winning synthesis. errata.md is what the implementation will actually ship. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Codex's second review left two residual gaps: 1. The ChatGPT-OAuth-bypass question (errata §1.3, "Open question resolve before Commit 1.4") was unresolved. Spike completed: builtin providers cannot be partial-overridden — codex hard-rejects any model_providers.openai or model_providers.chatgpt entry. No header-shortcut keys exist (openai_http_headers etc. are all unknown). Only viable mechanism is a custom model_providers.ccxray + model_provider="ccxray", which forces API-key mode and breaks ChatGPT OAuth. Decision: ccxray's Codex launcher detects auth mode at spawn time. API-key Codex injects the header; ChatGPT-OAuth Codex retains the existing -c chatgpt_base_url=… launch path with no header injection. Upstream verifier additionally accepts loopback-unauth requests matching the ChatGPT-Codex header signature (chatgpt-account-id + JWT Authorization). Threat-model justification: residual risk reduces from credential theft to cost amplification by other-UID local attackers, which needs a separate Unix-socket binding (future hardening, out of scope of this migration). 2. overview.md L19 still said ccxray_session while candidate-AB.md uses ccxray_s. Single-line fix to standardize on ccxray_s. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Codex's third review pass flagged that overview.md "Winning stance" still claimed: 1. Upstream domain accepts ONLY X-Ccxray-Auth (errata §1.3 adds the ChatGPT-Codex loopback-unauth carve-out). 2. Hub IPC is gated by SO_PEERCRED UID match (errata §1.2 explains that's not exposed by Node's public API; filesystem 0600 is the real gate). Both materially false in the executive summary. Fix: add an authoritative-precedence note at the top, soften the "only X-Ccxray-Auth" wording to acknowledge the ChatGPT-Codex carve- out, and replace SO_PEERCRED with the filesystem-permission language. Also amend the threat-coverage table rows 1 and 6 to mention the same carve-out and its safety argument (browsers cannot forge the chatgpt-account-id + JWT-shaped Authorization signature without same-UID compromise). candidate-AB.md remains the historical record; overview.md is now the up-to-date executive summary that points at both. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Captures the `/autoresearch` reason loop output for the ccxray auth scheme under `reason/260525-0055-ccxray-auth-design/`. Round 1 ran two adversarial candidates and synthesized AB which three blind judges unanimously preferred.
Read `candidate-AB.md` to implement. `overview.md` is the one-page summary; `lineage.md` is the phase-by-phase chronicle.
Files
`HANDOFF.md` stays gitignored (matches the existing `handoff.md` rule — scratch session-bridging notes are not durable docs).
Why merge this
Subsequent auth-migration PRs will reference `reason/260525-0055-ccxray-auth-design/candidate-AB.md` in their commit messages. Keeping the design provenance in-tree makes those commits self-documenting.
Test plan
🤖 Generated with Claude Code