Skip to main content

Overview

Mission Control supports three authentication methods:
  1. Session Cookie - For browser-based access after login
  2. API Key - For headless automation and CLI tools
  3. Google OAuth - For team SSO with admin approval workflow
All authenticated users are assigned one of three roles: viewer, operator, or admin.

Authentication Methods

Role-Based Access Control (RBAC)

Mission Control enforces three permission levels:
{
  "role": "viewer",
  "permissions": [
    "Read agents",
    "Read tasks",
    "Read token usage",
    "Read logs and activities",
    "Read system status"
  ],
  "restrictions": [
    "Cannot create or modify resources",
    "Cannot access admin settings",
    "Cannot manage users"
  ]
}

Role Hierarchy

Roles are hierarchical: viewer < operator < admin
const ROLE_LEVELS = {
  viewer: 0,
  operator: 1,
  admin: 2
};
Endpoints specify minimum required role. For example, POST /api/agents requires operator or higher.

Security Considerations

Follow these security best practices before deploying to production:

Password Requirements

  • Minimum 12 characters
  • Hashed with scrypt (CPU-intensive key derivation)
  • Constant-time comparison to prevent timing attacks
// From auth.ts:208
if (password.length < 12) {
  throw new Error('Password must be at least 12 characters');
}

Session Security

  • Duration: 7 days (604800 seconds)
  • Storage: SQLite user_sessions table
  • Token: 32-byte random hex (64 characters)
  • Cleanup: Expired sessions purged on each login
// From auth.ts:80
const SESSION_DURATION = 7 * 24 * 60 * 60; // 7 days
const token = randomBytes(32).toString('hex');

API Key Security

  • Constant-time comparison prevents timing attacks
  • Never log API keys in application logs
  • Rotate keys regularly
  • Use different keys for dev/staging/production
// From auth.ts:281
if (apiKey && safeCompare(apiKey, process.env.API_KEY || '')) {
  return { id: 0, username: 'api', role: 'admin' };
}

CSRF Protection

Mutating requests validate the Origin header:
// From proxy.ts:74-88
if (['POST', 'PUT', 'DELETE', 'PATCH'].includes(method)) {
  const origin = request.headers.get('origin');
  if (origin) {
    const originHost = new URL(origin).host;
    const requestHost = request.headers.get('host');
    if (originHost !== requestHost) {
      return NextResponse.json(
        { error: 'CSRF origin mismatch' },
        { status: 403 }
      );
    }
  }
}
API key authentication bypasses CSRF checks since keys are header-based.

User Management

Get Current User

curl http://localhost:3000/api/auth/me \
  -H "x-api-key: your-api-key"
Response:
{
  "user": {
    "id": 1,
    "username": "admin",
    "display_name": "Administrator",
    "role": "admin",
    "workspace_id": 1,
    "provider": "local",
    "email": null,
    "avatar_url": null,
    "created_at": 1709587200,
    "last_login_at": 1709673600
  }
}

List Users (Admin)

curl http://localhost:3000/api/auth/users \
  -H "x-api-key: your-api-key"
Response:
{
  "users": [
    {
      "id": 1,
      "username": "admin",
      "display_name": "Administrator",
      "role": "admin",
      "created_at": 1709587200
    },
    {
      "id": 2,
      "username": "operator1",
      "display_name": "Agent Operator",
      "role": "operator",
      "created_at": 1709673600
    }
  ]
}

Create User (Admin)

curl -X POST http://localhost:3000/api/auth/users \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "username": "analyst",
    "password": "secure-password-min-12-chars",
    "display_name": "Data Analyst",
    "role": "viewer",
    "email": "[email protected]"
  }'
Response: 201 Created
{
  "user": {
    "id": 3,
    "username": "analyst",
    "display_name": "Data Analyst",
    "role": "viewer",
    "email": "[email protected]",
    "created_at": 1709760000
  }
}

Update User (Admin)

curl -X PUT http://localhost:3000/api/auth/users \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "id": 3,
    "role": "operator",
    "display_name": "Senior Data Analyst"
  }'

Delete User (Admin)

curl -X DELETE http://localhost:3000/api/auth/users \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{"id": 3}'
Deleting a user destroys all their sessions immediately.

Error Responses

401 Unauthorized

Authentication required but not provided:
{
  "error": "Authentication required"
}
Causes:
  • No session cookie or API key provided
  • Session expired (7 days)
  • Invalid API key

403 Forbidden

Authenticated but insufficient permissions:
{
  "error": "Requires admin role or higher"
}
Causes:
  • Viewer trying to create resources
  • Operator trying to manage users
  • OAuth user not yet approved

409 Conflict

Resource already exists:
{
  "error": "Username already exists"
}

Initial Setup

On first run, Mission Control seeds an admin user from environment variables:
# .env
AUTH_USER=admin
AUTH_PASS=your-secure-password

# Or use base64 if password contains special characters
AUTH_PASS_B64=eW91ci1zZWN1cmUtcGFzc3dvcmQ=
If AUTH_PASS contains # or other shell metacharacters, use quotes or switch to AUTH_PASS_B64.

Generating a Secure Password

# Generate 24-character random password
openssl rand -base64 24

# For base64 encoding
echo -n "your-password" | base64

Best Practices

1

Use Strong Credentials

  • Passwords: Minimum 12 characters, mix of letters/numbers/symbols
  • API keys: At least 32 random characters
  • Rotate API keys quarterly
2

Deploy Behind Reverse Proxy

Use Caddy, nginx, or Traefik with automatic TLS:
server {
  listen 443 ssl http2;
  server_name mission-control.example.com;
  
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;
  
  location / {
    proxy_pass http://localhost:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
3

Configure Host Allowlist

Restrict network access in production:
MC_ALLOWED_HOSTS=mission-control.example.com,*.internal.corp
4

Enable Audit Logging

Track administrative actions:
curl http://localhost:3000/api/audit \
  -H "x-api-key: your-api-key"

Next Steps

Agents API

Manage agent lifecycle and status

Tasks API

Create and assign tasks to agents

Webhooks

Configure outbound event notifications

Token Tracking

Monitor LLM token usage and costs