API Keys
Truss uses API keys to authenticate client API requests. Every /v1/* endpoint requires a key passed via the apikey header (or x-api-key).
Key types
| Type | Prefix | RLS behavior | Use case |
|---|---|---|---|
anon | truss_pk_ | Respects RLS policies | Client-side apps, public-facing |
service_role | truss_sk_ | Bypasses RLS (runs as postgres role) | Server-side, admin scripts, CLI |
anon keys
Anon keys are safe to expose in client-side code. They respect PostgreSQL Row-Level Security (RLS) policies, so users can only access data their policies allow.
When a request uses an anon key with a JWT in the Authorization header, Truss:
- Decodes the JWT payload
- Sets
request.jwt.claimsandrequest.jwt.subas Postgres session config - Switches to the
authenticatedrole
service_role keys
Service role keys bypass RLS entirely and run queries as the postgres role. Never expose these in client-side code. Use them for:
- Server-side API calls
- Admin scripts and migrations
- Management API endpoints (which require service_role)
- CI/CD pipelines
Creating keys
Via dashboard
Navigate to Settings > API Keys and click “Create Key”. Choose the type and give it a label.
Via API
curl -X POST http://localhost:8787/api/keys \ -H "Content-Type: application/json" \ -d '{"keyType": "service_role", "label": "backend-server"}'Response:
{ "key": { "id": 1, "key_type": "service_role", "key_prefix": "truss_sk_abc", "label": "backend-server", "created_at": "2025-01-15T10:00:00Z" }, "secret": "truss_sk_abcdefghij..."}The secret is only returned once at creation time. Store it securely.
Using keys
Pass the key via the apikey header:
curl http://localhost:8787/v1/db/users \ -H "apikey: truss_pk_your_anon_key"const res = await fetch('http://localhost:8787/v1/db/users', { headers: { apikey: 'truss_pk_your_anon_key' }});The x-api-key header also works as an alias.
Revoking keys
curl -X DELETE http://localhost:8787/api/keys/{id}Revoked keys immediately stop working. The key row is kept for audit purposes but marked as revoked.
Rate limiting
API keys are rate-limited per minute. The limit is determined by your billing plan (default: 100 requests/minute). Rate limit headers are returned on every response:
X-RateLimit-Limit: 100X-RateLimit-Remaining: 95When the limit is exceeded, the API returns 429 Too Many Requests.
Security
- Keys are stored as SHA-256 hashes — the raw key is never stored
- Each key tracks
last_used_atfor auditing - Revoked keys are rejected immediately
- Rate limiting is per-key, in-memory, with a 60-second sliding window
Management API keys
The management API endpoints (/v1/status, /v1/projects, /v1/database/schema, etc.) require a service_role key. Attempting to access them with an anon key returns 403 Forbidden.