Lakuna · docs

Security

API key storage

Keys are never stored as plaintext. app/lib/api-keys.ts stores the per-request validation record under a one-way SHA-256 hash of the key - existence of a record at hash(key)is itself the proof, no key material is kept in the record. The per-user "show my key again" index (what the dashboard reads on every visit) is AES-256-GCM encrypted with a required API_KEY_ENCRYPTION_SECRET (32 bytes, hex-encoded - generate with openssl rand -hex 32).

A Redis-only compromise recovers no usable keys. Recovering them also requires the app server's environment secret - the database and the secret are two separate things to steal, and both are needed.

Rate limiting

The three agent-facing routes (/api/route, /api/strategies, /api/usage/report) are limited to 60 requests/minute per API key (app/lib/rate-limit.ts, backed by @upstash/ratelimit), returning 429 with a Retry-Afterheader past that. The dashboard's session-authenticated routes (/api/keys, /api/usage, /api/wall-detector) are not rate-limited. The limiter fails open on any Redis error, so it can't become a new outage cause on its own.