API Keys
An API key lets a customer call the panel's API from a script, a CI pipeline, or another program — without logging in through a browser each time. The key travels as a Authorization: Bearer … header and authenticates the request on behalf of the customer's organization.
Keys are managed entirely in the UI (Portal → API Keys). There is no terminal step.

What makes a customer key different
The panel has always had API keys for operators. This release adds org-scoped customer keys with three properties an operator key doesn't have:
- They belong to the customer's organization, not just the user who created them.
- They are stored in the secrets manager (OpenBao), in the customer's own compartment — so the panel can show the full key again later (an audited reveal), not just once at creation.
- They are gated by a capability. An operator turns the
api_keyscapability on or off per plan or per customer. When it's off, the customer can't mint keys and any key they already have stops authenticating immediately — no redeploy, no restart.
Think of it like the key to a rented unit: the building manager (the operator) can revoke access to the whole unit at any moment, and the moment they do, the tenant's key stops opening the door — even though the physical key still exists.
Creating and using a key (customer)
Open Portal → API Keys.
Click Create key, give it a name (e.g. "CI deploy"), and optionally pick an expiry (never / 30 / 90 / 365 days).
The full key is shown once, in the format
aap_XXXXXXXX_YYYYYYYYYYYYYYYY. Copy it now — for security it is not shown again automatically.
Send it as a bearer token:
curl -H "Authorization: Bearer aap_XXXXXXXX_YYYYYYYYYYYYYYYY" \ https://your-panel.example.com/api/v1/auth/me
If you lose a key created after org-scoped keys shipped, you can Reveal it again from the same page (this is recorded in the audit log). If you need to retire a key, Revoke it — anything using it stops working immediately. You can always revoke, even if the operator has since turned the capability off.
Why the page might be locked
If your provider hasn't included API keys in your plan, the page shows a locked card explaining why:
- "disabled by your administrator" — the operator turned the capability off globally or suspended the account.
- "not included in your plan" — API keys aren't part of your current plan; ask your provider to enable them.
Any keys you created earlier stay visible so you can still revoke them.
Enabling API keys (operator)
api_keys is a capability, resolved through the same cascade as the other capabilities (see Secrets Manager for the wider secrets story):
- Global switch — Settings → Capabilities. Off beats everything.
- Plan default — a plan may include
api_keysand set an optional max keys limit. - Per-customer override — enable, disable, or set a different max-keys limit for one customer.
The resolution order is: active subscription → global switch (off wins) → per-customer override → plan default → default off. A key minted by a customer authenticates only while the resolved answer is on; flip it off and the key returns 401 on the very next request.
The max keys limit caps how many active (not revoked, not expired) keys an organization may hold. Leave it blank for unlimited.
Upgrading — read this first
The upgrade migration adopts existing customer-role keys into their organization and gates them on the api_keys capability, which defaults to off. That is deliberate (secure-by-default), and it has one consequence you must plan for:
After upgrading, any existing customer API keys stop authenticating until you enable the
api_keyscapability (globally, on the plan, or per customer). Operator/admin keys are unaffected — they are never capability-gated.
Enable api_keys where you want those keys to keep working, in Settings → Capabilities and/or on the relevant plan.
Re-reveal is only for keys minted after the feature shipped
Keys created before org-scoped keys shipped were never stored in the vault — only a one-way hash of them is kept — so their plaintext genuinely cannot be recovered. Revealing such a key returns a notice telling you to rotate it instead: revoke it and create a new one. Every key you create from now on is re-revealable for as long as it exists.
What's recorded
Minting, revealing, and revoking a key each write an audit-log entry (api_key.create / api_key.reveal / api_key.revoke) with the key's name and prefix — never the key material itself. The plaintext lives only in the vault and in that one show-once response.