Secrets Vault
The secrets vault is a per-project, encrypted key-value store for your application’s secrets: third-party API keys, connection strings, OAuth client secrets, signing keys. Values are encrypted at rest and never returned by the API — you write them and reference them, but you can’t read them back in plaintext through the management surface.
Don’t confuse this with deployment secrets in
.env(database passwords, the control-plane signing secret). Those configure the stack; the vault holds your app’s secrets. See Concepts.
How it’s protected
Secret values are encrypted with pgcrypto (pgp_sym_encrypt), keyed on the
deployment’s CONTROL_PLANE_SECRET, and stored in the project database. Reads
return metadata only (name, description, timestamps) — never the value. This
makes the vault safe to browse in the console and safe to enumerate from CI without
leaking material.
Create or update a secret
Creating with an existing name upserts (updates the value):
anvilbase secrets set STRIPE_KEY "sk_live_…" --project <id>curl -X POST http://localhost:39001/api/v1/projects/<id>/secrets \ -H "Authorization: Bearer $ANVILBASE_TOKEN" -H "Content-Type: application/json" \ -d '{"name":"STRIPE_KEY","value":"sk_live_…","description":"prod payments key"}'name is 1–255 chars; value is non-empty. Returns 201 with the metadata
record (no value).
The CLI takes
nameandvalueas separate positional args, so values containing=(like base64) work without escaping.
Update an existing secret’s value
POST /secrets upserts (create-or-replace). To update only an existing secret —
so a typo’d name can’t silently create a new one — use PUT. It re-encrypts the
new value, optionally updates the description, and returns metadata only (never the
value). A missing secret is a 404. Admin-scoped.
curl -X PUT http://localhost:39001/api/v1/projects/<id>/secrets/STRIPE_KEY \ -H "Authorization: Bearer $ANVILBASE_TOKEN" -H "Content-Type: application/json" \ -d '{"value":"sk_live_NEW…","description":"rotated payments key"}'# → 200 with { id, name, description, created_at, updated_at } (no value)List secrets (metadata only)
anvilbase secrets list --project <id>
curl http://localhost:39001/api/v1/projects/<id>/secrets -H "Authorization: Bearer $ANVILBASE_TOKEN"You get names, descriptions, and timestamps — never values.
Delete a secret
Delete by name or UUID:
anvilbase secrets delete STRIPE_KEY --project <id>
curl -X DELETE http://localhost:39001/api/v1/projects/<id>/secrets/STRIPE_KEY \ -H "Authorization: Bearer $ANVILBASE_TOKEN"Using secrets
Secrets are meant to be consumed server-side — in edge functions or your own backend — never shipped to clients. The pattern is: keep the secret in the vault, resolve it at runtime in trusted code (with the project’s service-role context), and use it to call the third-party service. Because the value never appears in the management API responses, it can’t leak through the console, the CLI listing, or an audit export.
Rotation
Rotating an application secret you control is a re-set (or PUT) with the new
value — the same name/reference is kept, so consumers that read by name pick up the
new value:
anvilbase secrets set STRIPE_KEY "sk_live_NEW…" --project <id>When you want AnvilBase to generate a fresh random value for you (e.g. an
internal shared secret with no external source of truth), use the dedicated rotate
endpoint. It replaces the value with a new cryptographically-random one, re-encrypts
it at rest, and returns the new value exactly once (it is never readable again).
A missing secret is a 404. Admin-scoped.
curl -X POST http://localhost:39001/api/v1/projects/<id>/secrets/STRIPE_KEY/rotate \ -H "Authorization: Bearer $ANVILBASE_TOKEN"# → 200 with { id, name, …, value: "abs_…" } (value shown ONCE — save it)For platform credentials (a project’s JWT secret and API keys), use the dedicated rotation endpoints instead — see API Keys & Scopes → Rotation:
anvilbase secrets rotate jwt --project <id> # rotate the JWT signing secretanvilbase secrets rotate api-keys --project <id> # rotate anon + service_role keysIn the console
Project → Secrets lets you add, update, and delete secrets. Existing values are shown only as a masked placeholder after creation — there is no “reveal value” because the API never returns it.
Best practices
- One secret per credential, named clearly (
STRIPE_KEY,SENDGRID_KEY). - Reference secrets by name in code so rotation (re-
set) is transparent. - Never echo a secret into logs, error reporters, or client responses.
- Use a separate value per environment (dev/staging/prod project).
- Protect the deployment database — it’s the root of the vault’s encryption. See Encryption and the production checklist.
Next: Security → Overview.