Security & Auth

API key management, role-based access control, encryption, and TLS.

Local development? Auth is disabled by default for frictionless local development. Enable it when you're ready for staging or production.

Auth Modes

Auth mode is determined by environment variables:

# .env — three modes based on which variables are set
# Disabled (default): no AUTH_ENABLED, no API_KEY
# Legacy:  API_KEY=your-shared-secret
# RBAC:    AUTH_ENABLED=true
Mode How It Activates Description Use Case
disabled Neither AUTH_ENABLED nor API_KEY set No authentication required Local development, testing
legacy API_KEY env var set (without AUTH_ENABLED) Single shared API key via X-API-Key header Simple deployments
managed (RBAC) AUTH_ENABLED=true Full key management with roles, scoping, rotation Production, multi-tenant
Rate limiting. In managed mode, 20 failed authentication attempts within one minute from the same IP triggers a 1-minute lockout.

Bootstrap Your First Key

On first run with AUTH_ENABLED=true, create your admin key via the bootstrap endpoint:

curl -X POST http://localhost:9300/auth/bootstrap \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "nocturnusai", "keyName": "admin"}'
{
  "apiKey": "nai_a1b2c3d4...",
  "prefix": "nai_a1b2",
  "id": "uuid-here",
  "role": "admin",
  "name": "admin"
}
⚠️ One-time only. The bootstrap endpoint works only once. Store the returned API key securely — it cannot be retrieved again. After your first admin key is created, use it to manage all subsequent keys.

API Key Management

Use the admin API to create, rotate, and revoke keys:

# Create a scoped read-only key
curl -X POST http://localhost:9300/auth/keys \
  -H "Authorization: Bearer $ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "reader",
    "databases": ["production"],
    "tenants": ["tenant_a"],
    "description": "Read-only for tenant A"
  }'

# Rotate a key
curl -X POST http://localhost:9300/auth/keys/$KEY_ID/rotate \
  -H "Authorization: Bearer $ADMIN_KEY"

# Revoke a key
curl -X DELETE http://localhost:9300/auth/keys/$KEY_ID \
  -H "Authorization: Bearer $ADMIN_KEY"

Roles

Keys are scoped to one of three roles:

Role Permissions
reader Query, infer, context window (read-only)
writer All reader permissions + assert, retract, extract
admin All permissions + key management, database creation

Keys can also be scoped to specific databases and tenants, providing fine-grained access control for multi-tenant deployments. See Multi-Tenancy.


Using API Keys

Pass your key in the Authorization header:

# All requests include the bearer token
curl -X POST http://localhost:9300/tell \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer nai_a1b2c3d4..." \
  -d '{"predicate": "plan", "args": ["enterprise"]}'

Encryption at Rest

Enable AES-256 encryption for WAL files and snapshots:

# .env
ENCRYPTION_KEY=your-256-bit-key-here

TLS

Enable TLS for encrypted transport:

# .env
TLS_ENABLED=true
TLS_KEYSTORE_PATH=/path/to/keystore.p12
TLS_KEYSTORE_PASSWORD=your-password
💡 MCP with Auth. When using MCP with auth enabled, add the bearer token to your MCP client config headers. See MCP Integration for details.

What's Next?

Multi-Tenancy →

Isolate data across organizations and environments

Operations →

Monitoring, logging, and persistence

API Reference →

Full endpoint documentation including auth headers