# Yemaya Study & Deconstruction Workspace — Threat Model (YSD-4090)

This threat model covers the trust boundaries and attack surfaces of the Study &
Deconstruction Workspace. For each surface it names the assets, the principal
threats, the mitigation, and the mitigation's status (**implemented** /
**partial** / **planned**), citing the checklist item that owns it. It is a
living document: new surfaces (URL import, live sessions, provider callbacks)
update their rows as they ship.

## Trust boundaries

1. **Tenant boundary** — every record, object, and projection is owned by
   exactly one tenant; no cross-tenant read or write is ever legitimate.
2. **Project boundary** — within a tenant, membership scopes access to a
   project's sources, annotations, and derivatives.
3. **Rights boundary** — the central rights gate decides every
   playback/processing/sharing/export/transfer, deny-by-default.
4. **Untrusted-content boundary** — source bytes, transcripts, imported
   metadata, and (future) URLs are untrusted input to parsers and model prompts.
5. **Provider boundary** — external providers (streams, callbacks) are outside
   the trust perimeter; the workspace links, it does not import provider bytes.

## Surfaces and threats

### Tenant boundaries and project sharing

- **Assets:** all records, objects, projections.
- **Threats:** cross-tenant read via a forged/borrowed token; a foreign tenant's
  grant satisfying a local rights check; project membership bypass; a saved view
  or cache serving another tenant's data.
- **Mitigations:** tenant-scoped authorization on every store read and object
  key (**implemented**, YSD-3021/4091); the rights gate scopes
  `listRightsGrantsForWork` by tenant so a foreign grant cannot satisfy a local
  check (**implemented** — this was a real bug the YSD-3048 leakage tests
  found); the rights-epoch query cache keys by tenant and the zero-leakage suite
  covers direct results, facets, snippets, nearest neighbours, graph paths,
  clusters, caches, and saved views (**implemented**, YSD-3048); a
  validly-signed token for another tenant is refused 403 (**implemented**,
  app.spec).

### Untrusted files and media parsers

- **Assets:** the ingesting service, object storage.
- **Threats:** malicious media crashing/owning a parser; a decompression bomb; a
  DRM-protected file the workspace is coerced into decrypting; an oversized file
  exhausting resources.
- **Mitigations:** archives are refused outright (no decompression path,
  **implemented**, YSD-3022); size/duration/frame/pixel/codec limits are checked
  against the real probe before any byte is stored (**implemented**,
  YSD-3022/4095); DRM/encryption markers are detected and ingest refuses rather
  than decrypting (**implemented**, YSD-4030); parser sandboxing with resource
  limits is **planned** (YSD-4093).

### URL import, provider callbacks, thumbnail/link preview

- **Assets:** the service network position, internal services.
- **Threats:** SSRF to cloud metadata or internal services; DNS rebinding;
  redirect abuse; credential leakage to a provider.
- **Mitigations:** the walking skeleton is local-file only, so this surface is
  **not yet present**; when URL import ships it must apply an allowlist, block
  private/link-local/metadata ranges (including `::ffff:` IPv4-mapped forms),
  pin DNS, cap redirects, and strip credentials (**planned**, YSD-4094).
  Provider sources are link-only — no bytes are fetched (**implemented**,
  YSD-4009), which keeps most of this surface closed by construction.

### Model prompts and untrusted content

- **Assets:** the model context, model tools.
- **Threats:** prompt injection from transcripts, subtitles, documents,
  commentary, or imported metadata; a model output presented as a settled fact;
  a prohibited inference (face/voice recognition,
  demographic/mental-health/deception/emotion) declared as a capability.
- **Mitigations:** the analysis method surface is a fixed safe union validated
  against the YSD-4052 prohibition at wiring time (**implemented**); model
  outputs are always the `model-suggestion` layer, never a bare
  observation/interpretation (**implemented**, YSD-4071); safe-language checks
  reject mind-reading/diagnosis/opaque scores in prompts and copy
  (**implemented**, YSD-4070/4076); isolating untrusted content from system
  prompts and model tools is **partial** (YSD-4096) — the boundary is documented
  and the analysis surface is constrained, structural isolation lands with the
  model-integration work.

### Game connectors and live sessions

- **Assets:** session telemetry, participant identity, the session process.
- **Threats:** ingesting player PII; process injection / anti-cheat evasion;
  harassment or an unsafe classroom in a live session.
- **Mitigations:** game-session ingest scrubs player identifiers, chat, voice,
  and network addresses before storage (**implemented**, YSD-4057); the study
  adapters evaluate no live process and hold no injection capability
  (**implemented**, proven by the YSD-4015 conformance); moderation controls
  (flag/hide/remove/mute/lock/escalate) cover shared studies and live sessions
  (**implemented**, YSD-4074).

### Exports

- **Assets:** the export document, downstream consumers.
- **Threats:** exporting rights-denied source content; leaking secrets, signed
  URLs, or internal policy into an export; exporting a private example without
  audience-compatible consent.
- **Mitigations:** exports are rights-filtered per work and refuse outright when
  nothing is permitted (**implemented**, YSD-1035);
  attribution/licence/deep-link manifests ride every output (**implemented**,
  YSD-4032); audience-compatible consent gates private examples
  (**implemented**, YSD-4056); secrets, tokens, and signed URLs are scrubbed
  from exports (**implemented**, YSD-4097) — every provider deep link is
  credential-stripped (SigV4/SAS/token params and userinfo removed) and
  analyst-authored free text (licence conditions, attribution) is
  secret-redacted before it rides the export off-box; hidden container metadata
  is never promoted to a stored field by the prober, so it has no path into an
  export; analytics payloads are scrubbed at the event boundary
  (telemetry-privacy) and config summaries are redacted.

### Signing

- **Assets:** content-credential signatures, replay-bundle integrity.
- **Threats:** signing-key compromise; a forged or replayed signature.
- **Mitigations:** replay-bundle integrity is a real sha256 anchor
  (**implemented**, bellona adapter); content-credential signing and key
  rotation are **planned** (YSD-4092), with the honest
  `contentCredentials: { status: 'not-inspected' }` seam recorded until the
  inspector ships.

### Deletion

- **Assets:** originals, derivatives, projections, exports, tombstones.
- **Threats:** an incomplete deletion leaving recoverable data; a legal hold
  silently overridden; a stuck deletion reading as complete.
- **Mitigations:** deletion is a durable, resumable saga with per-store
  acknowledgements, a service-objective timer, and a terminal
  needs-manual-review state — it can never read as done while incomplete
  (**implemented**, YSD-3063); legal hold outranks deletion (**implemented**,
  YSD-3023); expiry invalidates caches/URLs and schedules derivative cleanup
  (**implemented**, YSD-3062).

### Administrator actions

- **Assets:** every record and control.
- **Threats:** an admin action taken without a trail; privilege escalation.
- **Mitigations:** the tamper-evident hash-chained audit ledger records rights
  decisions, access, sharing, exports, transfers, model runs, reviews, identity
  merges, graph traversals, deletion, restoration, and administrator actions
  (**implemented**, YSD-3060); auditing privileged access and separating service
  identities is **partial** (YSD-4092).

## Open items (planned mitigations)

- Parser sandboxing with resource limits (YSD-4093).
- SSRF / DNS-rebinding / redirect protection for URL import when it ships
  (YSD-4094).
- Structural isolation of untrusted content from model prompts/tools (YSD-4096)
  — no model surface exists yet; the isolation seam ships with it.
- Encryption-at-rest key rotation, short-lived credentials, privileged- access
  audit (YSD-4092).
- Security CI: SAST, dependency, secret, container, IaC, parser fuzz,
  authorization, prompt-injection, SSRF, archive-bomb, cross-tenant (YSD-4099).

Incident runbooks and alerts are **implemented** (YSD-4100):
`incident-runbooks.md` covers all eight incident classes and
`apps/yemaya/svc-study-workspace/observability/study-workspace.alerts.yml`
carries Prometheus alerts wired to real exported metrics (verified by
`alert-rules.spec.ts`, which fails on any fabricated metric name).
