API Keys
API keys provide programmatic access to Orphnet Logging. They authenticate the client SDK, CI/CD pipelines, and any system that needs to ingest or query logs without user interaction.
Key Types
| Type | Scope | Use Case |
|---|---|---|
| Workspace key | Access to all projects in a workspace | Multi-project ingestion, admin tools |
| Project key | Access to a single project | Production services, per-app isolation |
Workspace keys have userId: null (not tied to a user). Project keys are created under a specific project.
Key Prefixes
All API keys use the sk_ prefix:
Authorization: Bearer sk_a1b2c3d4e5f6...The auth middleware detects the sk_ prefix and routes to API key validation (vs eyJ for JWT tokens).
Scopes
Each key carries one or more scopes that control what operations it can perform:
| Scope | Grants | Implies |
|---|---|---|
logs:read | Query logs for the scoped project(s) | -- |
logs:write | Ingest log entries | logs:read |
admin | Full workspace management | All permissions |
Scope implications are enforced server-side: a key with logs:write can always read logs without explicitly including logs:read.
Creating API Keys
Create a key for a project (requires JWT auth with admin role in the workspace):
curl -X POST https://api.logvista.orph.dev/projects/{projectId}/keys \
-H "Authorization: Bearer eyJ..." \
-H "X-Workspace-Id: ws_..." \
-H "Content-Type: application/json" \
-d '{
"name": "production-ingest",
"scopes": ["logs:write"]
}'Response (201):
{
"success": true,
"data": {
"id": "tok_...",
"name": "production-ingest",
"key": "sk_a1b2c3d4...",
"scopes": ["logs:write", "logs:read"],
"project_id": "proj_..."
}
}One-time display
The key field is shown only once. It is stored as a SHA-256 hash on the server. If lost, revoke and create a new key.
Using API Keys
Pass the key in the Authorization header:
# Ingest a log
curl -X POST https://api.logvista.orph.dev/logger/{projectId}/log \
-H "Authorization: Bearer sk_your_key" \
-H "Content-Type: application/json" \
-d '{ "message": "Hello world", "level": "info" }'
# Query logs
curl -X POST https://api.logvista.orph.dev/logger/{projectId}/query \
-H "Authorization: Bearer sk_your_key" \
-H "Content-Type: application/json" \
-d '{ "filters": { "level": "error" } }'In the client SDK, pass the key during configuration:
import { createLoggingMiddleware } from '@orphnet/logging-api-client'
app.use('*', createLoggingMiddleware({
apiUrl: 'https://api.logvista.orph.dev',
apiKey: 'sk_your_key', // Sent as Authorization: Bearer sk_...
}))Revoking API Keys
Revoke a key immediately:
curl -X DELETE https://api.logvista.orph.dev/projects/{projectId}/keys/{keyId} \
-H "Authorization: Bearer eyJ..." \
-H "X-Workspace-Id: ws_..."Revocation is instant -- the KV cache is invalidated synchronously and the D1 record is marked inactive.
How Keys Are Validated
- The prefix (first 16 characters) is extracted from the bearer token
- KV is checked for a cached entry under
api_key:{prefix} - If found, the full SHA-256 hash is verified against the cached hash
- If not in KV, D1 is queried by hash; on a successful D1 hit, KV is repopulated
- If no active key matches,
401 UNAUTHORIZEDis returned
Security Properties
- Keys are high-entropy random 32-byte values (256 bits of entropy)
- Only the SHA-256 hash is persisted -- exposure of the DB or KV does not reveal keys
- Keys are scoped to a workspace and optionally a project
- A key for project A cannot query or write to project B
Next Steps
- Configuration -- Environment variables and deployment
- Middleware -- Use API keys with the client SDK
- Rate Limits -- Understand rate limiting for API key endpoints