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>
176 lines
5.8 KiB
Markdown
176 lines
5.8 KiB
Markdown
# 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.co`
|
|
- `https://www.cannaiq.co`
|
|
- `https://findadispo.com`
|
|
- `https://www.findadispo.com`
|
|
- `https://findagram.co`
|
|
- `https://www.findagram.co`
|
|
- `http://localhost:3010`
|
|
- `http://localhost:8080`
|
|
- `http://localhost:5173`
|
|
|
|
**Trusted Patterns:**
|
|
- `*.cannabrands.app`
|
|
- `*.cannaiq.co`
|
|
|
|
**Internal Header:**
|
|
- `X-Internal-Request` header matching `INTERNAL_REQUEST_SECRET` env 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_tokens` table)
|
|
|
|
## Authorization Levels
|
|
|
|
### Public (No Auth)
|
|
Routes accessible without authentication:
|
|
- `GET /health` - Health check
|
|
- `GET /api/health/*` - Comprehensive health endpoints
|
|
- `GET /outbound-ip` - Server's outbound IP
|
|
- `GET /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
|
|
|
|
```typescript
|
|
// 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:
|
|
|
|
1. **Internal IP**: Pods communicate via cluster IPs, which are trusted
|
|
2. **Internal Header**: Optional `X-Internal-Request` header for explicit trust
|
|
|
|
Endpoints used by workers:
|
|
- `POST /api/worker-registry/register` - Report for duty
|
|
- `POST /api/worker-registry/heartbeat` - Stay alive
|
|
- `POST /api/worker-registry/deregister` - Graceful shutdown
|
|
- `POST /api/worker-registry/task-completed` - Report task completion
|
|
|
|
## API Token Management
|
|
|
|
API tokens are managed via:
|
|
- `GET /api/api-tokens` - List tokens
|
|
- `POST /api/api-tokens` - Create token
|
|
- `DELETE /api/api-tokens/:id` - Revoke token
|
|
|
|
Token properties:
|
|
- `token`: The bearer token value
|
|
- `name`: Human-readable identifier
|
|
- `rate_limit`: Requests per minute
|
|
- `expires_at`: Optional expiration
|
|
- `active`: Enable/disable toggle
|
|
- `allowed_endpoints`: Optional endpoint restrictions
|
|
|
|
## Security Best Practices
|
|
|
|
1. **Never expose tokens in URLs** - Use Authorization header
|
|
2. **Use HTTPS in production** - All traffic encrypted
|
|
3. **Rotate API tokens periodically** - Set expiration dates
|
|
4. **Monitor rate limits** - Prevent abuse
|
|
5. **Audit access logs** - Track API usage via `api_usage_logs` table
|
|
|
|
## Related Files
|
|
|
|
- `src/auth/middleware.ts` - Auth middleware implementation
|
|
- `src/routes/api-tokens.ts` - Token management endpoints
|
|
- `src/middleware/apiTokenTracker.ts` - Usage tracking
|
|
- `src/middleware/trustedDomains.ts` - Domain trust markers
|