Skip to main content

API Keys

User-scoped bearer tokens for non-interactive callers (CI scripts, automation). They're an alternative way to authenticate the same user.

Where to find them​

Sidebar → Settings → API Keys card. Lists your own keys.

What an API key is​

  • A 64-character random hex string. No pk_ prefix.
  • Tied to your user, not your org. The request runs as you, inheriting all your org memberships and casbin permissions.
  • Hashed with SHA-256 server-side; the plaintext is shown once at creation and never again.

Create one​

New API key button:

  • Name — what the key is for
  • Expires in days — default 90; server caps at APIKeyMaxExpiryDays (silently clamps if you ask for more)

Submit. The next page shows the plaintext exactly once with a copy-to-clipboard button. Save it in your password manager / CI secret store / wherever — there's no recovery path.

Use it in HTTP​

curl -H "X-API-Key: <your-64-char-hex>" \
https://your-host/api/orgs/<org_id>/helm/list

Both auth headers (Authorization: Bearer <jwt> and X-API-Key: <hex>) are accepted; JWT takes precedence if both are sent.

Revoke​

Row actions → Revoke. Deletes the row; subsequent requests with that key get 401 invalid api key.

What an API key DOES NOT do​

  • Bypass casbin — same permissions as your user
  • Authenticate webhooks from external systems — those use HMAC signatures, not API keys
  • Bypass 2FA at the policy level — the key bypasses the 2FA prompt (no TOTP at use time) but a server policy of "all users must enrol in 2FA" still applies to your interactive logins
  • Bypass the license gate — LICENSE_MISSING / LICENSE_GRACE_READONLY apply to API key requests too
  • Carry an org or role of its own — you can't scope a key to "Org A read-only". To limit blast radius, create a dedicated user with only the org/role you want, and mint the key under that user.

Best practices​

  • One key per consumer. Don't share a key between two scripts; if one leaks you can't revoke without breaking the other.
  • Short expiry by default. 90 days is the default cap; many installs set it to 30 or even 7 for sensitive automation.
  • Name the key after the consumer. "github-actions-deploy" is searchable; "test1" isn't.
  • Rotate before expiry. Mint new + switch + revoke old. Schedule it on a cadence; don't wait for the key to expire.

Common errors​

  • invalid api key — wrong key, key revoked, or key expired
  • api key expired — key's expires_at is in the past; mint a new one
  • USER_DEACTIVATED — your user account is is_active=false; ask admin
  • permission denied — your user doesn't have the role permission for what the script is trying to do

See also​