Self-Hosted Threat Model
Chaos Cypher's all-in-one container is designed for single-user self-hosted deployment — typically a homelab, personal LAN, or a single VM behind a reverse proxy you control.
This page lists the threats Chaos Cypher defends against, the threats accepted by design, and how to harden further if your deployment shape diverges from the defaults.
What Chaos Cypher Defends Against
- Auth bypass via direct Cortex hits. Cortex refuses any
X-Auth-Userheader that doesn't come paired with the deployment-local edge-auth token. Direct port-8080 access (in dev compose, behind a misconfigured proxy, etc.) returns 401. - Session theft via stale cookies after logout. Logout bumps
session_epoch, invalidating every outstanding cookie for that user. - Prompt-injection-driven secret exfiltration. Model Context Protocol (MCP) file ingest is sandboxed to
/data/mcp_uploads; the LLM cannot read/data/.queue_password,/data/.session_secret, or/data/.edge_auth_token. Hidden files (dotfiles) are explicitly rejected even inside the sandbox. - Container blast radius. Cortex and Neuron run as
appuserwithno-new-privileges. The supervisor password is held only by supervisord (not propagated into the Cortex/Neuron environment). Static nginx config lives in root-owned/etc/nginx/conf.d; only the runtime token fragment lives in an appuser-writable dir. - Common archive attacks. Backup, package, and source-loader archive extraction enforces path containment (
is_relative_to), per-file + total decompressed size caps, member-count caps, and rejects symlinks and devices. Both the source-loader path and the.ccxpackage import path use the sameArchiveExtractorhelper. - Credential leaks via diagnostic exports. Log files are scrubbed for
Authorization,api_key=,Bearer, andtoken=patterns before zipping. Secret-bearing settings render as"configured"rather than partial reveals. dev_modeshipping to production by accident. Cortex refuses to start whensettings.dev_mode=Trueunless the operator has explicitly setCHAOSCYPHER_ALLOW_DEV_MODE=1to acknowledge.
What Chaos Cypher Explicitly Doesn't Defend Against
These are pragmatic deferrals for the single-user self-hosted posture. The enterprise build addresses each.
| Threat | Why it is accepted | If you need protection |
|---|---|---|
| First-arrival admin race. | Open-by-default bind matches the self-hosted convention (Vaultwarden, Jellyfin, Home Assistant, Gitea). Adding a setup-token UX or loopback gate would push the "everyone disables the security" failure mode. | Set CHAOSCYPHER_BIND=127.0.0.1 for first boot, complete /setup, then flip back. Or run the first boot on a network you fully control (laptop on home Wi-Fi, not a public VPS) before exposing it. |
| Online password brute-force beyond bcrypt + nginx rate-limit. | Account lockout would lock the owner out. Self-hosted single-user attacker doesn't get many guesses through 5r/s + bcrypt. | Set a 16+ char password; put the box behind a VPN or Tailscale; don't expose 0.0.0.0 without TLS. |
| DNS rebinding on operator-supplied URLs. | The operator triggers POST /api/v1/sources/url themselves; an attacker needs DNS control + the operator fetching their URL. | Don't fetch URLs from untrusted sources. |
| Tampered backup restores. | The operator only restores backups they made themselves. | Verify backup file integrity out-of-band (e.g., compare sha256sum to a copy you trust). |
| Disguised file uploads (e.g. SVG-with-script labeled as PDF). | The operator uploads their own files. | Don't upload files you didn't create. |
| Username enumeration via login timing. | The operator knows the username. | N/A. |
| Per-session cookie revocation list. | Logout invalidates all sessions; the single-user model treats "log out" as "log out everywhere." | Use a different account for short-lived shared access. |
Windows file ACLs on .session_secret. | Windows is a development target only. | Run on Linux for any non-dev deployment. |
| HTTP/2 / HSTS preload. | Both only matter once TLS is on; the operator opts into TLS. | Enable TLS in Settings, then run a Mozilla Observatory check and tune the headers. |
Hardening checklist for LAN / public exposure
If you set CHAOSCYPHER_BIND=0.0.0.0 (the default) and expose the box beyond your local machine:
- Set TLS first. Generate / install certs and switch to
nginx-https.confbefore opening the port. - Set a 16+ char password at
/setup(the minimum is 8 — go higher for any non-loopback exposure). - Set
CHAOSCYPHER_ALLOWED_HOSTSto your hostname/IP — blocks DNS-rebinding probes and Host-header spoofing. - Put the box behind a VPN, SSH tunnel, or Tailscale if possible. The box is designed to be safe on a small trusted network, not on the open internet.
- First-boot on a private network. Either set
CHAOSCYPHER_BIND=127.0.0.1for the initial/setup(then flip to0.0.0.0), or do the first boot on a trusted network where you'll be the first to reach the API. - Restrict
/api/v1/healthto your monitoring source with a dedicated nginxallow … ; deny all;block if you don't want LAN scanners to fingerprint your stack. (Note: even unauthenticated/healthonly returns{status}after the E1 hardening — the detailed payload requires auth.) - Rotate the API keys you've minted (
/api/v1/auth/keys) on a cadence that matches your threat model.
Diagnosing auth misconfiguration
If nginx's auth_request is misconfigured, X-Auth-User may not arrive at Cortex, producing silent 401 storms. Hit GET /api/v1/health/auth (no auth required) for diagnostics:
{
"x_auth_user_present": false,
"recent_failed_attempts": 142,
"last_failure_at": "2026-05-06T18:32:11.000000+00:00"
}
When recent_failed_attempts is non-zero on requests that should be authenticated, the nginx auth_request forward isn't reaching Cortex. Check your nginx logs and verify the auth_request directive points to the correct upstream and that the edge-auth token is set.
Note: x_auth_user_present reflects the current request only — hit the endpoint while also making an authenticated API call to compare the two states.
Reporting issues
Security issues: see SECURITY.md in the repo root.
See also
- API reference: Authentication — login, logout, API key management, and the nginx auth_request flow
- Security: Plugin trust model — what user-installed plugins can do and how to restrict them