Documentation
API key lifecycle
How to mint, store, rotate, and revoke Prometheus API keys — with the one-time copy semantics called out up front.
API keys are the only credential that lets the MCP server and CI jobs talk to the indexer worker. They are scoped to a single tenant, hashed at rest, and shown in cleartext exactly once. This page walks the full lifecycle.
Anatomy of a key
prom_live_8f3a1c2b9d4e5f6071829a3b4c5d6e7f0a1b2c3d4e5f6071
└──┬──┘└────────────────── 32-byte secret ──────────────────┘
│
└── environment prefix: prom_live_ (prod) or prom_test_ (staging)
- 32 bytes of cryptographic randomness, base16-encoded.
- Hashed with Argon2id before lookup. The cleartext never hits the database after issuance.
- Per-tenant. A key never carries authority over a different tenant, no matter what the calling code sets.
1. Create
app.prom.codes/api-keys → Create key
Owner or admin role required. Pick a human-readable label
(e.g. ci/github-actions, claude-desktop/laptop) so the audit log
and revocation list stay legible. Submit, and the new key appears in
a one-time reveal panel.
The corresponding api_key.create row lands in
/app/audit immediately, with the
actor, the new key's id, and the label you chose.
2. Use
Pass the key as a bearer token to every worker call and as the
PROMETHEUS_API_KEY environment variable to every MCP server
process:
curl -H "Authorization: Bearer prom_live_..." https://api.prom.codes/healthz
{
"mcpServers": {
"prometheus": {
"command": "npx",
"args": ["-y", "@prometheus/context-mcp@latest"],
"env": {
"PROMETHEUS_API_KEY": "prom_live_..."
}
}
}
}
The worker reads the key on every request, hashes it, and looks up the tenant. There is no session — every call is independently authenticated.
3. Rotate
Rotation is just "create new, switch over, revoke old":
- Create a new key with a label that includes today's date.
- Roll every consumer (CI, MCP hosts, ad-hoc scripts) to the new key. Keys are stateless, so the cutover can be staggered.
- Verify the new key is taking traffic by watching
api.prom.codeslogs (visible in/app/auditunderapi_key.useonce Phase 3 ships per-key usage rows). - Revoke the old key. From this moment on, any leftover consumer
gets a
401.
There is no automatic rotation schedule today. We recommend rotating on a quarterly cadence and immediately on personnel change or suspected compromise.
4. Revoke
app.prom.codes/api-keys → Revoke
Revocation is immediate. The worker re-checks the key on every
request, so the next call after the revoke returns 401 UNAUTHORIZED.
A revoked key cannot be reactivated — mint a new one if you
need to undo the action.
The audit log records api_key.revoke with the actor and the key id.
The key's cleartext is never logged.
What to do on a leak
- Revoke immediately — do not wait for the rotation step.
- Mint a fresh key with a clearly different label so post-mortem diffing is easy.
- Walk the audit log for the leaked key's id — any
api_key.userows (Phase 3) tell you whether the key was exercised between leak and revocation. If you suspect indexed data is now in the wrong hands, mail security@prom.codes so we can help you assess blast radius. - Update your secret store so the leak does not recur. We
recommend
direnv,1Password, or your CI's encrypted variables over plain.envfiles.
Naming conventions that pay off
| Pattern | Example | Why |
|---|---|---|
| Purpose / host | ci/github-actions | Lets you revoke a single CI without breaking laptops. |
| Operator + date | hans/2026-05 | Trivial to age out at rotation. |
| Workspace hint | monorepo/indexer | Useful once per-workspace keys ship in Phase 4. |