Skip to main content
Calseta uses API key authentication. Both the REST API and MCP server accept the same keys.

API Key Format

All keys use the cai_ prefix followed by a 32-character URL-safe random string:
cai_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
Keys are stored as bcrypt hashes. The full key is shown once on creation and cannot be retrieved again.

Creating an API Key

python -m app.cli.create_api_key \
  --name "My Agent" \
  --scopes "alerts:read,alerts:write,enrichments:read,workflows:read,workflows:execute"

Via API

curl -X POST http://localhost:8000/v1/api-keys \
  -H "Authorization: Bearer cai_your_admin_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Agent Key",
    "scopes": ["alerts:read", "alerts:write", "enrichments:read", "workflows:read"],
    "key_type": "agent",
    "expires_at": "2026-01-01T00:00:00Z"
  }'
Save the returned API key immediately. It cannot be retrieved after creation.

Key Types

Every API key has a key_type — either "human" (default) or "agent":
TypePurposeWorkflow behavior
humanHuman operators, dashboards, scriptsWorkflows triggered as trigger_source: human. Bypasses agent_only approval gates.
agentAI agents, automated systemsWorkflows triggered as trigger_source: agent. Must provide reason and confidence when executing workflows. Subject to agent_only and always approval gates.
The trigger_source for workflow execution is derived server-side from the API key’s key_type — it is not a request body field. This ensures agents cannot bypass approval gates by claiming to be human.
Create separate keys for human operators and AI agents. This gives you audit clarity and lets approval gates distinguish between human and agent triggers automatically.

Using API Keys

Include the key in the Authorization header with the Bearer prefix:
curl -X GET http://localhost:8000/v1/alerts \
  -H "Authorization: Bearer cai_your_api_key"
The MCP server uses the same header format.

Scopes

Each API key has one or more scopes that control access:
ScopeGrants access to
alerts:readRead alerts, indicators, activity, context
alerts:writeUpdate alert status, post findings
enrichments:readRead and trigger enrichment, read field extractions
workflows:readRead workflows and workflow runs
workflows:executeExecute workflows
approvals:writeApprove or reject workflow approval requests
agents:readRead agent registrations
agents:writeRegister, update, delete agents
adminFull access (API keys, source integrations, enrichment providers, field extractions)
Follow the principle of least privilege. An agent that only reads alerts and posts findings needs alerts:read and alerts:write — not admin.

Key Prefix Display

For display and audit purposes, only the key prefix (first 8 characters, e.g., cai_a1b2) is stored. This identifies which key was used in logs without exposing the full secret.

Rate Limiting

All endpoints are rate-limited. Authenticated requests are limited by API key prefix. Unauthenticated requests are limited by IP address. When rate-limited, the response includes a Retry-After header.

Allowed Sources

API keys can optionally restrict which alert sources they can ingest from:
{
  "name": "Sentinel-only key",
  "scopes": ["alerts:write"],
  "allowed_sources": ["sentinel"]
}
When allowed_sources is null (default), the key can ingest from any source.