Auth & Profile Plan (Cornice)
Auth & Profile Plan (Cornice)
Decision Summary
We will build authentication and profile management inside the Cornice FastAPI backend. This avoids external auth dependencies, keeps the stack self-contained, and makes it easy for others to run Cornice in their own environments.
Scope
- Auth: email/password plus OAuth (as needed).
- Profiles: per‑user risk settings and simulator defaults.
- Secrets: per‑user exchange API keys (Polymarket, Kalshi, future venues).
Why This Approach
- Self‑hosted: no external auth provider required.
- Small user base: fewer than 30 users, so the system can stay lean.
- Portability: easier for other operators to deploy without third‑party SaaS dependencies.
Security Model (Key Point)
Exchange keys must be encrypted at rest.
We will use envelope encryption:
-
Master key in env / KMS
Start with a single master key stored asCORNICE_KMS_KEY.
This can later be upgraded to a proper KMS (AWS/GCP/etc.) without changing the DB format. -
Encrypted blobs in Postgres
API keys and secrets are stored as encrypted blobs. The DB never stores plaintext keys. -
Per‑user keys never stored in plaintext
Keys are decrypted only in-memory when needed for execution. No plaintext persistence.
This is the central security guarantee of the auth system.
Data Model (High-Level)
users: identity (email, password hash, created_at).profiles: risk settings and simulator defaults.secrets: venue + encrypted API credentials + metadata.
Risk Settings (Examples)
min_net_edge_centsmax_leg_usddaily_cap_usdallow_live_trading
Simulator Implications
The simulator will:
- read per‑user risk settings
- verify user has keys on file
- check balances before “go live”
- allow users to transition from dry‑run to live using the same profile
Next Steps
- Implement auth endpoints in FastAPI.
- Add encryption utility using
CORNICE_KMS_KEY. - Create tables/migrations for users, profiles, and secrets.
- Integrate per‑user settings into trade intent generation.
Admin User Creation (CLI)
User creation is admin-only and handled via CLI:
python scripts/create_user.py <email> [password] [--no-reset]
This keeps registration closed while still allowing new members to be onboarded safely.
Default behavior: all new users are forced to update their password on first login. Use --no-reset to skip the forced reset.
Trust & Safety (Non‑Technical Summary)
AUTH_JWT_SECRET
This is the server’s signing key for login tokens. It proves a session token truly came from Cornice
and hasn’t been forged. It protects who is logged in, not the data itself.
CORNICE_KMS_KEY
This is the master encryption key used to lock exchange API credentials at rest. API keys are stored
in the database only as encrypted blobs. Without this key, the data is unreadable.
Why users can feel safe
- No plaintext keys in the database.
- Only Cornice can decrypt keys (and only in memory when needed).
- Auth tokens are signed, so impersonation is blocked unless the signing key is compromised.
- Self‑hosted deployment reduces exposure to third‑party breaches.
Safe Key Formats
- AUTH_JWT_SECRET: any long, random ASCII string (no spaces/newlines).
- CORNICE_KMS_KEY: a 32‑byte key. Use hex (64 chars) or base64 (44 chars).
Examples:
# 32-byte hex (64 chars)
4f8c2a3a9b5e4f1f6b17d6a1e3b2c9c4b6a6e9f0d1c3b4a5f6e7d8c9b0a1f2e3
# 32-byte base64 (44 chars)
q8dF6yE0N1e4zTgQb8vE3Ck7mBqXoJ2u5LhGmS7V9jA=