Security Model
Authentication & Authorization
JWT Flow
POST /api/auth/login/
→ access_token (60 min TTL)
→ refresh_token (7 day TTL, HttpOnly cookie)
POST /api/auth/token/refresh/
→ new access_token
→ refresh_token rotated (old blacklisted)
POST /api/auth/logout/
→ refresh_token blacklisted immediately
Role-Based Access Control
| Permission Class | Who |
|---|---|
| Platform operator only |
| Agency user for their own tenants |
| Tenant user for their own data |
| Any logged-in user |
Secrets Management
WhatsApp API Token Encryption
All tenant WhatsApp API tokens are encrypted at rest using Fernet (AES-256-CBC + HMAC-SHA256):
python
from cryptography.fernet import Fernet
f = Fernet(settings.FERNET_KEY)
encrypted = f.encrypt(raw_token.encode()) # stored in DB
decrypted = f.decrypt(encrypted).decode() # used at runtime
The must be set as an environment variable. It is never stored in code or committed to version control.
FERNET_KEYWebhook Security
Incoming Meta webhooks are verified using HMAC-SHA256:
python
# webhooks/security.py
import hmac, hashlib
def verify_signature(payload: bytes, signature: str, app_secret: str) -> bool:
expected = hmac.new(
app_secret.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
Requests with invalid signatures return immediately.
403 ForbiddenTransport Security
| Setting | Value |
|---|---|
| HSTS | 1 year + subdomains + preload (production) |
| HTTPS redirect | Via reverse proxy (Dokploy/nginx) |
| Session cookies | |
| CSRF cookies | |
| Clickjacking | |
| MIME sniffing | |
Rate Limiting
Meta API Rate Limiting
Custom token-bucket rate limiter in prevents exceeding Meta's per-number limits.
scheduler/services/rate_limiter.pyAPI Rate Limiting (Planned)
Per-tenant DRF throttling to prevent abuse:
python
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.UserRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'user': '1000/hour',
}
}
Security Checklist
- JWT tokens with short expiry (60 min)
- Refresh token rotation + blacklisting
- Fernet encryption for API secrets at rest
- HMAC-SHA256 webhook signature verification
- HSTS headers in production
- Tenant data isolation via middleware + permission classes
- CORS restricted to known origins in production
- Weekly automated dependency audits (GitHub Actions)
- CodeQL static analysis
- API rate limiting per tenant (planned)
- Sentry error tracking (planned)
- Secrets rotation procedure (planned)