API Key Authentication

Secure your Agentfield control plane and agents with API key authentication

API Key Authentication

Secure communication between agents and the control plane

Overview

Agentfield supports optional API key authentication to secure communication between agents and the control plane. When enabled, all API requests must include a valid API key.

Authentication is disabled by default. Enable it by setting the AGENTFIELD_API_KEY environment variable on your control plane.

Quick Start

1. Enable Authentication on Control Plane

Set the AGENTFIELD_API_KEY environment variable when starting your control plane:

# Using environment variable
export AGENTFIELD_API_KEY=your-secret-api-key
af dev

Or in Docker:

docker run -d \
  -p 8080:8080 \
  -e AGENTFIELD_API_KEY=your-secret-api-key \
  agentfield/control-plane:latest

2. Configure Your Agents

Pass the same API key to your agents:

from agentfield import Agent

app = Agent(
    node_id="my-agent",
    agentfield_server="http://localhost:8080",
    api_key="your-secret-api-key"  # Same key as control plane
)

@app.reasoner
async def process(text: str) -> str:
    return await app.ai(user=text)
import { AgentFieldClient } from '@agentfield/sdk';

const client = new AgentFieldClient({
  nodeId: 'my-agent',
  agentFieldUrl: 'http://localhost:8080',
  apiKey: 'your-secret-api-key'  // Same key as control plane
});
import "github.com/Agent-Field/agentfield/sdk/go/client"

c, err := client.New(
    "http://localhost:8080",
    client.WithAPIKey("your-secret-api-key"),
)

How Authentication Works

When API key authentication is enabled:

  1. All API requests to the control plane must include a valid API key
  2. Requests without a valid key receive a 401 Unauthorized response
  3. Certain paths are automatically excluded (health checks, metrics, UI)

Supported Authentication Methods

The control plane accepts API keys via three methods (in order of precedence):

MethodHeader/ParameterExample
X-API-Key Header (preferred)X-API-KeyX-API-Key: your-secret-key
Bearer TokenAuthorizationAuthorization: Bearer your-secret-key
Query Parameterapi_key?api_key=your-secret-key

The X-API-Key header is the preferred method and is what the SDKs use by default. The query parameter is useful for SSE/WebSocket connections where headers cannot be set.

Excluded Paths

These endpoints never require authentication:

  • /api/v1/health - Health check endpoints
  • /metrics - Prometheus metrics
  • /ui/* - Web UI static files

Configuration Reference

Control Plane Configuration

Prop

Type

You can also configure authentication via YAML:

# agentfield.yaml
api:
  auth:
    api_key: "your-secret-api-key"
    skip_paths:
      - "/custom/public/endpoint"

SDK Configuration

from agentfield import Agent
from agentfield.client import AgentFieldClient

# Option 1: Pass to Agent directly
app = Agent(
    node_id="my-agent",
    api_key="your-secret-api-key"
)

# Option 2: Pass to client for standalone usage
client = AgentFieldClient(
    base_url="http://localhost:8080",
    api_key="your-secret-api-key"
)
import { AgentFieldClient } from '@agentfield/sdk';

const client = new AgentFieldClient({
  nodeId: 'my-agent',
  agentFieldUrl: 'http://localhost:8080',
  apiKey: 'your-secret-api-key'
});
import "github.com/Agent-Field/agentfield/sdk/go/client"

// Using WithAPIKey option
c, err := client.New(
    "http://localhost:8080",
    client.WithAPIKey("your-secret-api-key"),
)

// Or using Bearer token (also supported)
c, err := client.New(
    "http://localhost:8080",
    client.WithBearerToken("your-secret-api-key"),
)

Docker Compose Example

Here's a complete docker-compose setup with authentication enabled:

# docker-compose.yml
version: '3.9'

services:
  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=agentfield
      - POSTGRES_USER=agentfield
      - POSTGRES_PASSWORD=change-in-production
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - agentfield-network

  control-plane:
    image: agentfield/control-plane:latest
    ports:
      - "8080:8080"
    environment:
      - AGENTFIELD_POSTGRES_URL=postgres://agentfield:change-in-production@postgres:5432/agentfield
      - AGENTFIELD_HTTP_ADDR=0.0.0.0:8080
      - AGENTFIELD_API_KEY=${AGENTFIELD_API_KEY}  # Enable auth
    depends_on:
      - postgres
    networks:
      - agentfield-network

  my-agent:
    build: ./agent
    environment:
      - AGENTFIELD_SERVER=http://control-plane:8080
      - AGENT_CALLBACK_URL=http://my-agent:8000
      - AGENTFIELD_API_KEY=${AGENTFIELD_API_KEY}  # Same key
    depends_on:
      - control-plane
    networks:
      - agentfield-network

networks:
  agentfield-network:
    driver: bridge

volumes:
  pgdata:
# .env
AGENTFIELD_API_KEY=your-secret-api-key-here

Start with:

docker-compose up -d

Best Practices

Generate Strong API Keys

Use cryptographically secure random strings:

# Generate a secure API key
openssl rand -base64 32

Use Environment Variables

Never hardcode API keys in source code:

import os

app = Agent(
    node_id="my-agent",
    api_key=os.getenv("AGENTFIELD_API_KEY")
)

Rotate Keys Regularly

  1. Generate a new API key
  2. Update the control plane configuration
  3. Update all agents with the new key
  4. Restart services

Secure Key Storage

  • Use secrets management (Docker secrets, Kubernetes secrets, AWS Secrets Manager)
  • Never commit API keys to version control
  • Use different keys for different environments (dev, staging, production)

Troubleshooting

401 Unauthorized Errors

Symptom: Agent fails to connect with unauthorized error

Solutions:

  1. Verify the API key matches on both sides:
# Check control plane environment
docker exec control-plane env | grep AGENTFIELD_API_KEY

# Check agent environment
docker exec my-agent env | grep AGENTFIELD_API_KEY
  1. Ensure no extra whitespace in the key:
# Wrong - has trailing newline
export AGENTFIELD_API_KEY="my-key
"

# Correct
export AGENTFIELD_API_KEY="my-key"
  1. Verify the header is being sent:
# Test with curl
curl -H "X-API-Key: your-key" http://localhost:8080/api/v1/health

Authentication Not Working

Symptom: Requests succeed without API key

Solution: Ensure AGENTFIELD_API_KEY is set on the control plane. If empty or unset, authentication is disabled.

# Verify it's set
echo $AGENTFIELD_API_KEY