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.