fix(security) P0: gate all internal CMOAgent portals — sovereignstrike.com/plan leak
⚠ Incident — 2026-05-20
`sovereignstrike.com/plan/` was discovered publicly accessible, exposing the Studio Plan portal with strategically sensitive data:
- Launch target (2026-08)
- Runway (7 meses) + Headcount (2 humanos + 11 agents)
- Partners (Freepik)
- Internal phase/XP tracking system
- Financial decisions (`Cortar burn: cancelar SaaS sin uso, auditar gastos mensuales`)
- Granular team task lists (`Reunión con Aziz: cerrar carpeta de assets + demo hook Unity`)
Visible to anyone visiting the public apex domain — NOT gated by CF Access (that protects only `studio.sovereignstrike.com`).
Root cause
```python _PREVIEW_PREFIXES = ("/landing", "/press") ```
Only `/landing` and `/press` were behind the shared-password gate. All other portals — `/`, `/index.html`, `/setup`, `/art`, `/cto`, `/trends`, `/creatives`, `/onboarding`, `/brainstorm`, `/insights`, `/projects`, `/plan`, `/launch`, `/studio`, `/s` — served their HTML unauthenticated on every hostname the process answers on, including the public apex.
Fix
- Enumerate every internal portal prefix in `_PREVIEW_PREFIXES`.
- New `_GATED_EXACT_PATHS` for the apex root (`/`, `/index.html`) so the gate applies BEFORE the path is rewritten to `/ceo_portal/index.html`.
- Document the contract: any new portal route MUST be added or the leak reopens.
Test plan
-
`uv run pytest -q` → 437 passed in 5.78s (was 401; +36 new positive cases + dedicated regression test) -
`test_is_preview_path_true_for_gated_trees` expanded to all 15+ portals -
`test_is_preview_path_false_for_everything_else` expanded with API routes + prefix-bleed cases (`/presser`, `/landingx`, `/setupage`, `/studio_something`, `/sa`) -
New `test_apex_root_is_gated_after_leak_fix` as explicit regression guard naming the incident date -
Post-merge: deploy ASAP and verify `curl -sI https://sovereignstrike.com/plan/` returns 401
Follow-ups (separate work)
- Audit each portal for sensitive data inlined into HTML at render time (consider moving server-side via per-request API auth).
- DNS strategy: apex `sovereignstrike.com` should not route to CMOAgent at all — tracked in `docs/marketing/sovereign_strike/web_build_plan.md` for the new Astro public site.
Severity
P0 — strategic + financial + team data exposed. Merge and deploy ASAP.