Update SSP
This commit is contained in:
+150
-9
@@ -572,13 +572,67 @@ this item builds the rollout machinery around it.
|
|||||||
stay served); security rollback via dbx-revoke / TPM monotonic counter
|
stay served); security rollback via dbx-revoke / TPM monotonic counter
|
||||||
(design §6).
|
(design §6).
|
||||||
- **Drain & retire** an old version only when SPDK/nvmet reports zero connected
|
- **Drain & retire** an old version only when SPDK/nvmet reports zero connected
|
||||||
controllers on it.
|
controllers on it. **Drain accuracy:** account for hosts powered off mid-rollout
|
||||||
|
— an assigned-but-offline host will reconnect to a version that may be gone, so
|
||||||
|
don't remove a version while any host that could return is still assigned to it.
|
||||||
- **Availability**: run NVMe/TCP target replicas behind distinct discovery
|
- **Availability**: run NVMe/TCP target replicas behind distinct discovery
|
||||||
entries (design §7) — never serve the whole fleet from one unreplicated node,
|
entries (design §7) — never serve the whole fleet from one unreplicated node,
|
||||||
especially mid-rollout (N versions + reboot bursts).
|
especially mid-rollout (N versions + reboot bursts).
|
||||||
- Note: kiosk *content* changes are server-side (the website) and need no fleet
|
- Note: kiosk *content* changes are server-side (the website) and need no fleet
|
||||||
update — only OS/UKI/rootfs changes require a reboot.
|
update — only OS/UKI/rootfs changes require a reboot.
|
||||||
|
|
||||||
|
### SPDK restart / availability is the load-bearing constraint (analysis 2026-06-25)
|
||||||
|
|
||||||
|
SPDK sits in the **live data path of every running host's root fs**, so a process
|
||||||
|
restart isn't like restarting a stateless service — it tears down **every**
|
||||||
|
NVMe/TCP association at once (fleet-wide, NOT version-scoped). The rollout design
|
||||||
|
must be built around **never restarting the process that holds live connections.**
|
||||||
|
|
||||||
|
- **Core principle:** a host changes root version *only by rebooting* (no live
|
||||||
|
swap). So: **version transitions = reboots; SPDK changes = additive/online; the
|
||||||
|
process stays up.** Routine rollouts never restart SPDK.
|
||||||
|
- **Online add/remove via JSON-RPC, no restart.** `nvmf_tgt` is fully
|
||||||
|
runtime-configurable (`bdev_aio_create`, `nvmf_create_subsystem`,
|
||||||
|
`nvmf_subsystem_add_ns`, `..._add_listener`). Add vY's namespaces live (existing
|
||||||
|
vX connections untouched); remove vX live once drained. **Per-version subsystem
|
||||||
|
(distinct NQN)** matters here: adding vY as a *new subsystem* never disturbs the
|
||||||
|
subsystem vX hosts are attached to — adding a *namespace* to a shared subsystem
|
||||||
|
fires a namespace-change AER + rescan at running hosts. Per-version subsystem
|
||||||
|
also gives clean per-release drain + per-release hostNQN allow-listing.
|
||||||
|
- **What a connection loss does to a running host:** root is **read-only erofs +
|
||||||
|
tmpfs overlay**. tmpfs writes (RAM) + page-cached reads keep working; **cold
|
||||||
|
reads block**. The nvme-tcp host driver reconnects (`reconnect_delay`) until
|
||||||
|
`ctrl_loss_tmo`. **Fast SPDK restart** (same NQN/UUID/addr within the window) →
|
||||||
|
host **survives with a stall**; **long/changed/expired** → root I/O errors, host
|
||||||
|
needs a reboot ("keep alive timeout / no route to host"). Read-only +
|
||||||
|
content-addressed makes reconnect unusually clean (no write/reservation state).
|
||||||
|
- **Cheap host-side mitigation:** tune `ctrl_loss_tmo` (even `-1` = retry forever)
|
||||||
|
+ `reconnect_delay` at `nvme connect` time (dracut nvmf step). For a diskless box
|
||||||
|
"hang and recover" beats "die" — there's nothing better to fail to.
|
||||||
|
- **Structural answer — HA + NVMe-oF multipath (ANA):** run ≥2 targets serving
|
||||||
|
**byte-identical, same-UUID** namespaces; hosts multipath across them, so one
|
||||||
|
target can be restarted/upgraded while the other serves (no root loss). The
|
||||||
|
**read-only, content-addressed root makes replication trivially coherent** (no
|
||||||
|
write-coherence problem) — this architecture is ideally suited to it. Wrinkle:
|
||||||
|
the **immutable UKI cmdline** points at one discovery address, so multipath needs
|
||||||
|
discovery to return multiple paths (or a DNS name resolving to several targets).
|
||||||
|
- **Planned SPDK restarts only via drain/failover** (multipath fail-over, or a
|
||||||
|
maintenance window with generous `ctrl_loss_tmo` so hosts recover not die). There
|
||||||
|
is **no zero-impact single-node SPDK restart.**
|
||||||
|
- **Implementation gap (current lab):** SPDK runs as a container with
|
||||||
|
`spdk-setup.sh` as entrypoint + the artifact image mounted → effectively
|
||||||
|
**single-version, configured at container start**, so changing versions =
|
||||||
|
container restart = drop all connections. The work here is a **long-lived target
|
||||||
|
+ an RPC-driven control path** ("add release / remove release / drain status")
|
||||||
|
decoupled from container lifecycle, with per-version subsystems.
|
||||||
|
- **Capacity:** each concurrently-served version costs target memory/hugepages +
|
||||||
|
file-backed bdev overhead — plan for N live versions (current + previous +
|
||||||
|
canary) during long rollouts.
|
||||||
|
- **Attach gating + discovery:** with several subsystems advertised, the dracut
|
||||||
|
connect + per-subsystem hostNQN allow-list must ensure a vX host attaches **only**
|
||||||
|
vX's namespace (the by-UUID verity ref protects *what mounts*, but gate the
|
||||||
|
*attach* too); `rd.nvmf.discover` selection must be deterministic, not connect-all.
|
||||||
|
|
||||||
## [ ] 7. Harden / evaluate the NVMe-oF target (serving-node resilience)
|
## [ ] 7. Harden / evaluate the NVMe-oF target (serving-node resilience)
|
||||||
|
|
||||||
There is **no production-grade memory-safe NVMe-oF target** — the Rust NVMe work
|
There is **no production-grade memory-safe NVMe-oF target** — the Rust NVMe work
|
||||||
@@ -607,7 +661,13 @@ export is read-only + single-namespace = inherently small attack surface.
|
|||||||
- **Network-isolate :4420** so only the boot VLAN reaches the target (compose
|
- **Network-isolate :4420** so only the boot VLAN reaches the target (compose
|
||||||
with 802.1X/MACsec segmentation in prod).
|
with 802.1X/MACsec segmentation in prod).
|
||||||
- **Replicas** behind distinct discovery entries (availability is the real risk
|
- **Replicas** behind distinct discovery entries (availability is the real risk
|
||||||
— it's the fleet's disk). Ties into #6 (rolling updates) availability.
|
— it's the fleet's disk). The target is a **fleet-wide SPOF in every running
|
||||||
|
host's root data path**; a process restart drops *all* NVMe/TCP associations at
|
||||||
|
once. Structural fix = **HA + NVMe-oF multipath (ANA)** over byte-identical,
|
||||||
|
same-UUID, read-only namespaces (replication is coherent precisely because the
|
||||||
|
root is read-only + content-addressed); cheap mitigation = generous host
|
||||||
|
`ctrl_loss_tmo`/`reconnect_delay`. See the **"SPDK restart / availability"**
|
||||||
|
analysis under #6 (rolling updates) — same constraint, fuller treatment.
|
||||||
- Revisit a memory-safe target only if/when an off-the-shelf one matures
|
- Revisit a memory-safe target only if/when an off-the-shelf one matures
|
||||||
(e.g. a future Rust-for-Linux `nvmet`).
|
(e.g. a future Rust-for-Linux `nvmet`).
|
||||||
|
|
||||||
@@ -631,6 +691,13 @@ smoke test.
|
|||||||
documented upgrade on the same CA. **BENCH-VERIFY** items flagged in the files:
|
documented upgrade on the same CA. **BENCH-VERIFY** items flagged in the files:
|
||||||
hostapd MACsec build, openssl tpm2 provider vs pkcs11 key ref, EAP-TLS version.
|
hostapd MACsec build, openssl tpm2 provider vs pkcs11 key ref, EAP-TLS version.
|
||||||
PKI product decision (greenfield): start step-ca; OpenBao/EJBCA/Dogtag later.
|
PKI product decision (greenfield): start step-ca; OpenBao/EJBCA/Dogtag later.
|
||||||
|
- **First step (DONE 2026-06-22): `enrol/tpm-selftest.sh`** — non-destructive TPM
|
||||||
|
capability check (run on the booted open-port image, no `disable_dot1x` needed)
|
||||||
|
to de-risk the TPM half before the full path. Likely first finding: no openssl
|
||||||
|
TPM2 **provider** in the image (`tpm2-tss` ≠ the provider) — add `tpm2-openssl`.
|
||||||
|
- **Enrolment of the per-host identity** (key@`0x81010001` + cert@NV) is its own
|
||||||
|
design — see **#11** (TOFU + OOB fingerprint broker, pre-auth permit-set,
|
||||||
|
provisioning UKI). `tpm-provision.sh` is the manual bench stand-in for it.
|
||||||
- **NVMe discovery by DNS:** `nvmet_traddr=nvme.fleet.lab` (CI), resolved at boot
|
- **NVMe discovery by DNS:** `nvmet_traddr=nvme.fleet.lab` (CI), resolved at boot
|
||||||
by the serving dnsmasq — drop the hardcoded `192.168.50.10`.
|
by the serving dnsmasq — drop the hardcoded `192.168.50.10`.
|
||||||
- **Signing — SIGNED-UKI + SECURE-BOOT-ON PATH BENCH-VERIFIED on the Proxmox VM
|
- **Signing — SIGNED-UKI + SECURE-BOOT-ON PATH BENCH-VERIFIED on the Proxmox VM
|
||||||
@@ -645,7 +712,9 @@ smoke test.
|
|||||||
EFI attribute prefix in a bash variable (`ATTR=$'\x27\x00\x00\x00'`). Bash
|
EFI attribute prefix in a bash variable (`ATTR=$'\x27\x00\x00\x00'`). Bash
|
||||||
strings can't hold NULs → only `0x27` survived → efivarfs read a corrupt
|
strings can't hold NULs → only `0x27` survived → efivarfs read a corrupt
|
||||||
attribute u32 → every write failed with `EINVAL` ("dd: Invalid argument").
|
attribute u32 → every write failed with `EINVAL` ("dd: Invalid argument").
|
||||||
Now emitted directly with `printf` at write time. (Red herring on the way:
|
Now emitted directly with `printf` at write time. **Baked fix VERIFIED on the
|
||||||
|
820 (2026-06-22): `sudo fleet-sb-enroll` enrolled db→KEK→PK cleanly, no inline
|
||||||
|
workaround.** (Red herring on the way:
|
||||||
Proxmox EFI disks default to `pre-enrolled-keys=1`, so `mokutil --db` shows
|
Proxmox EFI disks default to `pre-enrolled-keys=1`, so `mokutil --db` shows
|
||||||
the MS cert even in Setup Mode — looked like a non-empty-db rejection but was
|
the MS cert even in Setup Mode — looked like a non-empty-db rejection but was
|
||||||
the NUL bug all along; it failed identically on a clean `pre-enrolled-keys=0`
|
the NUL bug all along; it failed identically on a clean `pre-enrolled-keys=0`
|
||||||
@@ -657,12 +726,15 @@ smoke test.
|
|||||||
(`.gitea/workflows/dnsmasq-image.yaml`) — no longer built at deploy time, and
|
(`.gitea/workflows/dnsmasq-image.yaml`) — no longer built at deploy time, and
|
||||||
carries no keys/binary. (Decision: separate `fleet-ipxe` image, not baked into
|
carries no keys/binary. (Decision: separate `fleet-ipxe` image, not baked into
|
||||||
dnsmasq, so the daemon image stays key-agnostic across SB environments.)
|
dnsmasq, so the daemon image stays key-agnostic across SB environments.)
|
||||||
|
- **820 / PXE signed chain — BENCH-VERIFIED 2026-06-22.** Real hardware (HP
|
||||||
|
EliteBook 820 G4), Secure Boot **enforcing** (`mokutil --sb-state` = enabled,
|
||||||
|
Setup Mode no, db/KEK/PK enrolled): firmware verifies the signed `snponly.efi`
|
||||||
|
(fleet-ipxe image) → signed UKI and boots. Confirms the whole `fleet-ipxe`
|
||||||
|
signing pipeline + the PXE→iPXE→UKI chain under SB on real silicon (the VM only
|
||||||
|
covered the HTTP path, which has no iPXE stage).
|
||||||
- **REMAINING for production:** (a) **secure path** — re-verify signed boot with
|
- **REMAINING for production:** (a) **secure path** — re-verify signed boot with
|
||||||
`disable_dot1x=false` (802.1X/MACsec), not just the test path; (b) **820 / PXE
|
`disable_dot1x=false` (802.1X/MACsec), not just the test path; (b) confirm
|
||||||
path** — BENCH-VERIFY the signed `fleet-ipxe` chain on the 820 (the VM's HTTP
|
signing is reproducible (verity hash stable across two signed builds).
|
||||||
path has no iPXE stage, so the signed iPXE binary is still unverified on real
|
|
||||||
PXE hardware); (c) confirm signing is reproducible (verity hash stable across
|
|
||||||
two signed builds).
|
|
||||||
- **PXE-only iPXE fallback — BENCH-VERIFIED on the EliteBook 820 G4 (2026-06-20).**
|
- **PXE-only iPXE fallback — BENCH-VERIFIED on the EliteBook 820 G4 (2026-06-20).**
|
||||||
Firmware without UEFI HTTP boot chainloads `serving/tftp/snponly.efi` → renders
|
Firmware without UEFI HTTP boot chainloads `serving/tftp/snponly.efi` → renders
|
||||||
`autoexec.ipxe` (ifopen + DHCP-retry + `imgargs <real cmdline>`) → UKI over HTTP
|
`autoexec.ipxe` (ifopen + DHCP-retry + `imgargs <real cmdline>`) → UKI over HTTP
|
||||||
@@ -757,7 +829,9 @@ full ~17-min Packer build.
|
|||||||
Speed up bringing up new workstations: bake the **public** PK/KEK/db certs into an
|
Speed up bringing up new workstations: bake the **public** PK/KEK/db certs into an
|
||||||
image, detect Secure Boot **Setup Mode** at boot, and auto-enroll them so a
|
image, detect Secure Boot **Setup Mode** at boot, and auto-enroll them so a
|
||||||
fresh/reset box adopts the fleet trust root without a manual firmware-setup visit.
|
fresh/reset box adopts the fleet trust root without a manual firmware-setup visit.
|
||||||
Pairs with #8 (signing) + [secure-boot-keys.md](secure-boot-keys.md).
|
Pairs with #8 (signing) + [secure-boot-keys.md](secure-boot-keys.md). Shares the
|
||||||
|
provisioning-UKI + isolated-environment vehicle with **#11** (which enrols the
|
||||||
|
*network* identity); build them together.
|
||||||
|
|
||||||
**Tooling gap (found 2026-06-20): `efitools` is NOT packaged for EL9** — no
|
**Tooling gap (found 2026-06-20): `efitools` is NOT packaged for EL9** — no
|
||||||
`efi-updatevar`/`efi-readvar`/`KeyTool`. Resolved for the OS-side path by writing
|
`efi-updatevar`/`efi-readvar`/`KeyTool`. Resolved for the OS-side path by writing
|
||||||
@@ -817,3 +891,70 @@ enrolls.
|
|||||||
reasonable for a controlled fleet; the highest-assurance path is attended/firmware
|
reasonable for a controlled fleet; the highest-assurance path is attended/firmware
|
||||||
or manufacturer pre-provisioning. Default recommendation: **separate provisioning
|
or manufacturer pre-provisioning. Default recommendation: **separate provisioning
|
||||||
UKI + isolated VLAN + read-back verify.**
|
UKI + isolated VLAN + read-back verify.**
|
||||||
|
|
||||||
|
## [ ] 11. (DESIGN) TPM 802.1X identity enrolment (TOFU + OOB fingerprint)
|
||||||
|
|
||||||
|
How a host gets its **802.1X EAP-TLS client identity** the first time — the key at
|
||||||
|
TPM handle `0x81010001` + cert at NV `0x01800001` that invariant #1 says must come
|
||||||
|
from enrolment, never the image. Distinct from #10 (that enrols *Secure Boot*
|
||||||
|
PK/KEK/db); this enrols the *network identity*. They share the provisioning UKI +
|
||||||
|
isolated-environment vehicle. Pairs with #8 + the CA decision (start **step-ca**,
|
||||||
|
[serving/dot1x-bench/](../serving/dot1x-bench/); OpenBao/EJBCA/Dogtag later).
|
||||||
|
|
||||||
|
**Chosen pattern — trust-on-first-use with out-of-band fingerprint approval:**
|
||||||
|
on an empty TPM the host generates a key *in* the TPM, builds a CSR, submits it to
|
||||||
|
an enrolment **broker**, and shows a **fingerprint** on the Plymouth splash; an
|
||||||
|
admin visually cross-checks that fingerprint against the broker's pending-list and
|
||||||
|
approves; the broker has step-ca sign the CSR and returns the cert; the host writes
|
||||||
|
it to NV `0x01800001` and proceeds to authenticate. Sound, recognised pattern
|
||||||
|
(SSH/WireGuard/Signal-style OOB verification); good fit for invariant #1.
|
||||||
|
|
||||||
|
**Key design decisions (settled 2026-06-22):**
|
||||||
|
|
||||||
|
- **The pre-auth permit-set already exists — enrolment rides in it.** The firmware
|
||||||
|
can't do 802.1X, so the UKI fetch (DHCP/DNS/TFTP/HTTP to the serving host) is
|
||||||
|
**always pre-auth**; the secure model therefore *requires* a pre-auth permit-set
|
||||||
|
(low-impact 802.1X / pre-auth dACL / boot→secure dynamic VLAN; RADIUS returns the
|
||||||
|
secure VLAN on Access-Accept). The enrolment endpoint is just **another entry in
|
||||||
|
that set** — expose it as an `/enrol/` location on the **existing serving nginx**,
|
||||||
|
reverse-proxied to the broker. No new network mechanism.
|
||||||
|
- **The broker is the only new component.** step-ca signs but has no human-approval
|
||||||
|
queue: broker = `POST CSR + context → PENDING + fingerprint → admin approves →
|
||||||
|
step-ca signs → host polls → cert`. Exposed to *unauthenticated* devices by
|
||||||
|
design → harden: OOB-fingerprint gate (no auto-sign), rate-limit, time-boxed
|
||||||
|
pending, HTTPS (image trusts the serving CA), pre-auth permit scoped to only
|
||||||
|
these services + the serving host.
|
||||||
|
- **Trigger on EMPTY-NV only — split the three events:** empty NV → enrol (human);
|
||||||
|
valid key + expired/near-expiry cert → **renew** automatically (no human, it
|
||||||
|
already holds a trusted key); auth fails with a present cert → **alert + retry,
|
||||||
|
do NOT re-enrol** (auto-reenrol on failure would mask revocation and churn keys
|
||||||
|
on a transient RADIUS outage). Re-enrol after the first time = explicit admin
|
||||||
|
action (clear/flag the host).
|
||||||
|
- **Fingerprint: what it proves + entropy.** It proves "this CSR came from *this
|
||||||
|
physical device*" (approver reads the screen) — it does NOT prove TPM residency.
|
||||||
|
Pair it with **TPM attestation** (step-ca ACME `device-attest-01`, EK/AK) for the
|
||||||
|
residency proof: fingerprint = human authorises the device, attestation = the key
|
||||||
|
is really in a TPM (together → strong SSP R-01 story). Size for entropy — a short
|
||||||
|
hex fp is grindable; use a word-list/BIP39-style encoding (reads short, more
|
||||||
|
bits) + rate-limiting + a server nonce. Show device context (asset/port/location)
|
||||||
|
so the admin knows *what* they're approving.
|
||||||
|
- **Pre-auth traffic has no MACsec (plaintext at L2).** Fine for enrol (CSR/cert
|
||||||
|
are public; OOB fingerprint gives authenticity) — and it's exactly **why the UKI
|
||||||
|
must be Secure-Boot-signed** (#8): integrity of the boot comes from the signature,
|
||||||
|
not the network. Enrolment design + Secure Boot are two halves of the same
|
||||||
|
"pre-auth path is hostile" assumption.
|
||||||
|
- **Run it in a provisioning UKI/mode, not the production initramfs** — the boot
|
||||||
|
hook ordering is load-bearing (invariant #2); don't park it on a multi-minute
|
||||||
|
human-approval wait. Shares the #10 provisioning-UKI vehicle.
|
||||||
|
|
||||||
|
**Bench caveat:** `hostapd` wired is strictly port-based (no pre-auth per-flow
|
||||||
|
ACL) — before EAP success it passes nothing, so the bench can't reproduce
|
||||||
|
"boot + enrol pre-auth on the same port." Model the pre-auth state with a separate
|
||||||
|
provisioning bridge/VLAN on the rig; the in-place low-impact pre-auth permit is a
|
||||||
|
real-switch feature to validate on the 820's switch.
|
||||||
|
|
||||||
|
**First step DONE (2026-06-22):** `serving/dot1x-bench/enrol/tpm-selftest.sh` — a
|
||||||
|
non-destructive TPM capability check (device, key persist, NV roundtrip, openssl
|
||||||
|
TPM2 provider, CSR signed by the TPM key) to de-risk the TPM half before any of
|
||||||
|
this. Expected gap: the image installs `tpm2-tss` but no openssl TPM2 **provider**
|
||||||
|
(`tpm2-openssl`) — add it to the build once the self-test confirms.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Records where the as-built implementation diverges from
|
|||||||
`diskless-fleet-design-v2.pdf`. The PDF remains authoritative for the
|
`diskless-fleet-design-v2.pdf`. The PDF remains authoritative for the
|
||||||
architecture; this note captures deltas discovered bringing the build up on
|
architecture; this note captures deltas discovered bringing the build up on
|
||||||
**Rocky 9.8** until they are folded into a consolidated **v3**. Last updated
|
**Rocky 9.8** until they are folded into a consolidated **v3**. Last updated
|
||||||
2026-06-15.
|
2026-06-22.
|
||||||
|
|
||||||
The architecture is unchanged: 802.1X EAP-TLS with a TPM-held key, MACsec on the
|
The architecture is unchanged: 802.1X EAP-TLS with a TPM-held key, MACsec on the
|
||||||
access link, dm-verity-protected erofs root over NVMe/TCP, signed UKI, and the
|
access link, dm-verity-protected erofs root over NVMe/TCP, signed UKI, and the
|
||||||
@@ -57,6 +57,43 @@ indices shift with the transient discovery controller.
|
|||||||
[../serving/spdk-setup.sh](../serving/spdk-setup.sh) (2nd bdev/namespace), and
|
[../serving/spdk-setup.sh](../serving/spdk-setup.sh) (2nd bdev/namespace), and
|
||||||
CLAUDE.md invariant #9.
|
CLAUDE.md invariant #9.
|
||||||
|
|
||||||
|
## 1c. Design-level addition — pre-auth boot path & per-host identity enrolment
|
||||||
|
|
||||||
|
Two design points the PDF leaves implicit; both are load-bearing for the secure
|
||||||
|
model and are recorded here pending v3.
|
||||||
|
|
||||||
|
**The boot path is inherently pre-auth, so a pre-auth permit-set is mandatory.**
|
||||||
|
The firmware (UEFI HTTP boot / PXE→iPXE) fetches the UKI **before** any OS or
|
||||||
|
supplicant exists — there is no firmware 802.1X supplicant — so the UKI/initramfs
|
||||||
|
fetch always happens in the unauthenticated state. The secure model therefore
|
||||||
|
requires the authenticator to permit a *scoped* set of services pre-auth
|
||||||
|
(DHCP/DNS + TFTP + HTTP to the serving host) and only complete 802.1X once the
|
||||||
|
**OS** is running; RADIUS returns the secure VLAN on Access-Accept, after which
|
||||||
|
DHCP-for-the-running-system and the NVMe/TCP root ride **`macsec0`** (post-auth,
|
||||||
|
encrypted). Mechanism on a real switch: low-impact 802.1X / a pre-auth dACL /
|
||||||
|
boot→secure dynamic VLAN. Consequences:
|
||||||
|
- Pre-auth traffic has **no MACsec** (plaintext at L2). Integrity of the boot
|
||||||
|
therefore comes from **Secure Boot** (the signed UKI + signed `fleet-ipxe`), not
|
||||||
|
the network — this is *why* signing matters: the boot transport is untrusted.
|
||||||
|
- `hostapd` wired (the bench authenticator) is strictly port-based and can't model
|
||||||
|
a pre-auth per-flow permit — the in-place pre-auth ACL is a real-switch feature,
|
||||||
|
validated on the 820's switch, not the VM rig (see `serving/dot1x-bench/`).
|
||||||
|
|
||||||
|
**Per-host 802.1X identity is created by an enrolment flow, never baked in**
|
||||||
|
(invariant #1). Chosen pattern: **trust-on-first-use with out-of-band fingerprint
|
||||||
|
approval** — on an empty TPM the host generates a key *in* the TPM
|
||||||
|
(`0x81010001`), submits a CSR to an enrolment **broker** (reachable via the same
|
||||||
|
pre-auth permit-set, e.g. an `/enrol/` location on the serving nginx → broker →
|
||||||
|
step-ca signer), and shows a fingerprint on the Plymouth splash; an admin
|
||||||
|
cross-checks it and approves; the signed cert is written to NV `0x01800001` and
|
||||||
|
authentication proceeds. Enrol triggers on **empty-NV only** (expired cert →
|
||||||
|
automatic renew; auth-failure-with-cert → alert, not re-enrol). The fingerprint
|
||||||
|
authorises *which device*; **TPM attestation** (step-ca ACME `device-attest-01`)
|
||||||
|
proves *key residency* — use both for full assurance. Runs in a provisioning
|
||||||
|
UKI/mode, not the production initramfs. Full design + decisions: **TODO #11** (the
|
||||||
|
network-identity counterpart to **#10**, which enrols Secure Boot PK/KEK/db; both
|
||||||
|
share the provisioning-UKI vehicle).
|
||||||
|
|
||||||
## 2. Implementation notes (not architectural)
|
## 2. Implementation notes (not architectural)
|
||||||
|
|
||||||
These don't contradict the PDF (it doesn't specify them) but are worth recording.
|
These don't contradict the PDF (it doesn't specify them) but are worth recording.
|
||||||
|
|||||||
@@ -154,10 +154,14 @@ Mode failure (that surfaces as EACCES / "Permission denied"). Diagnose top-down:
|
|||||||
`pre-enrolled-keys=0` disk if the NUL bug is present. For a clean OVMF test bed:
|
`pre-enrolled-keys=0` disk if the NUL bug is present. For a clean OVMF test bed:
|
||||||
`qm set <vmid> --efidisk0 <storage>:1,efitype=4m,pre-enrolled-keys=0`.
|
`qm set <vmid> --efidisk0 <storage>:1,efitype=4m,pre-enrolled-keys=0`.
|
||||||
|
|
||||||
**Verified:** with the fix, a Proxmox VM enrols db→KEK→PK from the baked `.auth`
|
**Verified end-to-end on real hardware (2026-06-22):** `fleet-sb-enroll` (the
|
||||||
files and boots the CI-signed UKI under **enforcing Secure Boot** over the HTTP
|
baked, fixed script) enrols db→KEK→PK cleanly, and both boot transports verify
|
||||||
boot path (`mokutil --sb-state` = enabled). The PXE/iPXE front-end additionally
|
under **enforcing Secure Boot** (`mokutil --sb-state` = enabled):
|
||||||
needs `snponly.efi` signed with `db` — see the iPXE section below.
|
- **Proxmox VM — HTTP boot:** firmware → signed UKI (2026-06-20).
|
||||||
|
- **HP EliteBook 820 G4 — PXE boot:** firmware → signed `snponly.efi` (fleet-ipxe)
|
||||||
|
→ signed UKI (2026-06-22).
|
||||||
|
So the full signing pipeline (UKI + `fleet-ipxe`, both against the same enrolled
|
||||||
|
`db`) is proven on real silicon, not just in the VM.
|
||||||
|
|
||||||
## 4. Wire `db` into the build
|
## 4. Wire `db` into the build
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,12 @@
|
|||||||
> **A&A framework:** ASD *Information Security Manual* (ISM) — engagement target
|
> **A&A framework:** ASD *Information Security Manual* (ISM) — engagement target
|
||||||
> **May 2026 release**.
|
> **May 2026 release**.
|
||||||
>
|
>
|
||||||
> **Annex version:** 0.2 (2026-06-20). v0.2 reflects: STIG hardening applied +
|
> **Annex version:** 0.2 (updated 2026-06-22). v0.2 reflects: STIG hardening
|
||||||
> bench-verified, USBGuard device control enabled, admin `staff_u` confinement,
|
> applied + bench-verified, USBGuard device control enabled, admin `staff_u`
|
||||||
> audit offload verified, UKI signing wired (not yet enforced — new R-13),
|
> confinement, audit offload verified, PXE/iPXE boot path added, and **UEFI Secure
|
||||||
> PXE/iPXE boot path added.
|
> Boot signing verified enforcing on real hardware** (VM HTTP + 820 PXE) — R-13
|
||||||
|
> reduced from Medium to Low (residual is making signed + SB-on the standing
|
||||||
|
> default).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -150,7 +152,7 @@ ISM/PSPF style). Ratings are **pre-treatment** unless stated; the AO accepts the
|
|||||||
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| Media sanitisation / no data remanence | ISM-0347*, ISM-1218* | Prevent data remanence. | **Diskless** — no persistent local media; writable layer is **RAM tmpfs**, gone at power-off. | Implemented | — |
|
| Media sanitisation / no data remanence | ISM-0347*, ISM-1218* | Prevent data remanence. | **Diskless** — no persistent local media; writable layer is **RAM tmpfs**, gone at power-off. | Implemented | — |
|
||||||
| Tamper-evidence / boot integrity | ISM-1542*, ISM-0312* | Detect firmware/boot tampering. | Design: **UEFI Secure Boot** + signed UKI (+ signed iPXE on the PXE path) + immutable signed cmdline + dm-verity; TPM measurements available. Signing **wired in CI** + key/enrolment procedure + baked `fleet-sb-enroll` helper, but **lab runs unsigned with SB OFF**. | Partial | **R-13** (signing not enforced), R-11 (no remote attestation) |
|
| Tamper-evidence / boot integrity | ISM-1542*, ISM-0312* | Detect firmware/boot tampering. | Design: **UEFI Secure Boot** + signed UKI (+ signed iPXE on the PXE path) + immutable signed cmdline + dm-verity; TPM measurements available. **Verified enforcing on real hardware (2026-06-22):** CI-signed UKI under SB on a VM (HTTP) and signed iPXE→UKI under SB on an 820 (PXE), `db` enrolled via `fleet-sb-enroll`. Residual is making signed + SB-on the standing default for all builds/hosts. | Implemented (default-posture residual) | **R-13** (not yet default), R-11 (no remote attestation) |
|
||||||
| Device identification | ISM-1195* | Uniquely identify devices. | Identity derived from TPM cert (hostnqn from cert serial); no spoofable per-host config. | Implemented | — |
|
| Device identification | ISM-1195* | Uniquely identify devices. | Identity derived from TPM cert (hostnqn from cert serial); no spoofable per-host config. | Implemented | — |
|
||||||
|
|
||||||
### 2.11 Guidelines for Procurement, Outsourcing & Evaluated Products
|
### 2.11 Guidelines for Procurement, Outsourcing & Evaluated Products
|
||||||
@@ -176,7 +178,7 @@ asked to accept. Treatments map to [docs/TODO.md](TODO.md) (working POA&M).
|
|||||||
| **R-05** | **NOPASSWD key-only admin**; no per-host or rotatable access model; human admin MFA on the mgmt plane not enforced. | 2.4 (ISM-1507*/1173*) | Possible × Moderate → **Medium** | Single fleet-generic admin, key-only, root disabled, ECDSA/RSA key, **now SELinux-confined to `staff_u`** with sudo role/type elevation, fully audited; no interactive password to attack. | Per-host/rotatable access (SSH CA / config-agent) + admin MFA on the management plane. | **Low–Medium** | Platform team — *roadmap* |
|
| **R-05** | **NOPASSWD key-only admin**; no per-host or rotatable access model; human admin MFA on the mgmt plane not enforced. | 2.4 (ISM-1507*/1173*) | Possible × Moderate → **Medium** | Single fleet-generic admin, key-only, root disabled, ECDSA/RSA key, **now SELinux-confined to `staff_u`** with sudo role/type elevation, fully audited; no interactive password to attack. | Per-host/rotatable access (SSH CA / config-agent) + admin MFA on the management plane. | **Low–Medium** | Platform team — *roadmap* |
|
||||||
| **R-06** | **FIPS off**; ISM **AACA/AACP conformance not formally asserted**; crypto-module evaluation status unconfirmed. | 2.9 (ISM-0471*/1139*/1277*) | Possible × Major → **Medium** | Modern STIG crypto policy; non-exportable TPM key; no deliberately weak algorithms. Acceptable at OFFICIAL; **mandatory to resolve for PROTECTED+.** | Assert AACA/AACP conformance; decide on FIPS module / evaluated crypto alongside Secure Boot signing. | **Low** (at appropriate classification) | Security + Platform — *before PROTECTED+* |
|
| **R-06** | **FIPS off**; ISM **AACA/AACP conformance not formally asserted**; crypto-module evaluation status unconfirmed. | 2.9 (ISM-0471*/1139*/1277*) | Possible × Major → **Medium** | Modern STIG crypto policy; non-exportable TPM key; no deliberately weak algorithms. Acceptable at OFFICIAL; **mandatory to resolve for PROTECTED+.** | Assert AACA/AACP conformance; decide on FIPS module / evaluated crypto alongside Secure Boot signing. | **Low** (at appropriate classification) | Security + Platform — *before PROTECTED+* |
|
||||||
| **R-07** | Audit-log **offload plaintext**, **single-site**, **no SIEM alerting**; logs interceptable/repudiable and not actively reviewed. (Transport **bench-verified working** 2026-06-20.) | 2.6 (ISM-1432*/0109*/0859*) | Possible × Moderate → **Medium** | Isolated LAN; disk-assisted queue (no loss on collector blip); auditd local copy; per-source files; LinuxAudit captures USBGuard events. | rsyslog **TLS** (gtls/6514) + bundle CA in image (re-select the 3 waived `rsyslog_encrypt_offload_*` rules); define retention + integrity; forward to SIEM with alerting. | **Low** | Platform/SecOps — *production* |
|
| **R-07** | Audit-log **offload plaintext**, **single-site**, **no SIEM alerting**; logs interceptable/repudiable and not actively reviewed. (Transport **bench-verified working** 2026-06-20.) | 2.6 (ISM-1432*/0109*/0859*) | Possible × Moderate → **Medium** | Isolated LAN; disk-assisted queue (no loss on collector blip); auditd local copy; per-source files; LinuxAudit captures USBGuard events. | rsyslog **TLS** (gtls/6514) + bundle CA in image (re-select the 3 waived `rsyslog_encrypt_offload_*` rules); define retention + integrity; forward to SIEM with alerting. | **Low** | Platform/SecOps — *production* |
|
||||||
| **R-13** | **Boot chain unsigned / Secure Boot OFF** in the lab — the UKI and (on the PXE path) iPXE are not signed and SB is not enforced, so a substituted boot artifact would not be rejected by firmware. | 2.10 (ISM-1542*/0312*) | Possible × Major → **Medium** | dm-verity still rejects a tampered *root*; isolated lab LAN; signing is **wired in CI** + key/enrolment procedure + baked `fleet-sb-enroll` ready; only the enforcement is pending. | Enrol fleet `db` (PK/KEK/db per [secure-boot-keys.md](secure-boot-keys.md)); set `SB_KEY`/`SB_CERT` CI secrets; `sbsign` the UKI **and** iPXE; enable Secure Boot on targets. | **Low** | Platform team — *before production* |
|
| **R-13** | **Boot-chain signing not yet the standing default** — signing + Secure Boot enforcement are **verified end-to-end on real hardware** (VM HTTP UKI 2026-06-20; 820 PXE signed iPXE→UKI 2026-06-22, SB enforcing, `db` enrolled), but unsigned/SB-OFF lab builds remain possible (CI signs only when `SB_KEY`/`SB_CERT` are set) and not every host has `db` enrolled, so a substituted artifact could still boot on an un-enrolled/unsigned host. | 2.10 (ISM-1542*/0312*) | Unlikely × Major → **Low** | Capability **proven on hardware**; dm-verity rejects a tampered *root* regardless; isolated lab LAN. | Make signed + Secure-Boot-on the **default for all production builds/hosts**: keep `SB_KEY`/`SB_CERT` CI secrets set; enrol `db` fleet-wide; treat an unsigned build as lab-only. | **Low** | Platform team — *before production* |
|
||||||
| **R-08** | **Placeholder RADIUS CA** (`files/etc/dot1x/radius-ca.pem`) — real EAP-TLS trust anchor not provisioned; auth cannot succeed and trust is unestablished. | 2.4 (ISM-1546*) | Certain (lab) × Major → **Medium** | Documented as a placeholder; environment-specific provisioning is the intended path; no real CA committed. | Provision the environment's real RADIUS CA out-of-band (not committed unless classification permits). | **Low** | Environment owner — *before production* |
|
| **R-08** | **Placeholder RADIUS CA** (`files/etc/dot1x/radius-ca.pem`) — real EAP-TLS trust anchor not provisioned; auth cannot succeed and trust is unestablished. | 2.4 (ISM-1546*) | Certain (lab) × Major → **Medium** | Documented as a placeholder; environment-specific provisioning is the intended path; no real CA committed. | Provision the environment's real RADIUS CA out-of-band (not committed unless classification permits). | **Low** | Environment owner — *before production* |
|
||||||
| **R-09** | **Host firewall disabled**; host exposes more network surface than necessary. | 2.7 (ISM-1416*) | Possible × Moderate → **Low–Medium** | Isolated LAN; minimal services; egress controlled at the network/serving layer; no kiosk inbound. | Re-enable firewalld with explicit allow rules (NVMe/TCP `:4420`, DHCP, log offload, SSH) once the secure path is verified. | **Low** | Platform/network — *after R-01* |
|
| **R-09** | **Host firewall disabled**; host exposes more network surface than necessary. | 2.7 (ISM-1416*) | Possible × Moderate → **Low–Medium** | Isolated LAN; minimal services; egress controlled at the network/serving layer; no kiosk inbound. | Re-enable firewalld with explicit allow rules (NVMe/TCP `:4420`, DHCP, log offload, SSH) once the secure path is verified. | **Low** | Platform/network — *after R-01* |
|
||||||
| **R-10** | **Patch SLA undefined** — no documented cadence for rebuilding/redeploying against new CVEs. | 2.5 (ISM-1144*/1472*) | Likely × Moderate → **Medium** | Atomic rebuild/redeploy model makes patching fast & uniform; reproducible builds. | Define patch cadence & critical-CVE SLA; automate rebuild triggers. | **Low** | Platform team — *roadmap* |
|
| **R-10** | **Patch SLA undefined** — no documented cadence for rebuilding/redeploying against new CVEs. | 2.5 (ISM-1144*/1472*) | Likely × Moderate → **Medium** | Atomic rebuild/redeploy model makes patching fast & uniform; reproducible builds. | Define patch cadence & critical-CVE SLA; automate rebuild triggers. | **Low** | Platform team — *roadmap* |
|
||||||
@@ -204,7 +206,9 @@ R-12 and R-13** (and confirming R-03's `enable_stig=true`) are **closed before
|
|||||||
production**, and R-04/R-05/R-06/R-07/R-09/R-10/R-11 are either accepted with
|
production**, and R-04/R-05/R-06/R-07/R-09/R-10/R-11 are either accepted with
|
||||||
compensating controls (isolated-LAN lab) or carried on the POA&M with target
|
compensating controls (isolated-LAN lab) or carried on the POA&M with target
|
||||||
dates. Newly strengthened in v0.2: device control (USBGuard, now Implemented),
|
dates. Newly strengthened in v0.2: device control (USBGuard, now Implemented),
|
||||||
admin SELinux confinement (R-05), and STIG applied+verified (R-03 reduced).*
|
admin SELinux confinement (R-05), STIG applied+verified (R-03 reduced), and
|
||||||
|
**Secure Boot signing verified enforcing on real hardware (R-13 reduced
|
||||||
|
Medium→Low)**.*
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -224,9 +228,11 @@ admin SELinux confinement (R-05), and STIG applied+verified (R-03 reduced).*
|
|||||||
anything flagged **REVIEW** is an unjustified finding.
|
anything flagged **REVIEW** is an unjustified finding.
|
||||||
6. **Confirm lab-only flags are off** in the assessed build: `debug_shell=false`,
|
6. **Confirm lab-only flags are off** in the assessed build: `debug_shell=false`,
|
||||||
`enable_stig=true`, `disable_dot1x=false`, real RADIUS CA in place.
|
`enable_stig=true`, `disable_dot1x=false`, real RADIUS CA in place.
|
||||||
7. **Confirm boot-chain signing is enforced** (R-13): `db` enrolled, Secure Boot
|
7. **Confirm boot-chain signing is the default** (R-13): signing + Secure Boot
|
||||||
ON, UKI + iPXE signed (`sbverify`). The PXE/iPXE path's SB-OFF cmdline
|
enforcement are **verified on hardware** (VM HTTP + 820 PXE, 2026-06-22) —
|
||||||
workaround should be a no-op once SB is on.
|
confirm the *assessed* build is signed and the *assessed* hosts have `db`
|
||||||
|
enrolled with Secure Boot ON (`mokutil --sb-state`, `sbverify` UKI + iPXE). The
|
||||||
|
PXE/iPXE SB-OFF cmdline workaround is a no-op once SB is on.
|
||||||
8. **Witness device control** (USBGuard): a USB mass-storage device is blocked and
|
8. **Witness device control** (USBGuard): a USB mass-storage device is blocked and
|
||||||
logged, console HID still works.
|
logged, console HID still works.
|
||||||
|
|
||||||
|
|||||||
+20
-16
@@ -16,9 +16,9 @@
|
|||||||
| System name | Diskless Fleet Boot System ("the fleet") |
|
| System name | Diskless Fleet Boot System ("the fleet") |
|
||||||
| Document type | System Security Plan (SSP) |
|
| Document type | System Security Plan (SSP) |
|
||||||
| Version | 0.2 (DRAFT — pre-assessment) |
|
| Version | 0.2 (DRAFT — pre-assessment) |
|
||||||
| Date | 2026-06-20 |
|
| Date | 2026-06-22 |
|
||||||
| Author / maintainer | System Owner (delegate) |
|
| Author / maintainer | System Owner (delegate) |
|
||||||
| Status | Lab / pre-production. STIG hardening applied + bench-verified (unsigned, Secure Boot OFF); secure path (802.1X/MACsec) not yet bench-verified. |
|
| Status | Lab / pre-production. STIG hardening applied + bench-verified; **UEFI Secure Boot signing verified enforcing on real hardware** (VM HTTP + EliteBook 820 PXE); secure path (802.1X/MACsec) not yet bench-verified. |
|
||||||
| Companion documents | [Annex A — ISM control cross-reference & residual risk](ssp-annex-a-ism-residual-risk.md); [Architecture design v2](diskless-fleet-design-v2.pdf); [Design errata](design-v2-errata.md); [STIG deviation register](stig-deviations.md); [Backlog / POA&M source](TODO.md) |
|
| Companion documents | [Annex A — ISM control cross-reference & residual risk](ssp-annex-a-ism-residual-risk.md); [Architecture design v2](diskless-fleet-design-v2.pdf); [Design errata](design-v2-errata.md); [STIG deviation register](stig-deviations.md); [Backlog / POA&M source](TODO.md) |
|
||||||
|
|
||||||
> **Currency caveat (read before relying on control numbers).** This SSP and its
|
> **Currency caveat (read before relying on control numbers).** This SSP and its
|
||||||
@@ -164,19 +164,23 @@ This system follows the ISM A&A lifecycle:
|
|||||||
Milestones (POA&M)** (this repo's [TODO.md](TODO.md) is the working POA&M
|
Milestones (POA&M)** (this repo's [TODO.md](TODO.md) is the working POA&M
|
||||||
source).
|
source).
|
||||||
|
|
||||||
**Current status:** Pre-assessment **DRAFT (v0.2)**. The system is functional in a
|
**Current status:** Pre-assessment **DRAFT (v0.2, updated 2026-06-22)**. The system
|
||||||
lab configuration. **Progress since v0.1 (2026-06-20):** DISA STIG hardening
|
is functional in a lab configuration. **Progress since v0.1 (2026-06-20):** DISA
|
||||||
applied and **bench-verified** on a real build (kiosk, key-only SSH, audit
|
STIG hardening applied and **bench-verified** on a real build (kiosk, key-only SSH,
|
||||||
offload, DHCP-named host, NVMe/verity root all good with hardening on); USBGuard
|
audit offload, DHCP-named host, NVMe/verity root all good with hardening on);
|
||||||
device control enabled + verified; admin confined to `staff_u`; UKI signing wired
|
USBGuard device control enabled + verified; admin confined to `staff_u`; and —
|
||||||
in CI + Secure Boot key/enrolment procedure documented; both **HTTP-boot and
|
newly — **UEFI Secure Boot signing verified enforcing end-to-end on real
|
||||||
PXE/iPXE** boot paths working (the latter verified on an EliteBook 820 G4).
|
hardware**: the CI-signed UKI boots under Secure Boot on a VM (HTTP boot), and the
|
||||||
Several controls remain **partial or deferred**, tracked as residual risks with
|
signed iPXE→UKI chain boots under Secure Boot on an EliteBook 820 G4 (PXE boot),
|
||||||
treatments (Annex A §3). The two largest gates on a production ATO: (a) the
|
with `db`/`KEK`/`PK` enrolled via the baked `fleet-sb-enroll` helper. Several
|
||||||
secure path (**802.1X/MACsec**) is implemented but **not yet bench-verified** and
|
controls remain **partial or deferred**, tracked as residual risks with treatments
|
||||||
is disabled in test builds (`disable_dot1x=true`, R-01); (b) the lab runs
|
(Annex A §3). The largest remaining gates on a production ATO: (a) the secure path
|
||||||
**unsigned with Secure Boot OFF** (R-13) and with a lab-only **passwordless-root
|
(**802.1X/MACsec**) is implemented but **not yet bench-verified** and is disabled
|
||||||
debug shell** that must be removed (R-02).
|
in test builds (`disable_dot1x=true`, R-01); (b) a lab-only **passwordless-root
|
||||||
|
debug shell** must be removed (R-02). Boot-chain signing / Secure Boot — a major
|
||||||
|
v0.1 gate — is now **demonstrated on hardware**; the residual (R-13) is reduced to
|
||||||
|
making signed + Secure-Boot-on the **standing default** for every production
|
||||||
|
host/build.
|
||||||
|
|
||||||
## 5. Security control implementation — by ISM cyber security principle
|
## 5. Security control implementation — by ISM cyber security principle
|
||||||
|
|
||||||
@@ -281,7 +285,7 @@ production ATO:
|
|||||||
| R-07 | Audit-log offload **plaintext** (bench-verified working), single-site, no SIEM alerting. | **Medium** | Treat — TLS offload + monitoring on roadmap. |
|
| R-07 | Audit-log offload **plaintext** (bench-verified working), single-site, no SIEM alerting. | **Medium** | Treat — TLS offload + monitoring on roadmap. |
|
||||||
| R-08 | **Placeholder RADIUS CA** in the repo; real trust anchor not yet provisioned. | **Medium** | Treat — environment-specific, before production. |
|
| R-08 | **Placeholder RADIUS CA** in the repo; real trust anchor not yet provisioned. | **Medium** | Treat — environment-specific, before production. |
|
||||||
| R-09 | Host **firewall disabled** (workstation). | **Low–Medium** | Accept (isolated LAN) / treat with explicit allow-rules. |
|
| R-09 | Host **firewall disabled** (workstation). | **Low–Medium** | Accept (isolated LAN) / treat with explicit allow-rules. |
|
||||||
| R-13 | **Boot chain unsigned / Secure Boot OFF** in the lab (UKI + iPXE); CI signing wired but not enforced. | **Medium** | Treat — enrol `db`, enforce SB + sign UKI & iPXE before production. |
|
| R-13 | **Boot-chain signing not yet the standing default.** Signing + Secure Boot enforcement **verified end-to-end on hardware** (VM HTTP UKI 2026-06-20; 820 PXE signed iPXE→UKI 2026-06-22), but unsigned/SB-OFF lab builds are still possible (CI signs only when `SB_KEY`/`SB_CERT` are set) and not all hosts have `db` enrolled. | **Low** | Treat — make signed + Secure-Boot-on the default for all production builds/hosts (set CI secrets; enrol `db` fleet-wide). |
|
||||||
|
|
||||||
Each is detailed, ISM-cross-referenced, rated and assigned a treatment in Annex A.
|
Each is detailed, ISM-cross-referenced, rated and assigned a treatment in Annex A.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user