Files
cyclone/docs/superpowers/plans/2026-06-23-cyclone-auth-posture-alignment.md
T
Tyler d294b8bbed docs(plan): SP24 — auth posture alignment implementation plan
Plan covers the docs-only reconciliation between the auth work that landed
in main on 2026-06-23 and the three top-level docs (CLAUDE.md, docs/
REQUIREMENTS.md, docs/ARCHITECTURE.md). Includes a 6-line __main__.py edit
for the AUTH_DISABLED startup WARNING and one-paragraph addenda to the
cyclone-tests / cyclone-api-router / cyclone-spec skills.

Spec: docs/superpowers/specs/2026-06-23-cyclone-auth-posture-alignment-design.md
2026-06-23 14:49:26 -06:00

5.6 KiB

Auth Posture Alignment Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Reconcile CLAUDE.md, docs/REQUIREMENTS.md, and docs/ARCHITECTURE.md with the auth work that landed in main on 2026-06-23, and add a loud AUTH_DISABLED startup warning so a misconfigured production deploy fails loudly.

Architecture: Docs-only + one 6-line __main__.py edit + three skills addenda. No code paths change; the auth code already in main is the source of truth.

Tech Stack: Markdown, Python logging, existing cyclone.auth.deps.AUTH_DISABLED flag.

Spec: docs/superpowers/specs/2026-06-23-cyclone-auth-posture-alignment-design.md


File structure

Modified files:

  • CLAUDE.md (3 lines: 7, 97, 182)
  • docs/REQUIREMENTS.md (3 NFR / scope lines + §11 R-1 row + §6.1 SP24 row)
  • docs/ARCHITECTURE.md (2 lines: 16, 703 + 1 new "Auth" subsection + migrations table note)
  • backend/src/cyclone/__main__.py (startup warning when AUTH_DISABLED)
  • .superpowers/skills/cyclone-tests/SKILL.md (addendum)
  • .superpowers/skills/cyclone-api-router/SKILL.md (addendum)
  • .superpowers/skills/cyclone-spec/SKILL.md (addendum)

Task 0: Mark spec in implementation

  • Spec header Status: Draft, awaiting user sign-offStatus: Approved (in implementation on sp24-doc-posture-alignment).

Task 1: CLAUDE.md

  • Line 7 — replace "Local-only by design: binds to 127.0.0.1, no auth, no internet exposure." with the v1 posture: "Local-only by design: binds to 127.0.0.1, requires login (auth boundary is HTTP; file-system protection unchanged), no internet exposure."
  • Line 97 — update SP numbering to reflect "SP numbers are used through SP22; SP23 is the Ubuntu+Docker fork (awaiting user decision); this increment is SP24."
  • Line 182 — replace the "Local-only by design. The backend binds to 127.0.0.1, has no auth…" bullet with the new posture (login required; auth boundary is HTTP; SQLCipher + Keychain unchanged; don't add internet exposure).

Task 2: docs/REQUIREMENTS.md

  • Line 36 — replace "Local-only on purpose: binds 127.0.0.1, no auth, no internet exposure, single operator, single machine, one trading partner (Colorado Medicaid, currently)." with the v1 posture.
  • Line 39 — replace "Threat model: a process on the same host. No second party to authenticate; no second host to harden against." with the new threat model (process on same host + HTTP-layer login; SQLCipher + Keychain handle file-system threats; SP23 changes the model to LAN).
  • Line 154 (NFR-1) — replace "no auth, no API key" with "login required (bcrypt + HttpOnly session cookie; first admin bootstrapped from env vars CYCLONE_ADMIN_USERNAME + CYCLONE_ADMIN_PASSWORD); dev/test escape hatch via CYCLONE_AUTH_DISABLED=1."
  • §11 R-1 row — change "Open — addressed only if/when SP23 ships." to "Closed by SP24 — auth shipped via the merge of origin/main on 2026-06-23 (commits a25504b..39ae988); SP24 reconciled the docs to match. SP23 still covers the LAN-bind / Docker / RBAC product fork."
  • §6.1 — add an SP24 row pointing at this plan + the spec.

Task 3: docs/ARCHITECTURE.md

  • Line 16 — replace "has no authentication because the threat model is a stolen or imaged drive, not a remote attacker." with the new posture.
  • Line 703 — replace "Multi-user / multi-host — no auth, no LAN-bind, no Docker, no reverse proxy. The operator is one person, the host is one machine. (SP23 fork if this changes.)" with the new posture (login required; SP23 covers LAN-bind / Docker / RBAC fork).
  • Add a new "### Auth" subsection under §5.1 listing the cyclone.auth/ package contents and the matrix_gate dependency contract.
  • Migrations table — add a note that 0013 + 0014 are auth migrations and explain the renumbering on claims-unique-fix (0013/0014 → 0015/0016) to keep the auth migrations at the front.

Task 4: backend/src/cyclone/__main__.py

  • After bootstrap.run(), check cyclone.auth.deps.AUTH_DISABLED and emit a WARNING via logging.getLogger("cyclone") if True. The warning text must include the words "AUTH_DISABLED" and "dev only" so a misconfigured production deploy is greppable from logs.

Task 5: Skills addenda

  • cyclone-tests — add a paragraph noting the conftest's AUTH_DISABLED flip is mandatory context for any new test.
  • cyclone-api-router — add a paragraph noting every router needs Depends(matrix_gate) and the role matrix is in cyclone.auth.permissions.
  • cyclone-spec — add a paragraph noting the spec template's "threat model" example needs to be auth-aware (don't say "no second party to authenticate" any more; reference this SP as the reference pattern).

Task 6: Verification

  • grep -nE 'no auth|no authentication|no second party' CLAUDE.md docs/REQUIREMENTS.md docs/ARCHITECTURE.md returns no false-positive matches.
  • cd backend && .venv/bin/python -c "import cyclone.__main__" doesn't crash.
  • cd backend && .venv/bin/python -c "import cyclone; from cyclone.auth import deps; print(deps.AUTH_DISABLED)" prints False (default).
  • cd backend && CYCLONE_AUTH_DISABLED=1 .venv/bin/python -c "from cyclone.auth.bootstrap import run; run(); from cyclone.auth.deps import AUTH_DISABLED; print(AUTH_DISABLED)" prints True (env var flips the flag).