docs(wiki): ATECC608 is upcoming — retag ledger signing to the on-host reality

No secure element is on-site: event signing runs on the software HMAC
(EVENT_SIGNING_KEY, an env var on the host disk), so the ledger is
tamper-EVIDENT but forgeable by anyone who owns the host. Several pages
overstated it as present-tense "ATECC608-signed / unforgeable"; correct them.

- NEW concepts/hardware-signer-options.md: four options for a non-extractable
  signing key (USB HSM / YubiKey / reuse the TPM / plain-dongle trap) + the
  recommendation (TPM interim → USB-HSM target; ATECC608 stays for the embedded
  ESP32, wrong part for a PC host).
- entities/atecc608.md: UPCOMING-not-present status banner + PC-vs-embedded.
- disk-os-hardening.md: fix the live-USB row (BIOS boot-order password is
  load-bearing, not Secure Boot — a signed live USB runs); add a physical-tamper
  chain (Dell 7070 CMOS-reset → live-USB → PCR-7 same-signer unseal) + accepted
  risks (that unseal, unsigned-initramfs evil-maid, operator-USB read TODO).
- open-questions #6 reframed; standing-decisions / overview / threat-model /
  index de-overstated; log query entry.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-07-04 13:41:11 +02:00
parent 306d136a08
commit c142166972
9 changed files with 274 additions and 27 deletions
+68
View File
@@ -2139,3 +2139,71 @@ override-releases-with-attribution, low-confidence-no-warning, own-plate-no-warn
operator-issued-entry.md + plate-reconciliation.md; cross-linked from entry-exit-points,
capacity-occupancy, index. Preserves "a plate never OPENS a barrier alone — and now never TRAPS a car
alone either."
## [2026-07-01] deploy | Promote dev → stage (d2ab2e0) → park-buzi, pinned TAG=stage-d2ab2e0
Merged dev → stage (no-ff, clean — stage content was fully contained in dev). Shipped to the staging
booth: snapshot content-type fix, Active Sessions/modal rework, DB reset CLI, drawer redesign (operator
records / admin reviews), card tender disabled (no POS), operator-issued entry + exit plate-swap
reconciliation. Push to stage triggered CI → built parking-server/vision :stage + :stage-d2ab2e0. Pinned
TAG=stage-d2ab2e0 in komodo/resources.toml on BOTH stage and dev (the ResourceSync's source branch is a
Core-side config, so both agree — see komodo/README.md; they're identical content anyway).
Migration note: this promotion carries migrations 0018 (drawer:create) + 0019 (session:create). BOTH are
DATA SEEDS, not schema — INSERT OR IGNORE one role_permissions row each for the built-in `operator` role;
idempotent, no CREATE/ALTER, existing data untouched. They apply automatically at container boot
(docker-entrypoint.sh → migrate-runtime.mjs, before the server starts) against the /data volume DB, which
survives the redeploy. Caveat recorded in container-deployment.md: a permission seeded to the built-in
operator role does NOT reach a CUSTOM role — an admin toggles it in Setup → Roles.
Deploy (operator, in Komodo Core): refresh ResourceSync (TAG diff enables Execute) → Execute → Deploy
(Destroy+Deploy for a clean recreate; parking-data volume persists). Watch for `[migrate] done` in logs.
## [2026-07-02] query | Physical-tamper of the booth disk + ledger signing reality (ATECC608 is upcoming, not present)
Q (operator): can a malicious user boot a live Ubuntu / reset the BIOS (coin cell or PSWD jumper) and
get root on the storage? Traced on the actual box (Dell OptiPlex 7070): the BIOS admin password DOES
gate the F12 boot menu (selecting the USB prompts for it), so the live-USB path is closed **while the
password holds**. But a CMOS reset clears the admin password + reopens the boot menu WITHOUT wiping the
Secure-Boot key DBs (SPI-flash NVRAM, not RTC), and the 7070 default is Secure Boot=Enabled → PCR 7
reconstructs to the SAME value → a signed live Ubuntu (same signing authorities) matches the PCR-7-only
seal → the TPM releases the LUKS key → root on the decrypted disk. Battery-pull alone = nothing;
battery-pull → live-USB → PCR-7 unseal = realistic root-on-data. (Disabling Secure Boot instead CHANGES
PCR 7 → passphrase prompt → locked out; the same-signer default is the hole. systemd docs: PCR 7 + PIN.)
BIGGER correction surfaced: the ledger is NOT ATECC608-signed today. No secure element is on-site. Signing
runs on the software SoftwareSigner (HMAC, key = EVENT_SIGNING_KEY, an env var on the host disk). So the
chain is tamper-EVIDENT but forgeable by whoever owns the host — the disk-decryption chain above hands
them the key too. The ATECC608 was overstated as present in several pages; it's also the wrong part for a
PC (external I²C, embedded-native) — reserve it for the deferred ESP32; the realistic host signer is the
on-board TPM or a USB HSM.
Actions:
- NEW concepts/hardware-signer-options.md — four options (USB HSM/Nitrokey HSM 2 [target], YubiKey, reuse
the TPM [free interim, bind signing key with NO PCR policy], plain USB dongle [trap, avoid]) + the
recommendation (TPM now → USB-HSM target; ATECC608 stays for embedded). Notes the signer.ts keyId seam.
- Retag pass ATECC608 → UPCOMING/NOT-PRESENT + "software-signed today, forgeable by host owner" caveat:
entities/atecc608.md (status banner + PC-vs-embedded), append-only-event-chain already honest,
standing-decisions.md, overview.md, threat-model.md, open-questions.md #6 (reframed), index.md.
- disk-os-hardening.md: fixed the live-USB row (BIOS boot-order password is load-bearing, not Secure
Boot — signed live USB runs), added a caveat banner (software signer → disk decryption = ledger
forgery) + a "Physical-tamper chain & accepted risks" section (CMOS-reset chain; accepted risks:
PCR-7 same-signer unseal, unsigned initramfs evil-maid, operator-USB read TODO).
- Verify items for the box: (a) confirm F12/one-time-boot is password-gated (done — it is); (b) after a
CMOS clear does Secure Boot return Enabled? (expected yes on Dell); (c) can the unprivileged operator
login read /data or EVENT_SIGNING_KEY?
- Residual: signer.ts still uses HMAC (no code change this pass); the load-bearing anti-fraud control
remains reconciliation + escrowed offsite backups, NOT on-disk confidentiality/signature.
## [2026-07-02] review | Vision service (apps/vision/) hardening + fix backlog
Two code reviews of the Python/FastAPI ANPR service (general: bottlenecks/bugs/best-practice,
and a security-focused pass). Filed the findings as a prioritised, not-yet-fixed to-do list at
[[vision-service-hardening]]; cross-linked from [[opencv-anpr-service]] ("consult before touching")
and cataloged in index.md. Headline items: DoS (12MB cap checked *after* the body is buffered;
`cv2.imdecode` pixel-bomb; CPU inference on the async event loop stalling `/health`);
unauthenticated **and** operator-writable model weights → persistent recognition-poisoning
([[threat-model]]); `0.0.0.0`-by-default bind at all three layers; dev compose publishing 8089 on
all interfaces; plus correctness/hygiene (cwd-relative `.env`, `/health` always-200, pre-warm
swallowing failures, unbounded `min_confidence`). Reassurance recorded: a forged image can't open a
barrier (server re-gates at 0.85 + debounce), content-type isn't trusted, non-root, `.env` not baked
into the image. Nothing fixed yet — this is the backlog to work from.