Trust & Compliance
Iron-Clad Security
Security is the architectural foundation, not a feature layered on top. Every design decision starts with the assumption that data must be private, access must be verifiable, and secrets must never rest in plaintext.
Threat Model Summary
Data Exfiltration
ACL hard-filter at vector layer + relational post-filter. JWT-anchored WHERE on all SQL.
Credential Theft
AES-GCM secrets in S3, derived from passphrase. 15-minute JWT TTL. HttpOnly cookies.
Insider Threat
Full audit trail. Classification lock. Traceable delegation with immutable log.
Private-by-Default ACL
Every vector query anchored on owner_id. Hard-filter at engine level — no post-hoc stripping.
Every vector search carries a mandatory owner_id filter applied at the LanceDB engine level.
Sharing uses access_ids prefixed with user: or group:. Only appended — never standalone.
Creators always retain access even if sharing metadata is null or revoked by another editor.
Editors can share/revoke within their own access scope, but every change is audit-logged.
Defense-in-Depth Retrieval
Two independent permission checks: vector layer ACL + relational post-filter before delivery.
Layer 1: Hard-filter applied at the vector store during retrieval. Results never leave the engine if they fail.
Layer 2: Relational permission cross-check on retrieved document IDs before results reach the client.
Both layers must independently pass. Misconfiguration of one does not open the other.
All relational queries carry JWT-anchored WHERE clauses — no cross-tenant data can surface.
AES-GCM Secret Management
Secrets encrypted at rest in S3 with AES-256-GCM. Decrypted in-memory on boot only.
JWT signing secret encrypted at rest in S3 using AES-256-GCM.
Encryption key derived from the operator's HRAG_MASTER_PASSPHRASE via PBKDF2.
Decryption happens once on node boot, held in memory. Never written to disk.
If passphrase is absent, node enters LOCKED mode. All non-public routes return 503.
Pre-Signed URL Downloads
All document downloads use authenticated S3 pre-signed URLs with a strict 60-second TTL.
No file content is ever proxied through the application server.
Download tokens expire after 60 seconds — forwarding a URL grants no lasting access.
The pre-sign request is authorised via the user's JWT, checked server-side before URL generation.
S3 bucket is fully private. All access is exclusively via pre-signed URLs.
High-Water Mark Classification
Classification severity can only increase. Highest declared or AI-detected level is locked in.
Each document has a user-declared classification and an AI-assessed classification.
Effective classification is always the maximum of the two — the "high-water mark".
Downgrading is blocked at the API level, preventing accidental declassification.
AI assessment runs asynchronously in the ingestion worker — Local WASM, Ollama, or Cloud.
Immutable Audit Log
Every share, revoke, classification change, login, and admin action captured and retained.
Append-only audit log table. Rows are never updated or deleted.
Every access delegation (share/revoke) logged with actor identity, target, and timestamp.
Classification changes, admin mutations, and node registrations all produce audit records.
Compliance officers with isCompliance flag have read-only access to the full audit trail.
Authorization Sandwich
// Every authenticated request