Security Model
Sealed Secrets & Provider Key Encryption (AES-256-GCM)
In v1.1.0, third-party LLM and embedding API keys (Google Gemini, OpenAI, etc.) are never stored in plaintext in .env files or database rows.
- Master Key:
ENCRYPTION_MASTER_KEY— a 32-byte Base64-encoded key provided at container runtime. - Sealing Implementation:
shared/crypto/secrets.pyuses AES-256-GCM authenticated encryption. - Nonce Generation: Every encryption operation generates a cryptographically random 12-byte (96-bit) initialization vector (nonce).
- Storage: The resulting ciphertext and authentication tag are stored in the
model_providers.encrypted_api_keycolumn. - Decryption Lifecycle: Keys are decrypted into memory on-demand only when initiating outbound LLM provider requests. Decrypted strings never appear in application logs or gRPC responses.
Token Lifecycle
Auth Middleware Security Chain
OAuth 2.0 Security Flow (PKCE)
Role-Based Access Control (RBAC)
The PostgreSQL 18 schema defines three distinct roles (user_role ENUM):
| Role | Capabilities | Endpoints |
|---|---|---|
user | Standard chat, conversation history, memory management, usage metrics. | /chat/*, /user/* |
contributor | All user capabilities + submitting documents for review. | /resources/submissions/* |
admin | Full system governance, provider configuration, model catalog, user moderation, credit grants. | /admin/*, /resources/* |
Network Isolation & Attack Surface Analysis
1. Internal Docker Bridge Isolation
In production (docker-compose.yml), internal storage engines are completely shielded from host ingress:
- Redis (6379), Qdrant (6333/6334), PostgreSQL (5432), and Intelligence (50051) do not map ports to the host network.
- Only the Rust API gateway exposes port 4000 to host traffic.
2. Rate Limiting & Tiered Abuse Prevention
- Configured via
tower_governorin the API gateway. - Redis-backed sliding window rate limits protect against IP and user-level request flooding.
- Dedicated strict limiter protects public endpoints such as
POST /contactand/auth/signin.
3. Server-Side Credit Metering
- In v1.1.0, free quotas are enforced strictly on the server via
user_credit_balances. - Credits are denominated at 1 credit = 1.00); accounts receive a 10.00 credit signup bonus ($0.01 equivalent).
- Pre-stream reservations (
credit_holds) prevent users from streaming completions beyond their available balance. - All token debits are recorded in an append-only
credit_transactionsledger with cryptographic idempotency keys.
4. Tenant Isolation in Qdrant
- Knowledge chunks in Qdrant are partitioned with
user_idkeyword tenant indexes. - Hybrid search filters enforce
should: [user_id == current_user, is_global == true], guaranteeing that private enterprise documents cannot leak across user boundaries.
Last updated on