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
+61 -2
View File
@@ -20,14 +20,27 @@ across the first real provisioning (2026-06-23) and the firmware-update episode
> **not** replace reconciliation, and it cannot stop a *legitimate, logged-in* operator from
> committing fraud through the app (that's what the signed ledger + reconciliation are for).
> ⚠ **Caveat on the ledger's tamper-resistance (2026-07-02).** The "signed event chain" above is
> **software-signed today** (HMAC, key in `EVENT_SIGNING_KEY` on the host disk) — the [[atecc608]]
> secure element is [[open-questions|upcoming, not present]]. So a physical adversary who *decrypts
> the disk* (see the tamper chain below) reads the signing key and can **forge/re-sign a doctored
> ledger undetectably** — the chain does not save you against a host-owner until a non-extractable
> hardware signer ([[tpm|TPM]] / USB HSM — [[hardware-signer-options]]) is wired. Until then the disk's
> confidentiality/integrity leans harder on the controls below, and the residual backstop against
> forgery is **external reconciliation** against records the box doesn't hold (payments, an offsite
> backup, a separate witness), not the on-disk signature.
## What it defends against
The appliance sits on-site, physically reachable by the [[threat-model|booth operator (the primary
adversary)]] and by an outsider who can open the case. Without host hardening, either can:
- **Pull the SSD** and read/alter the SQLite ledger offline → FDE (LUKS) defeats this.
- **Boot a live USB** to mount and edit the disk → Secure Boot + TPM-sealing (PCR 7) defeats booting
a tampered/unsigned kernel; FDE keeps the data unreadable.
- **Boot a live USB** to mount and edit the disk → **the BIOS boot-order/boot-menu password is the
load-bearing control here**, NOT Secure Boot. Secure Boot happily runs a *signed* Ubuntu live USB,
and PCR-7-only sealing can't distinguish it from our own boot (same signing authorities → same
PCR 7 → the TPM would unseal). So confidentiality rests on the operator being unable to *select*
the USB. See the physical-tamper chain below (a CMOS reset strips that password).
- **Edit the GRUB cmdline** (`init=/bin/bash`) for a no-login root shell on the *decrypted* disk →
the GRUB edit-lock defeats this (the TPM seal does NOT — see below).
- **Escalate from the operator login** (sudo, `docker`/`lxd` groups) → the unprivileged-operator
@@ -74,6 +87,50 @@ turns a routine "security update" into a booth-availability risk:
> false safety signal). Before any firmware change, prove a *typed* passphrase still unlocks the disk
> with `--disable-external-tokens` — see [[appliance-provisioning]] §4a.
## Physical-tamper chain & accepted risks (traced 2026-07-02, Dell OptiPlex 7070)
The BIOS admin password gates Setup **and** the one-time boot menu (verified: choosing a USB device
at F12 prompts for the password). That closes the live-USB path — *while the password holds*. The
uncomfortable finding is that the password is a **soft control** against a case-opening adversary:
1. **CMOS reset** (pull the coin cell, or the on-board PSWD/CMOS-clear jumper — Dell documents its
location) → BIOS *settings* return to factory defaults: **admin password cleared, boot menu
open**. It does NOT wipe the Secure-Boot key databases (PK/KEK/db/dbx live in SPI-flash NVRAM,
not the battery-backed RTC), and the 7070's factory default is **Secure Boot = Enabled**. So
after the reset Secure Boot comes back **on, same MS keys** → **PCR 7 reconstructs to the same
value.**
2. **Boot a signed Ubuntu live USB** (now selectable). Same signing authorities → PCR 7 matches the
sealing policy → the attacker runs `cryptsetup`/`systemd-cryptsetup` and the **TPM releases the
LUKS key**. Disk decrypts; they have **root on the decrypted filesystem**, including the ledger.
- Note the asymmetry: if instead they *disable* Secure Boot in the now-unlocked BIOS, PCR 7
**changes** → the TPM refuses → the box drops to the slot-0 passphrase prompt they don't have.
So *disabling* Secure Boot locks them out; leaving it at the reset default lets them in. This is
the PCR-7-only "same-signer" weakness (systemd docs recommend PCR 7 **+ a PIN** to close it).
**Net:** a battery-pull alone yields nothing (disk stays sealed), but **battery-pull → live-USB →
PCR-7 unseal** is a realistic chain to **root on the decrypted data**. What it costs the attacker: a
screwdriver and a signed USB. What still holds after it: they never get the **escrowed slot-0
passphrase**, and (the point of the caveat above) the ledger's forgery-resistance depends on the
signer — with today's **on-disk HMAC key they CAN forge the ledger**; only a hardware signer
([[hardware-signer-options]]) would keep the financial record unforgeable through this.
**Accepted risks (named, not silently "covered"):**
- **PCR-7 same-signer unseal via CMOS reset** (above). *Not* mitigated by the current config. Real
fixes both cost the thing we optimised for: a **TPM PIN** (`--tpm2-with-pin=yes`) closes it but
**kills unattended boot** (someone types a PIN each power event); **custom Secure-Boot keys / more
PCRs** close it but reintroduce re-seal churn on kernel/shim updates (the exact thing PCR-7-only
avoids). Deferred decision — accept for now; the primary control remains reconciliation + escrowed
backups, not disk confidentiality.
- **Unsigned initramfs (evil-maid).** `/boot` is unencrypted and Ubuntu does **not** sign the
initramfs (Secure Boot verifies shim→GRUB→kernel; PCR 7 doesn't measure the initrd). The initramfs
is exactly the code that receives the LUKS key, so a maid who tampers it and waits one boot can
harvest the key. Accepted: needs repeated privileged physical access, and a hardware signer would
still keep the ledger unforgeable even from a fully-owned host.
- **Operator USB at an auto-logged-in session** — unverified what the unprivileged operator account
can read on the host (e.g. can it reach the Docker-mounted `/data`?). **TODO: verify** the operator
can't read the DB volume or `EVENT_SIGNING_KEY` from its own login.
## Where the commands live
This page is the rationale. The **verified, run-on-real-hardware commands** are in
@@ -89,4 +146,6 @@ root-capable remote agent — see [[fleet-deployment-komodo]] (bind to the NetBi
- [[threat-model]] — the operator-adversary framing this hardening serves.
- [[reconciliation]] / [[append-only-event-chain]] — the **primary** anti-fraud control this
complements, never replaces.
- [[hardware-signer-options]] — TPM / USB-HSM / ATECC608 options for a non-extractable ledger
signing key (the missing piece this page's tamper chain exposes).
- [[fleet-deployment-komodo]] — Periphery as part of the trusted computing base.
+13 -4
View File
@@ -40,10 +40,19 @@ procurement. (See [[parking-system-architecture]] §10.)
but **unverifiable after the machine dies**). **Restore is admin-only/out-of-band** (operator-adversary
surface — [[threat-model]]). See [[backup-recovery]], [[fleet-deployment-komodo]], [[disk-os-hardening]],
[[reconciliation]] (#4).
6. **Secure-element integration.** Confirm [[atecc608]] wiring/usage on the host (event
signing). The [[esp32-custom-controller]] command-authentication use is **deferred — not
being implemented for now** (access control is the [[dingtian-relay]] behind
[[network-isolation]]); revisit only if prevention-grade device auth becomes a requirement.
6. **Secure-element integration.** _(Updated 2026-07-02: no secure element is on-site today.)_
Event signing currently runs on the **software `SoftwareSigner`** (HMAC-SHA256, key in
`EVENT_SIGNING_KEY` — an env var **on the host disk**). So the ledger is tamper-EVIDENT but
**not** unforgeable by anyone who owns the host: a case-opening adversary who decrypts the disk
reads the key and can re-sign a doctored chain (see [[append-only-event-chain]] "pull-the-disk",
[[disk-os-hardening]] physical-tamper chain). The **[[atecc608]] is UPCOMING, not present** — and
it isn't even the right host part: on a PC appliance the realistic non-extractable host signer is
the **[[tpm|TPM 2.0]]** the box already has, or a **USB HSM** (Nitrokey HSM 2 / SmartCard-HSM);
reserve the ATECC608 for the (deferred) [[esp32-custom-controller]]. The concrete menu +
recommendation (TPM interim → USB-HSM target) is in [[hardware-signer-options]]. The
controller command-authentication use is **deferred — not being implemented for now** (access
control is the [[dingtian-relay]] behind [[network-isolation]]); revisit only if prevention-grade
device auth becomes a requirement.
7. **JWT signing: symmetric vs. asymmetric key.** _(Raised by the commit security review, not the
source doc.)_ Auth currently uses a symmetric HMAC secret (`@fastify/jwt`, see
[[local-jwt-auth]]) — the same secret signs *and* verifies, so it must live on every host that
+5 -3
View File
@@ -25,9 +25,11 @@ The decisions treated as settled in the design notes. (See [[parking-system-arch
deny-by-default native surface that fits [[threat-model|the booth-operator threat model]]. The
shell stays **thin**: all privileged logic remains in [[fastify]]. One open dependency — the
appliance's WebKitGTK version (see [[open-questions]] #11).
- **Integrity:** append-only, hash-chained, [[atecc608]]-signed event log
([[append-only-event-chain]]); **[[reconciliation]] is the anti-fraud control**; encryption
protects only at-rest (see [[threat-model]]).
- **Integrity:** append-only, hash-chained, **software-signed** event log
([[append-only-event-chain]]) — hardware-backed signing (a non-extractable key in the
**[[tpm|TPM]]** or a **USB HSM**; the [[atecc608]] is [[open-questions|upcoming, not present]]) is
the target that makes it unforgeable by a host owner ([[hardware-signer-options]]). **[[reconciliation]]
is the anti-fraud control**; encryption protects only at-rest (see [[threat-model]]).
- **Access control:** the **[[dingtian-relay]]** relay+input controller, on an **isolated VLAN**
([[network-isolation]]). Chosen because its **inputs are decoupled from its relays**, enabling
host-in-the-loop ticket-first entry — the resolution to [[access-controller-button-flow]].