Security audit identified 8 endpoint groups that were publicly accessible
without authentication. Added authMiddleware and requireRole where appropriate.
Protected endpoints:
- /api/payloads/* - authMiddleware (trusted origins or API token)
- /api/job-queue/* - authMiddleware + requireRole('admin')
- /api/workers/* - authMiddleware
- /api/worker-registry/* - authMiddleware (pods access via trusted IPs)
- /api/k8s/* - authMiddleware + requireRole('admin')
- /api/pipeline/* - authMiddleware + requireRole('admin')
- /api/tasks/* - authMiddleware + requireRole('admin')
- /api/admin/orchestrator/* - authMiddleware + requireRole('admin')
Also:
- Added API_SECURITY.md documentation
- Filter AI settings from /settings page (managed in /ai-settings)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
5.8 KiB
5.8 KiB
API Security Documentation
This document describes the authentication and authorization configuration for all CannaiQ API endpoints.
Authentication Methods
1. Trusted Origins (No Token Required)
Requests from trusted sources are automatically authenticated with internal role:
Trusted IPs:
127.0.0.1(localhost IPv4)::1(localhost IPv6)::ffff:127.0.0.1(IPv4-mapped IPv6)
Trusted Domains:
https://cannaiq.cohttps://www.cannaiq.cohttps://findadispo.comhttps://www.findadispo.comhttps://findagram.cohttps://www.findagram.cohttp://localhost:3010http://localhost:8080http://localhost:5173
Trusted Patterns:
*.cannabrands.app*.cannaiq.co
Internal Header:
X-Internal-Requestheader matchingINTERNAL_REQUEST_SECRETenv var
2. Bearer Token Authentication
External requests must include a valid token:
Authorization: Bearer <token>
Token Types:
- JWT Token: User session tokens (7-day expiry)
- API Token: Long-lived tokens for integrations (stored in
api_tokenstable)
Authorization Levels
Public (No Auth)
Routes accessible without authentication:
GET /health- Health checkGET /api/health/*- Comprehensive health endpointsGET /outbound-ip- Server's outbound IPGET /api/v1/deals- Public deals endpoint
Authenticated (Trusted Origin or Token)
Routes requiring authentication but no specific role:
| Route | Description |
|---|---|
/api/payloads/* |
Raw crawl payload access |
/api/workers/* |
Worker monitoring |
/api/worker-registry/* |
Worker registration and heartbeats |
/api/stores/* |
Store CRUD |
/api/products/* |
Product listing |
/api/dispensaries/* |
Dispensary data |
Admin Only (Requires admin or superadmin role)
Routes restricted to administrators:
| Route | Description |
|---|---|
/api/job-queue/* |
Job queue management |
/api/k8s/* |
Kubernetes control (scaling) |
/api/pipeline/* |
Pipeline stage transitions |
/api/tasks/* |
Task queue management |
/api/admin/orchestrator/* |
Orchestrator dashboard |
/api/admin/trusted-origins/* |
Manage trusted origins |
/api/admin/debug/* |
Debug endpoints |
Note: The internal role (localhost/trusted origins) bypasses role checks, granting automatic admin access for local development and internal services.
Endpoint Security Matrix
| Endpoint Group | Auth Required | Role Required | Notes |
|---|---|---|---|
/api/payloads/* |
Yes | None | Query API for raw crawl data |
/api/job-queue/* |
Yes | admin | Legacy job queue (deprecated) |
/api/workers/* |
Yes | None | Worker status monitoring |
/api/worker-registry/* |
Yes | None | Workers register via trusted IPs |
/api/k8s/* |
Yes | admin | K8s scaling controls |
/api/pipeline/* |
Yes | admin | Store pipeline transitions |
/api/tasks/* |
Yes | admin | Task queue CRUD |
/api/admin/orchestrator/* |
Yes | admin | Orchestrator metrics/alerts |
/api/admin/trusted-origins/* |
Yes | admin | Auth bypass management |
/api/v1/* |
Varies | Varies | Public API (per-endpoint) |
/api/consumer/* |
Varies | Varies | Consumer features |
Implementation Details
Middleware Stack
// Authentication middleware - validates token or trusted origin
import { authMiddleware } from '../auth/middleware';
// Role requirement middleware - checks user role
import { requireRole } from '../auth/middleware';
// Usage in route files:
router.use(authMiddleware); // All routes need auth
router.use(requireRole('admin', 'superadmin')); // Admin-only routes
Auth Middleware Flow
Request → Check Bearer Token
├─ Valid JWT → Set user from token → Continue
├─ Valid API Token → Set user as api_token role → Continue
└─ No Token → Check Trusted Origin
├─ Trusted → Set user as internal role → Continue
└─ Not Trusted → 401 Unauthorized
Role Check Flow
Request → authMiddleware → requireRole('admin')
├─ role === 'internal' → Continue (bypass)
├─ role in ['admin', 'superadmin'] → Continue
└─ else → 403 Forbidden
Worker Pod Authentication
Worker pods (in Kubernetes) authenticate via:
- Internal IP: Pods communicate via cluster IPs, which are trusted
- Internal Header: Optional
X-Internal-Requestheader for explicit trust
Endpoints used by workers:
POST /api/worker-registry/register- Report for dutyPOST /api/worker-registry/heartbeat- Stay alivePOST /api/worker-registry/deregister- Graceful shutdownPOST /api/worker-registry/task-completed- Report task completion
API Token Management
API tokens are managed via:
GET /api/api-tokens- List tokensPOST /api/api-tokens- Create tokenDELETE /api/api-tokens/:id- Revoke token
Token properties:
token: The bearer token valuename: Human-readable identifierrate_limit: Requests per minuteexpires_at: Optional expirationactive: Enable/disable toggleallowed_endpoints: Optional endpoint restrictions
Security Best Practices
- Never expose tokens in URLs - Use Authorization header
- Use HTTPS in production - All traffic encrypted
- Rotate API tokens periodically - Set expiration dates
- Monitor rate limits - Prevent abuse
- Audit access logs - Track API usage via
api_usage_logstable
Related Files
src/auth/middleware.ts- Auth middleware implementationsrc/routes/api-tokens.ts- Token management endpointssrc/middleware/apiTokenTracker.ts- Usage trackingsrc/middleware/trustedDomains.ts- Domain trust markers