Security model
High-level principles only: sessions, ownership, encryption, CSRF, headers and the boundaries between manager and project.
What it is
The security model rests on a small number of rules. Manager sessions are signed tokens in an httpOnly cookie. Every project request is checked for ownership before it is forwarded. Secrets are encrypted at rest under a master key. State-changing cookie requests carry a CSRF token. The process applies security headers, rate limits, central error redaction and process-level guards.
This page describes principles only. It is not an audit, a threat model, or a list of known issues. It explains the boundaries the product intends to maintain, so an operator can reason about them.
Why a single policy matters
A product with two entry points can easily acquire two policies. Here the path front door and the subdomain proxy call the same evaluator, so a request cannot be admitted by one route and denied by another. The same reasoning applies to the manager and the project: the manager's cookie is not a project credential, and a project key is not a manager credential.
Trust boundaries
Diagram: the browser holds a session cookie; the manager verifies it, checks ownership, and forwards to the project; the vault key stays inside the manager boundary, and project containers receive only the configuration they need.
The controls
Sessions. Manager sessions are JWTs signed with JWT_SECRET, carried in an httpOnly session_token cookie, with a token version that allows revocation. The signing key must be at least 32 characters, and the well-known Supabase example value is rejected by value.
CSRF. Cookie-authenticated state changes use a double-submit token, so a cross-site form cannot act with the user's session.
Ownership. A manager session reaches only projects it owns or administers. The denial response does not disclose whether a project exists.
Encryption. Project and edge-function secrets are encrypted with scrypt and AES under VAULT_MASTER_KEY. A previous key can be retained during rotation.
Process. CLI processes are spawned without a shell. Security headers, rate limiting and central error redaction apply to the HTTP surface. The manager's own token is stripped before a proxied request leaves the process.
What is encrypted where
Diagram: settings and vault rows live in the manager database; vault values are ciphertext; project data and backups sit outside the manager boundary.
Operating within the model
Keep the master key and the signing key out of source control. Use the setup script to generate them, store them where you keep the rest of the machine's secrets, and keep a copy of the master key with the database backup. Give manager accounts the smallest role that does the job. Treat the service-role key as a server credential and never ship it to a browser.
Understand the trust direction: a project is not trusted to administer the manager, and the manager does not expose a general database proxy. Each forwarded request is subject to the same ownership check regardless of the route it used.
The model also explains what the manager does not promise. It does not sandbox a project from the host, isolate projects from each other at the network level, or protect a database from a user who already has the postgres role. It concentrates on the boundary that matters for a local multi-project tool: who may reach a project through the shared entry point, and how stored secrets are kept at rest.
Failure and recovery
A missing or short signing key stops the process at boot rather than starting with a weak session scheme. A missing master key stops it in the same way. A lost master key makes vault rows unreadable; a retained previous key is the recovery path after a rotation. A revoked session is rejected on its next request. If you suspect a manager account is compromised, deactivate it and rotate the signing key, which invalidates existing sessions.