The Manager API runs on port 8443 with TLS enabled by default. All endpoints (except health check) require authentication via a Bearer token.
Bearer Token Authentication
The Manager API uses a shared static token for authentication. This token is configured via the MANAGER_AUTH_TOKEN environment variable and compared using SHA-256 timing-safe comparison to prevent timing attacks.
curl -X GET https://localhost:8443/api/agents \
-H "Authorization: Bearer YOUR_MANAGER_TOKEN" \
-H "Content-Type: application/json"
The Manager token grants full access to all Manager API endpoints. Treat it like a root password:
- Never commit it to version control
- Use a strong, random value (at least 32 characters)
- Rotate it periodically
- Set via environment variable, not in config files
Token Validation
Every request is validated with the following steps:
- Extract the
Authorization header
- Verify the
Bearer prefix
- SHA-256 hash the provided token
- Timing-safe compare against the stored hash
- Reject with
401 if comparison fails
The timing-safe comparison ensures that attackers cannot deduce the correct token by measuring response times. Every invalid token takes the same amount of time to reject, regardless of how many characters match.
Rate Limiting
| Scope | Limit | Window |
|---|
| Per IP | 60 requests | 1 minute |
When rate-limited, the API returns:
{
"ok": false,
"error": "Too many requests. Please try again later."
}
With headers:
| Header | Value |
|---|
X-RateLimit-Limit | 60 |
X-RateLimit-Remaining | 0 |
Retry-After | Seconds until the limit resets |
The Manager API sets the following security headers on every response:
| Header | Value | Purpose |
|---|
X-Content-Type-Options | nosniff | Prevents MIME-type sniffing |
X-Frame-Options | DENY | Prevents clickjacking via iframes |
X-XSS-Protection | 1; mode=block | Enables XSS filter in legacy browsers |
Strict-Transport-Security | max-age=31536000; includeSubDomains | Enforces HTTPS for 1 year |
Content-Security-Policy | default-src 'self' | Restricts resource loading |
X-Request-Id | Unique UUID | Request tracing identifier |
CORS Configuration
Cross-Origin Resource Sharing is configured via the CORS_ALLOWED_ORIGINS environment variable.
# Allow specific origins
CORS_ALLOWED_ORIGINS=https://dashboard.panguard.ai,https://admin.example.com
# Allow all origins (development only)
CORS_ALLOWED_ORIGINS=*
Never use CORS_ALLOWED_ORIGINS=* in production. Always specify the exact origins that should have access to the Manager API.
| Header | Value |
|---|
Access-Control-Allow-Origin | Configured origin(s) |
Access-Control-Allow-Methods | GET, POST, PUT, DELETE, OPTIONS |
Access-Control-Allow-Headers | Authorization, Content-Type, X-Request-Id |
Access-Control-Max-Age | 86400 (24 hours) |
Health Check
GET /health
Returns the service health status. No authentication required.
curl -X GET https://localhost:8443/health
{
"ok": true,
"data": {
"status": "healthy",
"version": "1.2.0",
"uptime": 86400,
"agents": {
"total": 12,
"online": 10
}
}
}
Use the /health endpoint for load balancer health checks and monitoring systems. It responds quickly and does not require authentication.