- FEATURES.md: Added Multi-Agent System section (registry, dashboard, assignment, mentions, permissions, error learning, doc freshness) - FEATURES.md: Added Dashboard Widgets section (activity clock, hourly activity, where time went, wall time, session metrics, widget toggles, lifecycle hooks, cost prediction, timezone-aware metrics) - FEATURES.md: Added v2.0 API endpoints to route table - FEATURES.md: Updated response envelope with timezone meta fields - CHANGELOG.md: Added #92 Dashboard Widget Toggles to v2.0.0 - README.md: Moved #92 from backlog to shipped in v2.0.0 - README.md: Cleaned stale 'NEW — v1.x' tags from pre-v2.0 features - CLAUDE.md: Updated to v2.0.0 — added mcp/ package, multi-agent lessons, registry/telemetry file locations - security.md: Added v2.0.0 changelog entry (permissions, MCP patch) - All docs verified: no broken links, no stale version refs, no secrets
9.1 KiB
Veritas Kanban Server - Security Guide
Overview
The Veritas Kanban server includes a flexible authentication and authorization system to protect API endpoints and WebSocket connections from unauthorized access.
Quick Start
Development (Localhost Bypass)
For local development, enable localhost bypass:
# .env
VERITAS_AUTH_ENABLED=true
VERITAS_AUTH_LOCALHOST_BYPASS=true
This allows unauthenticated requests from localhost/127.0.0.1 while still requiring auth for remote connections.
Production
For production, configure API keys:
# .env
VERITAS_AUTH_ENABLED=true
VERITAS_AUTH_LOCALHOST_BYPASS=false
VERITAS_ADMIN_KEY=your-secure-admin-key
VERITAS_API_KEYS=agent1:key1:agent,dashboard:key2:read-only
Authentication Methods
Clients can authenticate using any of these methods:
1. Authorization Header (Recommended)
curl -H "Authorization: Bearer your-api-key" \
http://localhost:3001/api/tasks
2. X-API-Key Header
curl -H "X-API-Key: your-api-key" \
http://localhost:3001/api/tasks
3. Query Parameter (WebSocket)
const ws = new WebSocket('ws://localhost:3001/ws?api_key=your-api-key');
Roles and Permissions
| Role | Read | Write | Admin Actions |
|---|---|---|---|
admin |
✅ | ✅ | ✅ |
agent |
✅ | ✅ | ❌ |
read-only |
✅ | ❌ | ❌ |
Role Details
- admin: Full access to all endpoints including sensitive operations
- agent: Can read/write tasks, run agents, manage worktrees. Intended for AI agents like OpenClaw
- read-only: Can only perform GET requests. Suitable for dashboards and monitoring
Configuration Reference
Environment Variables
| Variable | Default | Description |
|---|---|---|
VERITAS_AUTH_ENABLED |
true |
Enable/disable authentication |
VERITAS_AUTH_LOCALHOST_BYPASS |
false |
Allow unauthenticated localhost requests |
VERITAS_ADMIN_KEY |
(none) | Admin API key with full access |
VERITAS_API_KEYS |
(none) | Comma-separated API keys (format: name:key:role) |
API Key Format
name:key:role,name2:key2:role2
Example:
veritas:vk_abc123xyz:agent,dashboard:vk_def456uvw:read-only
Generating API Keys
Using OpenSSL
# Generate a random 32-character key
openssl rand -base64 32
Using the Built-in Function
import { generateApiKey } from './middleware/auth.js';
const key = generateApiKey('vk'); // e.g., vk_AbCdEf123...
API Endpoints
Auth Status (Unauthenticated)
Check the current authentication configuration:
curl http://localhost:3001/api/auth/status
Response:
{
"enabled": true,
"localhostBypass": false,
"configuredKeys": 2,
"hasAdminKey": true
}
Health Check (Unauthenticated)
curl http://localhost:3001/health
WebSocket Authentication
WebSocket connections are authenticated on connect:
// With API key
const ws = new WebSocket('ws://localhost:3001/ws?api_key=your-key');
ws.onclose = (event) => {
if (event.code === 4001) {
console.error('Authentication failed:', event.reason);
}
};
WebSocket Close Codes
| Code | Meaning |
|---|---|
1000 |
Normal close |
4001 |
Authentication required/failed |
Error Responses
401 Unauthorized
{
"error": "Authentication required",
"code": "AUTH_REQUIRED",
"hint": "Provide API key via Authorization header (Bearer <key>), X-API-Key header, or api_key query parameter"
}
403 Forbidden
{
"error": "Write access denied",
"code": "WRITE_FORBIDDEN",
"hint": "Your API key has read-only access"
}
Security Best Practices
-
Never commit API keys - Use environment variables or
.envfiles (add to.gitignore) -
Rotate keys regularly - Update API keys periodically, especially if compromised
-
Use HTTPS in production - API keys are transmitted in headers/URLs
-
Principle of least privilege - Use
read-onlyfor dashboards,agentfor automation -
Monitor access - The server logs connection attempts with role information
Migrating from No Auth
If you're upgrading from an earlier version without authentication:
-
Before upgrading: Document all clients that access the API
-
During upgrade:
- Start with
VERITAS_AUTH_LOCALHOST_BYPASS=truefor smooth transition - Generate API keys for each client
- Update clients to include authentication headers
- Start with
-
After testing: Disable localhost bypass for production
Troubleshooting
"Authentication required" for localhost
Check that VERITAS_AUTH_LOCALHOST_BYPASS=true is set, or provide an API key.
"Invalid API key"
- Verify the key matches exactly (no extra spaces)
- Check that the key is in the
VERITAS_API_KEYSorVERITAS_ADMIN_KEYvariable - Ensure the format is correct:
name:key:role
WebSocket immediately closes
- Check browser console for the close reason
- Ensure the API key is passed as a query parameter:
?api_key=...
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Request Flow │
├─────────────────────────────────────────────────────────────┤
│ │
│ Client Request │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ CORS/JSON │ (express middleware) │
│ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌───────────────────────┐ │
│ │ /health │──▶│ Bypass auth │ │
│ │ /api/auth/* │ │ (unauthenticated) │ │
│ └──────────────┘ └───────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ authenticate │ (middleware/auth.ts) │
│ │ │ │
│ │ - Check auth │ │
│ │ enabled │ │
│ │ - Localhost │ │
│ │ bypass? │ │
│ │ - Validate │ │
│ │ API key │ │
│ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Route Handler│ (req.auth available) │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Changelog
- v2.0.0 (2026-02-06): Multi-agent security
- Agent permission levels (Intern/Specialist/Lead) with enforcement
- Agent registry with heartbeat-based liveness tracking
- MCP SDK patched to ^1.26.0 (GHSA-345p-7cg4-v4c7)
- Rate limiting documentation (reverse proxy recommended for public deployments)
- v1.0.0 (2026-01-29): Initial authentication implementation
- API key authentication for HTTP and WebSocket
- Role-based authorization (admin, agent, read-only)
- Localhost bypass for development
- Configuration via environment variables