Skip to content

API keys

A personal access token (API key) is a long-lived bearer for programmatic access. It authenticates as you: every call made with it rides your normal workspace memberships, roles, and per-object ACLs.

knak_<keyId>_<secret>

Mint one in the Knobs app under Settings → Security, or via the API below. The plaintext token appears exactly once — at mint — and is stored only as a SHA-256 hash. Copy it immediately.

Send it as a bearer token on any product endpoint:

Terminal window
curl -H "Authorization: Bearer knak_..." https://api.knobs.io/v1/users/me/workspaces

Key management is session-only: these three routes reject API keys (401 api_key_not_allowed), so a leaked key can never create or destroy credentials. Call them from the Knobs app’s Settings page, or with a session JWT.

Endpoint Description
POST /v1/users/me/api-keys Mint a key {name, expiresAt?}201 {key, token} — the only place the plaintext token appears
GET /v1/users/me/api-keys List my keys (metadata only, never the secret)
DELETE /v1/users/me/api-keys/{kid} Revoke a key — takes effect immediately
Terminal window
curl -X POST https://api.knobs.io/v1/users/me/api-keys \
-H "Authorization: Bearer <session-jwt>" \
-H "Content-Type: application/json" \
-d '{"name": "deploy-bot", "expiresAt": "2026-12-31T00:00:00Z"}'
{
"key": {
"id": "k_ab12…",
"name": "deploy-bot",
"tokenHint": "knak_…7f3a",
"createdAt": "2026-07-16T17:20:00Z",
"expiresAt": "2026-12-31T00:00:00Z"
},
"token": "knak_k_ab12…_<secret>"
}
  • name: 1–48 characters (letters, digits, space, dash, underscore).
  • expiresAt (optional): must be in the future and at most 366 days out. Omit for a non-expiring key.
  • Limit: 25 keys per user429 too_many_keys past that; revoke an unused key first.
Terminal window
curl -H "Authorization: Bearer <session-jwt>" https://api.knobs.io/v1/users/me/api-keys
{
"keys": [
{
"id": "k_ab12…",
"name": "deploy-bot",
"tokenHint": "knak_…7f3a",
"createdAt": "2026-07-16T17:20:00Z",
"expiresAt": "2026-12-31T00:00:00Z",
"lastUsedAt": "2026-07-16T18:01:12Z"
}
]
}

tokenHint (knak_… + last 4 characters) is all you ever see of the secret again.

Terminal window
curl -X DELETE -H "Authorization: Bearer <session-jwt>" \
https://api.knobs.io/v1/users/me/api-keys/{kid}

Revocation is immediate — in-flight and subsequent requests with that key get 401.

  • Acts as the user. A key carries no scopes of its own; it inherits exactly your access (amr: ["apikey"] in the identity read). Anything you can do in the app, the key can do via REST.
  • Credential-management fence. A key can never touch credentials: API-key management, passkeys, MFA, and recovery contacts are session-only and answer 401 api_key_not_allowed to a key.
  • Hashed at rest, shown once. Only the SHA-256 of the token is stored; comparison is constant-time.
  • Expiry and revocation. Optional expiry up to 366 days; revocation via DELETE /v1/users/me/api-keys/{kid} is instant.
  • Brute-force braking. Failed knak_ authentications are rate-limited per IP; valid traffic never touches the limiter.
  • Independent of account sign-in state. Keys don’t consult Firebase on each request — disabling an account does not kill its keys. Revoke them explicitly when offboarding.

Treat a key like a password: keep it in a secret manager, scope one key per automation, set an expiry, and rotate by minting a replacement then revoking the old one.