Skip to content

docs(reason): record auth scheme design loop output (round 1)#35

Merged
lis186 merged 4 commits into
mainfrom
docs/auth-design-260525
May 25, 2026
Merged

docs(reason): record auth scheme design loop output (round 1)#35
lis186 merged 4 commits into
mainfrom
docs/auth-design-260525

Conversation

@lis186
Copy link
Copy Markdown
Owner

@lis186 lis186 commented May 25, 2026

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

File Purpose
`overview.md` One-page winning stance + threat coverage table
`task.md` Original brief: 5 known problems, 6 threats, constraints, rubric
`candidate-A.md` Round 1 Generate-A (rejected)
`critique-A.md` Adversarial critique of A — 4 FATAL, 4 MAJOR, 2 MINOR
`candidate-B.md` Round 1 Generate-B (structural baseline for AB)
`candidate-AB.md` Winning synthesis
`judge-transcripts.md` Three blind judges' verdicts
`lineage.md` Convergence chronicle

`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

  • No code changes — pure docs
  • `HANDOFF.md` correctly excluded by existing gitignore rule

🤖 Generated with Claude Code

lis186 and others added 4 commits May 25, 2026 11:25
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>
@lis186 lis186 merged commit c52937f into main May 25, 2026
2 checks passed
@lis186 lis186 deleted the docs/auth-design-260525 branch May 25, 2026 05:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant