Skip to main content
Authentication is disabled by default so you can get started quickly in local development. Before sharing your server or deploying to production, enable API key authentication to protect the control plane from unauthorized access.

How It Works

Agent Control uses a two-tier API key model:
Key typeEnvironment variableWhat it can do
RegularAGENT_CONTROL_API_KEYSRegister agents, evaluate controls, read controls and agents
AdminAGENT_CONTROL_ADMIN_API_KEYSEverything above plus create/update/delete controls and manage agent-control associations
The /health endpoint is always public and requires no authentication.
Give your agent runtime a regular key. Reserve admin keys for setup scripts, CI pipelines, and the UI dashboard.

Step-by-Step Setup

1

Start the server with authentication enabled

Pass the authentication environment variables when starting the server:
curl -L https://raw.githubusercontent.com/agentcontrol/agent-control/refs/heads/main/docker-compose.yml \
  | AGENT_CONTROL_API_KEY_ENABLED=true \
    AGENT_CONTROL_API_KEYS="my-runtime-key" \
    AGENT_CONTROL_ADMIN_API_KEYS="my-admin-key" \
    AGENT_CONTROL_SESSION_SECRET="some-long-random-string" \
    CORS_ORIGINS="http://localhost:4000" \
    docker compose -f - up -d
Replace the placeholder key values above with strong, unique secrets before any shared or production deployment.
2

Pass the API key from the SDK

The SDK reads the AGENT_CONTROL_API_KEY environment variable by default, or you can pass it explicitly:
from agent_control import AgentControlClient

# Option 1: Environment variable (recommended)
# export AGENT_CONTROL_API_KEY="my-runtime-key"
async with AgentControlClient() as client:
    await client.health_check()

# Option 2: Explicit constructor argument
async with AgentControlClient(api_key="my-runtime-key") as client:
    await client.health_check()
3

Use an admin key for control management

Operations that modify controls or agent-control associations require an admin key. This keeps your control plane locked down even if a runtime key is compromised.
# setup.py — run with an admin key
async with AgentControlClient(api_key="my-admin-key") as client:
    await controls.create_control(client, name="block-ssn", data={...})
    await agents.add_agent_control(client, agent_name="my-agent", control_id="...")
4

Include the key in direct API calls

If calling the REST API directly, include the key in the X-API-Key header:
curl -H "X-API-Key: my-runtime-key" \
  http://localhost:8000/api/v1/agents

Key Rotation

Agent Control accepts multiple comma-separated keys per variable, making zero-downtime rotation straightforward:
  1. Add the new key alongside the old one: AGENT_CONTROL_API_KEYS="old-key,new-key"
  2. Redeploy the server
  3. Update all clients to use the new key
  4. Remove the old key: AGENT_CONTROL_API_KEYS="new-key"
  5. Redeploy again

Troubleshooting

401 Unauthorized — check these in order:
  1. Authentication is enabled (AGENT_CONTROL_API_KEY_ENABLED=true)
  2. Your key is present in the correct variable (AGENT_CONTROL_API_KEYS for regular, AGENT_CONTROL_ADMIN_API_KEYS for admin operations)
  3. The X-API-Key header (or SDK api_key argument) matches exactly — no trailing whitespace or quotes
See the Authentication reference for the full configuration table.