Files
Inboxintel/docs/discovery/multi-provider/06-security-model.md
T
cesnimda 4ce2df0a2b
CI / backend (push) Successful in 52s
CI / frontend (push) Successful in 14s
Deploy Staging / deploy (push) Successful in 18s
CI / backend (pull_request) Successful in 52s
CI / frontend (pull_request) Successful in 15s
Security / secrets (push) Successful in 4s
Security / dependencies (push) Successful in 55s
Security / secrets (pull_request) Successful in 4s
Security / dependencies (pull_request) Successful in 54s
docs: discovery blueprint + multi-provider design (#8)
2026-07-01 19:59:53 +02:00

80 lines
4.5 KiB
Markdown

# 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.