Skip to main content
OpenFang supports optional API key authentication. When an API key is configured, all endpoints (except public health checks) require a valid Bearer token.

Setting an API Key

Add an API key to your configuration file:
~/.openfang/config.toml
api_key = "your-secret-api-key-here"
After setting the key, restart the daemon:
openfang restart
API keys are stored in plaintext in config.toml. Use strong, randomly-generated keys and protect the config file with restrictive permissions (chmod 600 ~/.openfang/config.toml).

Making Authenticated Requests

Include the API key as a Bearer token in the Authorization header:
curl http://127.0.0.1:4200/api/agents \
  -H "Authorization: Bearer your-secret-api-key-here"
In JavaScript:
fetch('http://127.0.0.1:4200/api/agents', {
  headers: {
    'Authorization': 'Bearer your-secret-api-key-here'
  }
})
In Python:
import requests

headers = {'Authorization': 'Bearer your-secret-api-key-here'}
response = requests.get('http://127.0.0.1:4200/api/agents', headers=headers)

No Authentication Mode

If api_key is empty or not set in the config, the API is publicly accessible without authentication:
~/.openfang/config.toml
# api_key = ""  # Commented out or empty = no auth required
Running without authentication is only safe on localhost. Never expose an unauthenticated API to the public internet — anyone could spawn agents, access memory, or shut down the kernel.

CORS Behavior

With Authentication

CORS is restricted to localhost origins:
  • http://127.0.0.1:4200
  • http://localhost:4200
  • http://127.0.0.1:8080
  • http://localhost:8080
  • http://localhost:3000

Without Authentication

CORS is restricted to the same localhost origins as above. This prevents malicious websites from making cross-origin requests to your local OpenFang instance.

Public Endpoints

The following endpoints do not require authentication even when an API key is set:
  • GET /api/health — Basic health check (redacted status)
  • GET / — WebChat UI
  • GET /logo.png — Logo image
  • GET /favicon.ico — Favicon
All other endpoints require the Bearer token when authentication is enabled.

Channel Identity Resolution

When messages arrive from channel adapters (Telegram, Discord, etc.), OpenFang maps the sender’s platform identity to an agent:
  1. User ID mapping — Each channel message includes a user_id (Telegram user ID, Discord user ID, etc.)
  2. Agent binding — You can configure which agent should respond to a specific user:
~/.openfang/config.toml
[channels.telegram]
bot_token_env = "TELEGRAM_BOT_TOKEN"
default_agent = "assistant"  # Fallback agent
allowed_users = ["123456", "789012"]  # Optional whitelist
  1. Dynamic binding — Use the bindings API to map users to agents:
curl -X POST http://127.0.0.1:4200/api/bindings \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "telegram",
    "user_id": "123456",
    "agent_name": "coder"
  }'

WebSocket Authentication

WebSocket connections inherit HTTP authentication. When connecting to:
ws://127.0.0.1:4200/api/agents/{id}/ws
Pass the API key as a query parameter:
const ws = new WebSocket(
  'ws://127.0.0.1:4200/api/agents/a1b2c3d4.../ws?key=your-api-key-here'
)
Or include it in the Sec-WebSocket-Protocol header:
const ws = new WebSocket(
  'ws://127.0.0.1:4200/api/agents/a1b2c3d4.../ws',
  ['bearer', 'your-api-key-here']
)
The current implementation accepts API keys via query parameters for WebSocket convenience, but this may change in future versions. Prefer header-based auth when possible.

RBAC (Role-Based Access Control)

OpenFang currently implements a single-role system: either you have the API key (full access) or you don’t (no access). Future versions will support:
  • Read-only keys — List agents, view sessions, but no mutations
  • Agent-scoped keys — Access specific agents only
  • Channel-specific keys — For webhook integrations
  • Temporary tokens — Time-limited access for external services

Security Best Practices

Generate API keys with at least 32 characters of entropy:
openssl rand -base64 32
Or use a password manager to generate a cryptographically secure key.
Change your API key periodically (every 90 days recommended):
  1. Update api_key in config.toml
  2. Restart the daemon: openfang restart
  3. Update all clients with the new key
On Unix systems:
chmod 600 ~/.openfang/config.toml
This prevents other users from reading your API key.
Instead of hardcoding keys in config.toml, reference environment variables:
api_key_env = "OPENFANG_API_KEY"
Then set the env var:
export OPENFANG_API_KEY="your-secret-key"
openfang start
If you must expose OpenFang publicly:
  1. Always set an API key
  2. Use a reverse proxy with TLS (nginx, Caddy)
  3. Add firewall rules to restrict access
  4. Consider adding HTTP basic auth at the proxy layer for defense-in-depth

Example: Authenticated Session

# Set API key
API_KEY="your-secret-api-key-here"

# List agents
curl http://127.0.0.1:4200/api/agents \
  -H "Authorization: Bearer $API_KEY"

# Spawn a new agent
curl -X POST http://127.0.0.1:4200/api/agents \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "manifest_toml": "name = \"my-agent\"\nversion = \"0.1.0\"\ndescription = \"Test agent\"\nmodule = \"builtin:chat\"\n\n[model]\nprovider = \"groq\"\nmodel = \"llama-3.3-70b-versatile\"\n"
  }'

# Send a message
curl -X POST http://127.0.0.1:4200/api/agents/<agent-id>/message \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Hello, agent!"}'

Next Steps

Agents API

Manage agent lifecycles

Workflows API

Orchestrate multi-agent tasks

Build docs developers (and LLMs) love