API Keys
The API Keys view lets Lumio operators inspect and manage any account's or user's API keys for support and incident response - listing keys, editing a key's label and scopes, rotating a leaked secret, and revoking a key. It covers both key kinds: personal user API keys (lm_usr_, stored in api_keys) that carry a single member's identity, and account service keys (lm_svc_, stored in account_service_keys) that belong to the account and outlive the member who minted them.
This is the operator surface, gated on the admin-scope account-apikeys:* family. It is distinct from the account-scope apikeys:* family a member uses to manage their own keys under Dashboard → API Keys - holding one never grants the other.
Where to find it
There is no standalone sidebar entry. The API-keys panel is reached in two places:
- Admin → Accounts → account detail - lists both kinds for that account: its members' personal
lm_usr_keys and the account'slm_svc_service keys. - Admin → Users → user detail - lists that user's personal
lm_usr_keys only (a service key has no owning user).
Quick start
- Open Admin → Accounts, drill into an account (or Admin → Users → a user), and scroll to the API Keys panel.
- Each key renders as a card showing its kind badge (
personal/service), label, non-secret prefix, scopes, and created / last-used dates. The secret itself is never shown. - Use Edit to change a key's label and scopes, Rotate to regenerate its secret, or Revoke to delete it.
- Rotate reveals the new full key exactly once - copy it and hand it back to the account. Everything else on the card is non-secret.
Detailed walkthrough
API Keys panel
One card per key. Each card shows:
- Kind - a
personal(lm_usr_) orservice(lm_svc_) badge. - Label - the human-friendly name, with the key's non-secret prefix in monospace.
- Scopes - the key's permission list, as chips.
- Owner / account - for a personal key, the owning user; the account it is bound to for both kinds.
- Created and Last used - dates; "Last used" is omitted when the key has never been used.
Card actions are each gated on their own permission: Edit (account-apikeys:edit), Rotate (account-apikeys:rotate), Revoke (account-apikeys:delete).
Editing a key (label + scopes)
Edit (gated on account-apikeys:edit) updates a key's label and scope list. Scope edits are validated against the assignable-scope registry for the key's kind (the same ZAF-1170 registry the dashboard picker uses): an unknown, deny-listed, or user-scoped-on-a-service-key scope is rejected before the write.
An operator can never push a key above its own principal:
- For a personal key, the scopes are additionally capped to the key owner's own grantable permissions - an operator cannot grant a member's key a permission the member does not hold.
- For a service key, the account is the principal, so the ceiling is the registry (minus the deny-list).
Rotating a key
Rotate (gated on account-apikeys:rotate) regenerates the key's secret in place: the key id, label, and scopes are unchanged, but the old secret stops working immediately and a new full key is returned exactly once. The plaintext is shown in a one-time reveal - copy it and hand it back to the account through a secure channel. It is never shown again, never returned by the list, and never logged.
Revoking a key
Revoke (gated on account-apikeys:delete) hard-deletes the key row. Any subsequent request using that key returns 401. The delete is idempotent - revoking an already-gone key resolves to the same not-found result rather than erroring.
Permissions
The panel is gated on the admin-scope account-apikeys:* family - admin-scope (global) permissions checked against the caller's admin role, seeded to system_admin, and enforced by AdminPermissionGuard (GraphQL) / require_admin_permission (REST). They are not the account-scope apikeys:* permissions a member uses on their own keys.
| Action | Permission |
|---|---|
| View any account's / user's keys | account-apikeys:read |
| Edit a key's label + scopes | account-apikeys:edit |
| Rotate a key's secret | account-apikeys:rotate |
| Revoke (delete) a key | account-apikeys:delete |
Dashboard entry requires admin:access. System admins implicitly hold every account-apikeys permission.
API
{kind} is personal (lm_usr_) or service (lm_svc_); the GraphQL enum ApiKeyKind uses PERSONAL / SERVICE.
| UI action | GraphQL | REST |
|---|---|---|
| List an account's keys (both kinds) | adminAccountApiKeys(accountId) | GET /v1/admin/accounts/\{account_id\}/api-keys |
| List a user's keys (personal only) | adminUserApiKeys(userId) | GET /v1/admin/users/\{user_id\}/api-keys |
| Edit a key (label + scopes) | adminUpdateApiKey(kind, id, label, permissions) | PATCH /v1/admin/api-keys/\{kind\}/\{id\} |
| Rotate a key's secret | adminRotateApiKey(kind, id) | POST /v1/admin/api-keys/\{kind\}/\{id\}/rotate |
| Revoke a key | adminDeleteApiKey(kind, id) | DELETE /v1/admin/api-keys/\{kind\}/\{id\} |
The two rotate results return { key, apiKey } (personal) / { key, serviceKey } (service) - the full key string plus the updated non-secret metadata. Every operator action emits a system-scope audit event (system:api_key_updated / system:api_key_rotated / system:api_key_revoked) with the operator as the actor; these rows never surface in the target account's or user's own audit log.
Tips & gotchas
- The rotated secret is shown once. The card only ever displays the non-secret prefix; a secret lost after the one-time reveal cannot be recovered - rotate again.
- Operator edits cannot escalate a key. A personal key stays capped to its owner's permissions and a service key to the account's registry ceiling, so an operator can never grant a scope the principal itself does not hold.
account-apikeys:*≠apikeys:*. The former is admin-scope (this page); the latter is account-scope (the member's own Dashboard → API Keys). Holding one does not unlock the other.- Revoke is idempotent and has no confirmation. One click deletes the key.
- Personal keys carry a member identity; service keys do not. That is why the user-detail panel lists only personal keys, and why service-key scopes are capped to the account rather than a user.
Related
- Accounts - the account-detail page that surfaces this panel
- Users - the user-detail page that surfaces personal keys
- System Keys - internal service-to-service keys (
lm_sys_), a separate operator surface - Audit Log - the
system:api_key_*operator events these actions emit - Permissions - the
account-apikeys:*family