# 06 — Security Model (Part 5) Builds on the existing hardening (read-only scope, encrypted tokens, IDOR global query filters, SSRF egress guard, non-root containers, confirmed destructive actions) and adds what multi-user + admin + multi-provider require. ## RBAC - Roles: **Admin** · **Member** (small-team, one org). First user bootstraps as Admin. - Enforced by **policy-based authorization** at the API (ASP.NET Core policies), not in the UI. | Capability | Member | Admin | |------------|:------:|:-----:| | Read/manage **own** mail & accounts | ✅ | ✅ | | Own user settings | ✅ | ✅ | | Link/unlink **own** provider accounts | ✅ | ✅ | | View/manage **other users** | ❌ | ✅ | | Toggle **feature flags** (incl. AI global) | ❌ | ✅ | | Enable/disable **providers** | ❌ | ✅ | | **Maintenance mode**, system settings | ❌ | ✅ | | View **audit log** & monitoring | ❌ | ✅ | - **No cross-user data access, ever** — Admin manages *accounts/flags/system*, **not** other users' email contents (privacy). Admin power is over the *platform*, not people's inboxes. ## OAuth token storage - Refresh/access tokens **encrypted at rest** with the Data Protection API (AES); keys persist to the mounted `/keys` volume (existing). Decrypted **only in-memory** for the moment of an API call. **Never logged, never sent to the browser.** - 1:1 `provider_tokens` per account; rotation timestamped; a compromised/rotated token is replaced atomically. Token columns are `bytea` ciphertext, not readable in DB dumps. ## Session handling - Opaque **server-side sessions** (DB-backed) + HttpOnly/Secure/SameSite cookie; **id rotated on login** (anti-fixation); idle + absolute expiry; server-side **revocation** (logout, sign-out-everywhere, admin revoke, role change). CSRF via SameSite + token. ## Admin access protection - Admin routes require the **Admin policy**; sensitive mutations (toggle AI global, disable a provider, suspend a user, enter maintenance) require a **confirmation / step-up** and are **rate-limited**. - **Every admin action is audit-logged** (`audit_logs`: actor, action, target, metadata, ip, time) — append-only. - First-admin bootstrap is one-time; afterwards admin is grant-only by an existing Admin (logged). Guard against privilege escalation: role changes are Admin-only + audited + force session refresh. ## API security boundaries - **Per-user isolation** via EF **global query filters** (extended to `account_id`/`user_id`) so a query can *never* return another user's rows — the IDOR safeguard, now multi-account. - **Input validation** (FluentValidation) on all DTOs; **mass-assignment safe** (explicit DTOs, no entity binding). - **Rate limiting** on auth, admin, search, and AI endpoints. - **SSRF egress guard** (existing) constrains all outbound calls — provider APIs, IMAP hosts, Ollama, and any opt-in cloud AI — to an allowlist; user-supplied IMAP hosts are validated. - **Security headers** (CSP, HSTS, X-Frame-Options, etc.) via the reverse proxy/API; strict CORS. ## Multi-provider & AI specifics - **Least-privilege scopes** per provider; extra scopes added per-feature with consent. - **Provider isolation:** disabling a provider flag revokes its use cleanly; per-account tokens are independent (one reauth doesn't affect others). - **Prompt injection:** email content is untrusted → LLM output is **advisory only, never triggers actions**; a human/rule confirms. AI runs **local by default**; cloud AI is explicit opt-in with per-feature consent + egress logging. - **Attachments/vision:** sandboxed parsing, size/type limits, never executed. ## Threat model (summary) | Threat | Mitigation | |--------|------------| | Account hijack via linking | Must authenticate as target user; unique `(provider, sub)`; linking an owned identity blocked | | Token theft / DB exposure | Encryption at rest; tokens never in logs/browser; rotation | | Privilege escalation | Admin-only role changes, audited, session refresh; policy checks server-side | | IDOR / cross-user leakage | Global query filters on user_id/account_id | | CSRF / session fixation | SameSite + token; session id rotation; server-side revoke | | SSRF (providers/IMAP/AI) | Egress allowlist guard; validate user-supplied hosts | | Prompt injection | AI advisory-only; never acts; local-first | | Mass admin abuse | Rate limit + step-up + full audit trail | ## Non-negotiables Admins manage the platform, **not** users' inboxes · tokens encrypted & browser-invisible · every privileged action audited · AI never required and never acts autonomously.