Security
Owner: Engineering Last reviewed: 2026-Q2
This document captures our current security posture and concrete guardrails implemented in this repo, plus recommended hardening steps. It focuses on authN/Z, user data isolation, file handling, data protection, infrastructure, and developer practices.
Overview
- Threat model: user-scoped SaaS where users manage boards, action points, shares, and documents. High-value assets: documents (and extracted text/embeddings), user identities, workspace metadata, board permissions, and action-point shares.
- Primary risks: cross-tenant data access, insecure file uploads, SSRF via URL-based analysis, credential leakage, dependency and container vulnerabilities.
Authentication
- Provider: Clerk. Frontend obtains tokens via Clerk React SDK.
- Verification: Backend verifies JWT via Clerk JWKS with caching (
backend/py/core/authentication.py).- Validates signature (RS256),
exp,nbf, andiss. - Authorized party: validate
azpagainstCLERK_AUTHORIZED_PARTIESwhen configured. - Extracts
ClerkUsercontext:clerk_user_id, email/name fields, plan claim, and subscription status.
- Validates signature (RS256),
Authorization
- Dual model (ADR-001):
get_current_user()→ClerkUserfor role/permissions checks.get_current_db_user()→ localUser(JIT provisioned) for DB relationships.
- Enforce ownership and explicit grants for boards, action points, and documents.
- Use
core/authorization.pyhelpers; never rely solely on client hints.
Tenant Isolation
- User-scoped entities use local
User.idownership and grant tables rather than Clerk organization IDs. - All queries returning protected data must filter through ownership,
BoardPermission,ActionPointShare, or document permissions for the current localUser. - Guard against cross-user access attempts; return
404where existence should not be disclosed and log security-relevant events.
CORS & Security Headers
- CORS origins depend on
ENVIRONMENTinbackend/py/main.py(prod/staging allow specific domains; dev allows localhost). - Security headers middleware adds:
X-Frame-Options: DENYX-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=block(legacy)Strict-Transport-Securityenabled for non-dev (HSTS)
Input Validation & File Handling
- File validation in
backend/py/core/config.py:- Size limits: per file and per session
- Allow-list by MIME and extension with mismatch checks
- Clear error messages for invalid content
- Quarantine-first pattern (
backend/py/services/quarantine_service.py):- Upload to quarantine container → Defender for Storage scans → promote to files or delete infected
- Feature flags:
ENABLE_VIRUS_SCAN,ENABLE_QUARANTINE
- Storage access via time-limited SAS URLs; never trust client-provided MIME or metadata.
- Hashing/deduplication:
Document.content_hashused to detect duplicates.
Document & AI Integrations
- External services: Azure OpenAI, Vision, Document Intelligence. Always set timeouts and handle retries (
httpxwith sane defaults). - URL-based analysis endpoints (e.g., analyze_url) are SSRF-prone. Required hardening:
- Block link-local, RFC1918, and metadata IPs; allow-list schemes and domains if possible.
- Enforce max download size and content-type allow-list when fetching remote content.
Data Protection
- Database: Azure PostgreSQL with TLS enforced.
- Async engine uses SSL context; sync URL includes
sslmode=require(backend/py/db/database.py).
- Async engine uses SSL context; sync URL includes
- At-rest encryption:
- Azure Blob Storage provides SSE.
- Application-level envelope encryption fields exist (
Document.encrypted_dek,encryption_key_id;Organization.kek_key_id). Implement/maintain KEK/DEK rotation policy.
- Avoid storing secrets or PII in logs; mask sensitive values.
Secrets & Configuration
- Backend env template:
backend/py/env.example(DB, Clerk, Azure OpenAI/Vision/Doc Intelligence, Storage, SP credentials). - Frontend env template:
frontend/env.example. - Store secrets in Azure DevOps variable groups and/or Azure Key Vault; do not commit secrets. Rotate keys regularly.
Logging, Audit, and Monitoring
- Audit logging model in
models(AuditLog) and security event enums (SecurityEventType,AlertSeverity). - Prefer structured logs with request IDs (
X-Request-IDallowed in CORS headers). - Observability: use OpenTelemetry libs to emit traces/metrics to Azure Monitor.
- Health endpoints:
/health/live,/health/ready,/health/status,/health/metrics.
API Hardening (Recommended)
- Rate limiting: add per-route limits (e.g., Redis + token bucket) especially for embeddings and upload routes.
- Request size/time limits: enforce maximum payload sizes and timeouts at app and reverse-proxy layers.
- Input schemas: use Pydantic constraints (length/pattern) and explicit enums where applicable.
- Error handling: avoid leaking internals; map to consistent HTTP responses (
core/errors.py). - Idempotency: use idempotency keys for repeatable operations where appropriate.
Dependency & Container Security (Recommended)
- Keep dependencies pinned and updated; run
pip-auditandnpm auditin CI. - Container images: use minimal base images and run as non-root; enable ACR image scanning.
- SBOM generation for backend/frontend images; track CVEs and patch promptly.
Incident Response
- Prioritize containment and mitigation. Roll back by redeploying the previous image tag.
- Use
incident-response.mdfor severity, roles, communications, and postmortems. - Capture a brief postmortem with root cause, impact, timeline, and specific follow-ups.
- Add detection rules/dashboards for similar events; update the handbook if controls change.
Developer Security Checklist
- AuthN/Z: use
get_current_userand/orget_current_db_usercorrectly; verify user-scoped filters and permission grants. - Input validation: Pydantic constraints; never trust client MIME/types.
- Files: respect size/MIME allow-list; prefer quarantine flow; generate SAS server-side.
- Secrets: load from environment/Key Vault; never log secrets.
- External calls: set timeouts, retries, and sane limits.
- Observability: add logs/traces; ensure health checks cover new dependencies.
- Docs: update ADRs and this page when adding sensitive flows or controls.
Next Improvements (Backlog)
| Item | Owner | Target | Tracking |
|---|---|---|---|
| Implement SSRF protections for URL-based analysis endpoints: network blocklist/allow-list, resolver checks | Backend Engineering | 2026-Q3 | Create issue before enabling broad URL ingestion |
| Introduce global and per-user rate limiting for expensive APIs | Backend Engineering | 2026-Q3 | Track with API hardening work |
| Enforce KEK/DEK rotation and document the key management SOP | Engineering + Security owner | 2026-Q4 | Track with data-protection work |
| Add automated dependency and container scanning jobs in pipelines | Engineering + DevOps owner | 2026-Q3 | Track with CI/CD hardening |