Authentication: API Keys
Scoped API keys for programmatic access to Sibyl.
Overview
API keys provide:
- Long-lived credentials for automation
- Scoped permissions (read, write, MCP)
- Organization-bound access
- Revocation support
Key Format: sk_live_<random> or sk_test_<random>
Key Scopes
| Scope | Description |
|---|---|
mcp | Access to /mcp MCP endpoints |
api:read | Read operations on /api/* (GET, HEAD, OPTIONS) |
api:write | All operations on /api/* (implies read) |
Creating API Keys
Via CLI
bash
sibyl auth api-key create --name "CI/CD Pipeline" --scopes mcp,api:readVia REST API
http
POST /api/auth/api-keysRequest:
json
{
"name": "CI/CD Pipeline",
"scopes": ["mcp", "api:read"],
"expires_at": "2025-12-31T23:59:59Z"
}Response:
json
{
"id": "key_uuid",
"name": "CI/CD Pipeline",
"key_prefix": "sk_live_abc123...",
"scopes": ["mcp", "api:read"],
"created_at": "2024-12-30T10:00:00Z",
"expires_at": "2025-12-31T23:59:59Z",
"key": "sk_live_abc123def456ghi789..."
}Important: The full key is only returned once on creation. Store it securely.
Using API Keys
Authorization Header
bash
curl -X GET "https://api.example.com/api/entities" \
-H "Authorization: Bearer sk_live_abc123def456ghi789..."MCP Endpoint
bash
curl -X POST "https://api.example.com/mcp" \
-H "Authorization: Bearer sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"method": "tools/call",
"params": {
"name": "search",
"arguments": {"query": "OAuth patterns"}
}
}'Key Storage
API keys are stored securely:
- Prefix stored in plaintext - For lookup (
sk_live_abc123...) - Full key hashed with PBKDF2 - For verification
- Algorithm: SHA-256
- Iterations: 210,000
- Salt: 16 random bytes
Key Management
List Keys
http
GET /api/auth/api-keysResponse:
json
{
"keys": [
{
"id": "key_uuid",
"name": "CI/CD Pipeline",
"key_prefix": "sk_live_abc123...",
"scopes": ["mcp", "api:read"],
"created_at": "2024-12-30T10:00:00Z",
"expires_at": "2025-12-31T23:59:59Z",
"last_used_at": "2024-12-30T15:30:00Z",
"revoked_at": null
}
]
}Revoke Key
http
DELETE /api/auth/api-keys/{key_id}Response: 204 No Content
Revoked keys immediately stop working.
Scope Enforcement
REST API Scopes
| HTTP Method | Required Scope |
|---|---|
| GET, HEAD, OPTIONS | api:read OR api:write |
| POST, PUT, PATCH, DELETE | api:write |
MCP Scope
The mcp scope is required for /mcp endpoint access:
json
{
"scopes": ["mcp"]
}Without mcp scope, MCP requests return 403.
Combined Scopes
For full access:
json
{
"scopes": ["mcp", "api:write"]
}Authentication Flow
- Extract token from Authorization header
- Check if token starts with
sk_ - Look up key by prefix in database
- Verify key hasn't been revoked
- Check key hasn't expired
- Verify full key hash matches
- Update last_used_at timestamp
- Return user and organization context
Organization Binding
API keys are bound to:
- User who created them
- Organization active at creation time
All operations use the bound organization context.
Expiration
Keys can have optional expiration:
json
{
"expires_at": "2025-12-31T23:59:59Z"
}Expired keys return 401:
json
{
"detail": "API key expired"
}Error Responses
| Status | Cause |
|---|---|
| 401 | Invalid, expired, or revoked key |
| 403 | Insufficient scope for operation |
Invalid Key:
json
{
"detail": "Invalid API key"
}Insufficient Scope:
json
{
"detail": "Insufficient API key scope"
}Best Practices
Scope Minimization
Grant only required scopes:
json
// Read-only automation
{"scopes": ["api:read"]}
// MCP agent only
{"scopes": ["mcp"]}
// Full access (use sparingly)
{"scopes": ["mcp", "api:write"]}Key Rotation
- Create new key with same scopes
- Update integrations to use new key
- Verify new key works
- Revoke old key
Naming Convention
Use descriptive names:
"CI/CD - GitHub Actions"
"Agent - Claude Code"
"Monitoring - Datadog"Expiration Policy
Set expiration for temporary access:
json
{
"name": "Contractor Access",
"expires_at": "2025-03-31T23:59:59Z"
}Environment Variables
For CI/CD and automation, use environment variables:
bash
# GitHub Actions
- name: Query Sibyl
env:
SIBYL_API_KEY: ${{ secrets.SIBYL_API_KEY }}
run: |
curl -H "Authorization: Bearer $SIBYL_API_KEY" \
https://api.example.com/api/entitiesRelated
- auth-jwt.md - JWT session authentication
- index.md - API overview
