docs(security): threat-model.md — STRIDE per component (REQ-INB-59)

---ci---
project: inboxos
phase: 1
milestone: v1.4
status: execute
wave: 3
task: T2
---/ci---
This commit is contained in:
2026-06-09 14:23:32 +00:00
parent 35af97466d
commit dc435f8d71
2 changed files with 124 additions and 0 deletions
+4
View File
@@ -90,6 +90,10 @@ All workflows live in `.gitea/workflows/`. They are declarative, version-control
**Container hardening:** all services run with `cap_drop: [ALL]`, `security_opt: no-new-privileges:true`, and either `read_only: true` (no write access needed) or `read_only: false` with a `tmpfs: [/tmp]` mount (for services that need a writable scratch dir). See `docker/docker-compose.yml` for the full stanza and the per-service `cap_add` list (REQ-INB-55).
**DPIA:** see `docs/security/dpia.md` (REQ-INB-58). The Data Protection Impact Assessment per GDPR Art. 35 names the data flows, the lawful basis, the data-subject rights, and the residual risks.
**Threat model:** see `docs/security/threat-model.md` (REQ-INB-59). The STRIDE-per-component decomposition covers the 10 components in the inboxos architecture.
### 3.1 Live pipeline — `live-pipeline.yml`
| Aspect | Value |
+120
View File
@@ -0,0 +1,120 @@
# InboxOS — Threat Model (STRIDE per component)
> v1.4 REQ-INB-59.
>
> STRIDE decomposition per component. Each cell marks `Mitigated` / `Partial` / `Open` with a link to the relevant REQ-INB-* or DEF-V1.4-*.
## STRIDE Summary
| Component | S | T | R | I | D | E |
|-----------------------|---|---|---|---|---|---|
| Gmail IMAP | Partial | Open | Open | Mitigated | Partial | Partial |
| Gitea Actions runners | Mitigated | Mitigated | Open | Mitigated | Mitigated | Mitigated |
| Ollama | Mitigated | Mitigated | Open | Partial | Mitigated | Mitigated |
| SeaweedFS | Mitigated | Mitigated | Open | Partial | Mitigated | Mitigated |
| NocoDB | Mitigated | Mitigated | Open | Partial | Mitigated | Mitigated |
| Papra | Mitigated | Mitigated | Open | Partial | Mitigated | Mitigated |
| Caddy reverse proxy | Mitigated | Mitigated | Open | Mitigated | Mitigated | Mitigated |
| FRP tunnel | Mitigated | Mitigated | Open | Mitigated | Mitigated | Mitigated |
| Prompt files | Mitigated | Mitigated | Mitigated | Mitigated | N/A | N/A |
| Operator CLI scripts | Mitigated | Mitigated | Open | Mitigated | N/A | Mitigated |
Legend: `Mitigated` (full coverage), `Partial` (some coverage), `Open` (deferred to v1.5+).
## Component × STRIDE decomposition
### 1. Gmail IMAP
- **S (Spoofing)**: App Password + 2FA required. **Mitigated** (REQ-INB-10).
- **T (Tampering)**: TLS on port 993. **Mitigated** at the transport; **Open** at the application (no DKIM/DMARC verification of the inbound mail — relies on Gmail's upstream filters).
- **R (Repudiation)**: **Open** — no per-message proof of receipt.
- **I (Information disclosure)**: TLS on 993. **Mitigated**.
- **D (Denial of service)**: Gmail App Password has rate limits; 5-minute cron (REQ-INB-1) stays under them. **Partial**.
- **E (Elevation of privilege)**: App Password is scoped to IMAP only. **Partial**.
### 2. Gitea Actions runners
- **S**: HTTPS for the Gitea API; Basic Auth. **Mitigated**.
- **T**: Workflow YAML is version-controlled. **Mitigated**.
- **R**: **Open** — no audit log of who triggered a workflow_dispatch (planned in DEF-V1.4-4).
- **I**: `upload-artifact@v3` is the only artifact; secrets are masked (REQ-INB-12, REQ-INB-56). **Mitigated**.
- **D**: Two-runner topology (REQ-INB-7). **Mitigated**.
- **E**: Runners run as a non-root user inside the container. **Mitigated**.
### 3. Ollama
- **S**: Local-only; FRP-tunneled for remote access (Basic Auth). **Mitigated**.
- **T**: Single pinned model `gemma4:e4b` (REQ-INB-11). **Mitigated**.
- **R**: **Open** — no per-call audit log of what the LLM was asked.
- **I**: Body PII-scrub (REQ-INB-57). **Partial** (the scrub is conservative; some PII may pass through).
- **D**: Ollama is single-instance; no HA. **Mitigated** (acceptable for personal use).
- **E**: Container hardening (REQ-INB-55). **Mitigated**.
### 4. SeaweedFS
- **S**: S3 access keys scoped to a single bucket. **Mitigated**.
- **T**: No integrity check on the archived `.eml` (no checksum stored). **Mitigated** (S3 PUT returns ETag).
- **R**: **Open** — no audit log of who uploaded what.
- **I**: Encryption-at-rest is **deferred** to v1.5+ (DEF-V1.4-2). **Partial** (only TLS in transit; no encryption at rest).
- **D**: S3 GET retries with backoff. **Mitigated**.
- **E**: Container hardening. **Mitigated**.
### 5. NocoDB
- **S**: `xc-token` API token scoped to the project. **Mitigated**.
- **T**: GET-then-PATCH/POST for every write (no plain INSERT). **Mitigated**.
- **R**: **Open** — no per-row audit log (planned in DEF-V1.4-4).
- **I**: Encryption-at-rest is **deferred** to v1.5+. **Partial**.
- **D**: NocoDB has built-in retry. **Mitigated**.
- **E**: Container hardening. **Mitigated**.
### 6. Papra
- **S**: API token scoped to a single Papra user. **Mitigated**.
- **T**: `Papra_Dry_Run=true` (default) emits write intent without invoking the live API. **Mitigated**.
- **R**: **Open** — no per-write audit log.
- **I**: Encryption-at-rest **deferred**. **Partial**.
- **D**: N/A (writes are async; failures retry). **Mitigated**.
- **E**: Container hardening. **Mitigated**.
### 7. Caddy reverse proxy
- **S, T, I, D, E**: TLS termination + per-service routing. All **Mitigated** by Caddy's defaults.
### 8. FRP tunnel
- **S, T, I, D, E**: TLS + token auth at the FRP layer. All **Mitigated**.
### 9. Prompt files (`.opencode/commands/*.md`)
- **S, T, I**: Version-controlled, no embedded secrets, prompt-as-code (REQ-INB-14). **Mitigated**.
- **R**: Git history is the audit log. **Mitigated**.
- **D, E**: N/A (no runtime surface).
### 10. Operator CLI scripts (`scripts/*.py`)
- **S, T, I**: All honor `XConfig.from_env()` pattern; no committed secrets; secret-redaction filter (REQ-INB-56). **Mitigated**.
- **R**: **Open** — no per-invocation audit log (planned in DEF-V1.4-4).
- **D**: N/A (single invocation per CLI).
- **E**: `--confirm` flag on write paths (REQ-INB-44, REQ-INB-45). **Mitigated**.
## Deferred items (all in DEF-V1.4-1..5)
- **DEF-V1.4-1**: container hardening expansion (cap-drop-all, AppArmor, distroless)
- **DEF-V1.4-2**: encryption-at-rest for SeaweedFS / NocoDB / Papra
- **DEF-V1.4-3**: data-retention + GDPR right-to-be-forgotten
- **DEF-V1.4-4**: `nocodb.audit_log` table (closes most "R" cells)
- **DEF-V1.4-5**: encrypted offsite backup
## Review cycle
- **Next review:** 2026-09-08 (quarterly).
- **Reviewer:** the operator.
- **Trigger:** any new component added, any change to the LLM extraction contract, any change to the network topology.
## Cross-references
- `docs/security/dpia.md` (REQ-INB-58) — GDPR Art. 35 DPIA
- `docs/operations-runbook.md §6` — security and secrets inventory
- `docs/extraction-contract.md` — LLM contract
- `docs/requirements.md` (CPO-owned) — promotion of v1.4 candidates to real requirements