3.6 KiB
3.6 KiB
nigig-traffic threat model (TRAFFIC-13, scoped)
Traffic is an OFFLINE, non-authenticated app. There is deliberately NO network, payment, account, telemetry, or instructor-sharing boundary in this tranche — and no such claims may appear in copy (ADR 001). Do not add web-style encryption/authentication work here. Real surfaces:
1. Dependency / toolchain supply chain
- Pinned git dependency (
andodeki/makepadfork) + crates.io packages. - Mutable CI bootstrap (
actions/checkout@v4, rustup installer download). - Gates:
Cargo.lockcommitted +cargo metadata --lockedclean-tree check; advisory/license/duplicate/yanked/source policy (CIsupply-chainjob); third-party actions pinned to immutable SHAs; toolchain from controlled image or digest-verified installer; SBOM + license/source manifest archived per release (docs/SBOM.mdat release). - Exceptions (advisory waivers, unlicensed crates) require owner, reason, and expiry, and fail closed when expired.
2. Scenario / profile / replay / asset parsing
- Inputs: static catalog (code), future imported scenario packs, learner profile JSON, replay digests, GLB/image assets.
- Policy: byte/count/depth/string/path limits BEFORE allocation/parse;
reject absolute paths,
..traversal, backslashes, unsupported file types; bounded, allocation-free-first parsers (persistence.rs,assets.rs); fuzz the byte-accepting parsers/converters with a corpus (cargo fuzztarget or#[test]hostile-archive suite at release). - Oversize/decompression-bomb/corrupt inputs fail within memory/time
budgets without panic (no
unwrap/expectinsrc/; CI greps it).
3. Path and resource exhaustion
- Asset IDs are logical (
sign_stop.glb), never filesystem paths; one validated join root; noCARGO_MANIFEST_DIRprobes in packaged builds. - Budgets (§6) enforced by validators: ≤256 entities/scenario, ≤32 movers, ≤2048 statics, ≤64 criteria, ≤4096 rule events (ring cap), 30-minute attempt cap, 8 MiB profile, 10k attempts before compaction, 150 MiB curated assets, texture residency caps. Over-budget content is excluded from the catalog, never silently downscaled for assessment.
4. Local learner privacy
- Anonymous by default: opaque learner ID (
anon-*), no names, no telemetry, no cloud sync, no home-grown at-rest encryption. - Restrictive platform file permissions on the profile dir; atomic temp + flush/sync + rename writes; verify-by-reopen; recovery states (Absent / Corrupt-preserved / FutureVersion-read-only / IoError) that never silently reset to empty.
- Logs are bounded and contain no profile contents or absolute developer paths. Export/delete/reset controls ship with persistence before any "saved locally" copy appears (settings copy is session-only until then).
- Explicit NON-GOALS this tranche: accounts, instructor sharing, cloud backup, analytics, secondary use. Each needs a separately reviewed purpose, retention policy, consent flow, and threat model.
5. Unsafe / dependency-code scope
- Source-level
unsafegrep covers Trafficsrc/only and does NOT constrainunsafein dependencies (including the Makepad fork). Dependency risk is managed via pin + audit + SBOM, not grep.
Residual risks (accepted, tracked)
- GUI harness cannot boot in CI (TRAFFIC-14): runtime regressions rely on headless production-path journeys until the harness is repaired.
- No qualified curriculum review (TRAFFIC-08): all content is practice preview; assessment release is blocked.
- Pinned fork is internally inconsistent (TRAFFIC-P0-01): builds fail closed until a coherent upstream revision is pinned.