KMS & secrets
The gateway stores upstream credentials (API keys and the like) so it can attach them to proxied calls. Those secrets are envelope-encrypted at rest: a per-credential data key encrypts the secret, and a master key — the KMS key — wraps the data keys. The database never holds plaintext credential material.
The master key: FARCASTER_KMS_KEY
Section titled “The master key: FARCASTER_KMS_KEY”The built-in KMS provider takes its master key from FARCASTER_KMS_KEY, a
hex-encoded 32-byte key (64 hex characters):
FARCASTER_KMS_KEY=$(openssl rand -hex 32)If FARCASTER_KMS_KEY is not set, the gateway generates a random
ephemeral key at startup. That key does not survive a restart — so any
credential encrypted under it becomes undecryptable once the process
restarts. The ephemeral mode is safe only for local development and in-process
tests. Never run production without setting FARCASTER_KMS_KEY.
The key must stay stable across restarts and upgrades: it’s the root of trust for every stored credential. Losing it means losing access to all credentials in the database. Treat it — and back it up — with the same care as the database itself.
Key rotation
Section titled “Key rotation”Rotating FARCASTER_KMS_KEY itself is not supported today. The built-in
provider reads a single master key from that one environment variable and
ignores any version token on decrypt — there’s no way to run with an old and a
new master key at once. If you change FARCASTER_KMS_KEY and restart, every
credential wrapped under the previous key becomes permanently undecryptable.
Treat the master key as fixed for the lifetime of the database, per the
warning above.
What is supported is tenant KEK rotation, via
credential.Service.RotateKEK: it generates a new per-tenant KEK, wraps it
under the currently-configured master key, and re-wraps that tenant’s
credential data keys under the new KEK — all without touching the encrypted
secrets themselves or requiring the old master key. This rotates the
per-tenant key material on your normal schedule; it does not rotate
FARCASTER_KMS_KEY.
Secret-handling hygiene
Section titled “Secret-handling hygiene”- Deliver
FARCASTER_KMS_KEY,FARCASTER_DATABASE_URL, and any provider credentials through your platform’s secret store or injected environment — never a committed file. The repo’s.env*is gitignored and read-denied by policy. - Don’t bake secrets into container images or CI logs.
- Rotate database credentials on your normal schedule. The master key itself
has no rotation path today (see key rotation above); rotate tenant KEKs via
RotateKEKinstead.