Appearance
Security & technical compliance
Control matrix
| Control | Implementation |
|---|---|
| Edge gate | HMAC ticket (SESSION_SIGNING_KEY) + expiry; no demo bypass in prod |
| Session SoR | AuthSessions + C# middleware; claims > headers |
| Tenant isolation | EF OrganizationId filters + BFF enforceRbacGuard + Postgres FORCE RLS (TenantRlsConnectionInterceptor, GUCs app.current_tenant_id / app.is_platform_operator) |
| RBAC API | Permissions on all SoR controllers + BFF Zod guards |
| Document fingerprint | SHA-256 at upload; duplicate → 409 |
| Binary access | Private R2; short presigned GET; optional AES-256-GCM |
| Audit | Append-only AuditEvent SHA-256 chain (PreviousHash / Hash) |
| Copilot disclaimer | Attached to every assistant answer |
| Secrets | Coolify/Docker runtime env — never in image layers or git |
Six-tier RBAC
Full matrix: Trust boundaries. Roles: PLATFORM_OPERATOR → SYNDICATE_GUEST. Fail-closed on market/portfolio/search/jobs — no seed-org fallback.
Queue durability
REDIS_URL→ BullMQ (web) +RedisAnalysisJobStore(C#)- Production fail-closed without Redis
- Emergency only:
LOCUS_ALLOW_INMEMORY_QUEUE=1 - Upload →
DOCUMENT_OCR; analysis → orchestrated Python job
Vault crypto
DOCUMENT_ENCRYPTION_KEY_HEX→ AES-256-GCM (vault-crypto.ts)- Read via BFF
/api/locus/documents/{id}/contentwhen encrypted - Production fail-closed; emergency:
LOCUS_ALLOW_PLAINTEXT_DOCUMENTS=1
BFF validation
Every /api/locus/* through Zod (validation.ts / schemas.ts) → structured 400, no stack traces to clients.
Auth model
- Register → Organization + admin → OTP
- Login always
mfaRequired→ OTP →locus_session=v1.<payload>.<sig> - Logout revokes
AuthSessions - No OIDC/SAML
- Ops: separate
locus_ops_session
Details: Auth & sessions.
Audit integrity
AuditService.VerifyChainIntegrityAsync — per-tenant hash chain. Mutations emit actor / action / before-after JSON.
Deploy posture (Coolify)
- One Dockerfile app per tier: web / backend / workers (+ Postgres / Redis)
- Secrets = runtime env only (“Not available during build”)
- Never set
LOCUS_ALLOW_*emergency flags in prod - CI:
.github/workflows/ci.yml— bun test/build, Python,dotnet build, secrets hygiene
Postgres FORCE RLS (shipped, slice 27)
Migration 20261012080000_PostgresRlsAndTsvectorSearch (+ later tables such as DossierRegulatoryFindings). Policies use GUCs set by TenantRlsConnectionInterceptor. Users / AuthSessions / AccessRequests stay outside FORCE RLS so pre-claim auth works. EF filters remain the app-layer fail-closed path.
Production backlog (honest)
- Maps → durable stores migration remnants
- Live Watchtower polling at scale (scheduler default off)
- Official foundational PDFs attached in ops (CI fixtures ≠ production corpus)