Security
Security is designed in at every layer — authentication, authorization, data protection, and network isolation.
Authentication
| Mechanism |
Detail |
| JWT access + refresh |
Signed tokens, sub = user UUID, role claim |
| HttpOnly cookies |
ACCESS_TOKEN / REFRESH_TOKEN, XSS-safe |
| SameSite=Strict |
CSRF protection |
Secure flag |
Enforced in production (cookie_secure) |
| Password hashing |
bcrypt via verify_password |
| Token rotation |
Refresh endpoint issues new tokens; refresh tokens single-use |
Authorization (RBAC)
Roles are hierarchical:
viewer → manager → admin → superadmin
| Role |
Capabilities |
viewer |
Read dashboards, logs, KPIs |
manager |
Manage alerts, incidents, toggle sources |
admin |
+ users, tasks, clear-all |
superadmin |
+ role management |
- Routers declare required page permissions (
require_page("sources"))
- Destructive actions require explicit roles (
require_roles("admin", "superadmin"))
- Frontend guards routes with
usePermissions
Data Protection
| Concern |
Implementation |
| PII |
Stripped in the normalizer before storage |
| Uploaded files |
Raw content never echoed to the client (parse errors return generic message) |
| Secrets |
In .env only; .env.example has placeholders; .env gitignored |
| Sensitive errors |
Internal exception details logged, not returned |
Network Isolation
graph LR
subgraph PUBLIC["Public"]
LB[Load balancer / TLS]
end
subgraph PRIVATE["aiops_net (private bridge)"]
API[API :8000]
PG[Postgres :5432]
RED[Redis :6379]
KAF[Kafka :19092]
PIPE[Pipeline]
ML[ML :8001]
end
LB --> API
LB --> VEC[Vector :8686/8687]
- Internal services (Kafka, PG, Redis, ML) on private network with no external exposure
- Only API (8000), Vector (8686/8687), collectors (8080) are host-reachable
- Kafka broker listener split: internal
PLAINTEXT + host PLAINTEXT_HOST
Rate Limiting
slowapi + Redis-backed limits protect public endpoints:
| Endpoint |
Limit |
/api/auth/login |
login_limit |
/api/auth/refresh |
refresh_limit |
/api/sources create/upload |
source_create_limit |
/api/monitoring/clear-all |
clear_all_limit |
/ws/kpis |
ws_limiter (per IP) |
WebSocket Security
- Token validated via Bearer header, sub-protocol, cookie, or query (in that order)
- Invalid/missing token →
1008 Policy Violation
- Per-IP rate limiting
Destructive Operations
DELETE /api/monitoring/clear-all:
- Requires
admin or superadmin
- Rate limited
- Confirmed client-side by
ConfirmDialog
Container & Image Security
| Practice |
Detail |
| Read-only model mount |
log_priority_roberta mounted :ro |
| Resource limits |
Memory limits on all services |
| Base images |
Pinned tags (e.g. postgres:16-alpine, apache/kafka:3.7.0) |
.dockerignore |
Keeps secrets/build junk out of images |
Recommended Hardening
- Enable TLS at the load balancer for API + Vector
- Rotate JWT signing secrets and DB passwords regularly
- Use a secret manager instead of
.env in production
- Schedule
pg_dump backups and test restores
- Restrict Docker socket access to CI/admin only