Files
parking_solution/wiki/concepts/threat-model.md
T
julian bfe64032d8 Initial scaffold: Turborepo monorepo + design wiki
Turborepo (pnpm workspaces) with all dependencies pinned to latest
mutually-compatible versions: turbo 2.9, TypeScript 6, Fastify 5,
React 19, Vite 8, better-sqlite3 12 + Drizzle ORM 0.45.

Layout:
- apps/server   Fastify backend (local JWT auth + role guard, /health)
- apps/web      React 19 + Vite 8 operator SPA
- packages/db   Drizzle schema on SQLite/WAL; append-only events + users
- packages/devices  reader/printer/relay adapter interfaces (intent-only relay)
- packages/shared   shared domain types

Architecture constraints from the design wiki are encoded in the scaffold:
append-only hash-chained + signed event log, device-agnostic adapters,
"a barrier is not a door" (relay expresses intent only), fully-local
offline-first auth.

wiki/ is an LLM-maintained Obsidian knowledge base (28 pages) ingested
from the architecture & design notes, with its own maintenance schema.

Verified: pnpm install, full turbo build (5/5), server boots and serves
/health, drizzle-kit generates the initial migration.
2026-06-14 00:34:11 +02:00

1.7 KiB

type, tags, sources, updated
type tags sources updated
concept
parking
security
foundational
parking-system-architecture
2026-06-14

Threat Model

The second foundational force (with offline-first). The central insight is a reframing of who the adversary is. (See parking-system-architecture §3.)

The key reframing

Early thinking focused on protecting the database at rest — SQLCipher, LUKS, BitLocker, TPM-sealed keys. All of that defends against an outsider who steals the machine or boots from external media.

That is the wrong primary threat. The most likely adversary is the legitimate operator at the booth. While the app runs, the database is decrypted in memory and the operator has full authorised access through the app. Encryption does nothing against the classic parking fraud: take the cash, then void/delete the entry/exit record so the books balance.

Consequences

The controls that actually address insider/operator fraud are different in kind:

  • append-only-event-chain — events appended, never edited/deleted; a "void" is itself a recorded event, hash-chained, and atecc608-signed (unforgeable).
  • reconciliation against an authority the operator can't alter — this is what remote sync really is: a fraud-control mechanism, not just a backup.
  • disk-os-hardening still worthwhile (defeats boot-from-USB) but not the main event; with LUKS in place, SQLCipher is optional defence-in-depth.

The same reframing recurs at the device layer: the uhppote-controller's real problem is unauthenticated commands (uhppote-udp-protocol), addressed by detection (event-log-ingestion) or prevention (esp32-custom-controller).