Security
Authentication and project grants
Personal API keys are user-owned, organization-scoped credentials. Authority is the intersection of the active user membership, current project access, and the key's explicit product grant.
Authorization header
Authorization: Bearer twd_live_<public-id>.<secret>
Use HTTPS only. The full key is shown once at creation and is stored server-side only as a protected verification value.
Grant matrix
| Level | Board | Docs | Swagger |
|---|---|---|---|
none | No access to that product for the project. | ||
read | List work, runs, evidence and reports. | Read pages, revisions and links. | List/render permitted and common contracts. |
write | Create/update work and telemetry. | Create/revise/archive pages and bindings. | Create/manage permitted contracts, versions and environments. |
Create and manage keys
The recommended flow is the authenticated UI at /app/api-keys. Browser-session API calls are also available:
| GET | /api/me/api-keys | List your keys. Secret values are never returned again.Browser session |
| POST | /api/me/api-keys | Create a key and receive its secret exactly once.Browser session |
| GET | /api/me/api-keys/:id | Read key metadata and grants.Browser session |
| PATCH | /api/me/api-keys/:id | Rename, change expiry, or replace grants.Browser session |
| DELETE | /api/me/api-keys/:id | Revoke the key immediately.Browser session |
{
"name": "Terminal agent",
"expiresAt": "2026-12-01T00:00:00.000Z",
"grants": [
{ "projectId": "<project-id>", "board": "write", "docs": "write", "swagger": "read" }
]
}
Live authority
- Removing the user from the organization invalidates the key.
- Removing project access removes that project from the effective grants.
- Revocation or expiry returns
401 Unauthorized. - A valid key without the requested product/project level returns
403 Forbidden. - Swagger organization-common definitions are readable from an authorized project, but mutation still requires maintainer authority.
Rotation
Create a replacement key, update the consumer, verify GET /api/auth/context, then revoke the old key. Do not overwrite a key in place or share one credential between people.