Skip to main content

API Keys

Generate and manage cryptographically secure API keys for authenticating SDK requests and external integrations.

Overview

API keys provide secure, auditable authentication for programmatic access to the ASCEND platform without requiring user credentials.

Source: ow-ai-backend/routes/api_key_routes.py (SEC-018)

Compliance: SOX, GDPR, HIPAA, PCI-DSS 8.3.1, SOC 2 CC6.1

Security Features

Cryptographic Security

FeatureImplementation
Key Generation256-bit entropy via secrets.token_urlsafe(32)
StorageSHA-256 hash with random salt
DisplayFull key shown ONCE at creation
MaskingOnly prefix visible after creation

Key Format

owkai_admin_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8
└────┬────┘└─┬─┘└──────────────┬──────────────────┘
prefix role random token (43 chars)

Key Prefix by Role

RolePrefix Example
adminowkai_admin_...
userowkai_user_...
managerowkai_manager_...

Generating API Keys

Generate New Key

curl -X POST https://pilot.owkai.app/api/keys/generate \
-H "Cookie: session=YOUR_SESSION_COOKIE" \
-H "Content-Type: application/json" \
-d '{
"name": "Production SDK Key",
"description": "Used by customer service agent",
"expires_in_days": 365,
"permissions": [
{"category": "agent_actions", "actions": ["create", "read"]},
{"category": "alerts", "actions": ["read"]}
],
"rate_limit": {
"max_requests": 5000,
"window_seconds": 3600
}
}'

Response:

{
"success": true,
"api_key": "owkai_admin_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8",
"key_id": 42,
"key_prefix": "owkai_admin_a1b2",
"name": "Production SDK Key",
"expires_at": "2026-01-15T10:00:00Z",
"created_at": "2025-01-15T10:00:00Z",
"warning": "⚠️ Save this key now - you will NOT see it again!"
}

Permission Shorthand (SEC-094)

You can use string shorthand for permissions:

{
"name": "Read-Only Key",
"permissions": ["agent:read", "action:read", "alert:read"]
}

Converts to:

{
"permissions": [
{"category": "agent", "actions": ["read"]},
{"category": "action", "actions": ["read"]},
{"category": "alert", "actions": ["read"]}
]
}

Listing API Keys

Get All Keys

curl "https://pilot.owkai.app/api/keys/list?include_revoked=false&page=1&page_size=20" \
-H "Cookie: session=YOUR_SESSION_COOKIE"

Response:

{
"success": true,
"keys": [
{
"id": 42,
"name": "Production SDK Key",
"description": "Used by customer service agent",
"key_prefix": "owkai_admin_a1b2",
"is_active": true,
"expires_at": "2026-01-15T10:00:00Z",
"last_used_at": "2025-01-15T14:30:00Z",
"usage_count": 1547,
"created_at": "2025-01-15T10:00:00Z"
}
],
"total_count": 3,
"page": 1,
"page_size": 20
}

Revoking API Keys

Revoke a Key

curl -X DELETE "https://pilot.owkai.app/api/keys/42/revoke?reason=Replaced%20with%20new%20key" \
-H "Cookie: session=YOUR_SESSION_COOKIE"

Response:

{
"success": true,
"message": "API key revoked successfully",
"key_id": 42,
"revoked_at": "2025-01-15T16:00:00Z"
}

Revocation Details

FieldDescription
revoked_atTimestamp of revocation
revoked_byUser ID who revoked
revoked_reasonAudit trail reason

Usage Statistics

Get Key Usage

curl "https://pilot.owkai.app/api/keys/42/usage?limit=100" \
-H "Cookie: session=YOUR_SESSION_COOKIE"

Response:

{
"success": true,
"key_id": 42,
"key_prefix": "owkai_admin_a1b2",
"statistics": {
"total_requests": 1547,
"recent_requests": 100,
"success_rate": 98.5,
"last_used_at": "2025-01-15T14:30:00Z"
},
"recent_activity": [
{
"timestamp": "2025-01-15T14:30:00Z",
"endpoint": "/api/v1/actions",
"method": "POST",
"status": 200,
"ip_address": "192.168.1.100",
"response_time_ms": 125
}
]
}

Rate Limiting

Default Limits

SettingDefaultMax
max_requests1000100,000
window_seconds3600 (1 hour)86,400 (24 hours)

Rate Limit Algorithm

Sliding window rate limiting:

  1. Request arrives
  2. Check current window count
  3. If under limit: increment and allow
  4. If over limit: return 429 with Retry-After header

Custom Rate Limits

Premium keys can have custom limits:

{
"rate_limit": {
"max_requests": 10000,
"window_seconds": 3600
}
}

Permissions

Permission Categories

CategoryActions
agent_actionscreate, read, update, delete
alertsread, acknowledge, escalate
smart_rulescreate, read, update, delete
analyticsread, export
auditread, export

Granular Resource Filters

{
"permissions": [
{
"category": "agent_actions",
"actions": ["create"],
"resource_filter": {
"agent_id": "specific-agent",
"risk_level": "low"
}
}
]
}

Database Schema

ApiKey Table

ColumnTypeDescription
idIntegerPrimary key
user_idIntegerOwner user
organization_idIntegerMulti-tenant isolation
key_hashString(64)SHA-256 hash
key_prefixString(20)Display prefix
saltString(32)Random salt
nameString(255)User-friendly name
is_activeBooleanActive status
expires_atDateTimeExpiration (null = never)
usage_countBigIntegerTotal requests
last_used_atDateTimeLast activity

API Reference

EndpointMethodDescription
/api/keys/generatePOSTGenerate new key
/api/keys/listGETList all keys
/api/keys/{id}/revokeDELETERevoke key
/api/keys/{id}/usageGETGet usage stats

Source: ow-ai-backend/routes/api_key_routes.py

Best Practices

  1. Rotate regularly: Replace keys every 90 days
  2. Use minimal permissions: Only grant required actions
  3. Set expiration: Avoid never-expiring keys
  4. Monitor usage: Review usage statistics weekly
  5. Revoke promptly: Revoke compromised keys immediately
  6. Document purpose: Use descriptive names

Troubleshooting

Key not working

Check:

  • Is key active? (is_active: true)
  • Is key expired? (check expires_at)
  • Is key revoked? (check revoked_at)
  • Rate limit exceeded? (check usage stats)

429 Too Many Requests

Cause: Rate limit exceeded.

Solution: Wait for Retry-After header duration or request higher limits.

Authentication required error

Solution: Use Authorization: Bearer YOUR_API_KEY header format.


Source: api_key_routes.py, models_api_keys.py