Generate, manage, and revoke account-scoped API-key credentials. SHA-256 hashed storage — plaintext shown once at creation. Management does not automatically enable key-based authentication on application endpoints.
Key Generation
sk_-prefixed keys with 256-bit entropy via crypto.randomBytes. SHA-256 hashed. 12-char prefix for display.
Access Control
Configured organization manager roles, owner and admin by default. Membership verified on every operation. New-key scopes use an explicit allowlist.
Management Dashboard
/org-dashboard/api-keys — table view, create dialog, copy-once display, revoke with confirmation.
Expiration and Revocation
Creation validates ISO 8601 expiry; revocation deactivates the credential. Management does not authenticate other endpoints or update last_used_at.
| API Route | Method | Description |
|---|---|---|
/api/account/api-keys | GET | List keys (hash never exposed) |
/api/account/api-keys | POST | Create key (returns full key once) |
/api/account/api-keys | DELETE | Revoke key (sets is_active = false) |
Management security contract
All three API methods require an authenticated session and the configured session-finalization checks. Membership is checked for the canonical application actor, not the Auth provider subject: configured organization manager roles (owner and admin by default) can manage keys; other roles receive 403, and a missing membership receives 404. Both membership role columns participate in this check, and disabled or deletion-scheduled actors cannot manage keys. Creation and revocation retain CSRF protection, the strict rate limit, and the credentialChange reauthentication policy.
Every handler response uses Cache-Control: private, no-store. Lists are limited to 100 metadata records and never include hashes. Creation returns the plaintext key only after validated creation metadata and a successful database commit; store it securely when displayed. Missing application identity returns 503 APPLICATION_IDENTITY_UNAVAILABLE before management work. Malformed JSON returns 400. Database failures or malformed database responses return a generic 500 and synthetic diagnostics, not a false missing-account response or raw database error.
The dashboard uses the same shared Prisma path and configured manager check as the API, with its canonical application actor and selected workspace. A missing or denied membership renders not-found. Database failures or malformed results raise a generic logged page error instead of showing an empty list. The page receives only validated metadata, never hashes, plaintext keys or Auth-provider coordinates. Access is rechecked under database locks so concurrent membership changes cannot bypass authorization for the operation.
Revoking an unknown key, or a key outside the authorized Account, is an idempotent success that changes no row and discloses no existence information. An ambiguous creation failure must not be blindly retried: it may already have persisted a hash-only key. This management boundary does not by itself activate or certify any Database/Auth composition. Bearer-key authentication for other endpoints must be implemented separately.
Personal data export
Exports include metadata for Accounts the application actor can still manage, with no hashes or plaintext secrets. Historical nullable fields and custom scope values remain readable. The export accepts at most 1,000 Accounts and detects a result above 1,000 keys with an extra sentinel row; oversized exports require manual review instead of silent truncation. Request cancellation and the configured export deadline interrupt the database read. Final composition-specific local certification remains separate from these implementation checks.