NTS authenticated time is now bench-verified end-to-end unattended on a clean
build (comet-beacon-54, 5294860): chronyc -N authdata shows ntp.fleet.lab in NTS
mode with cookies > 0, sources read under enforcing SELinux, no lo.sources, no
manual step. This clears the two dispatcher-integration defects found on the way
(distro 20-chrony-dhcp clobber; /run/chrony-dhcp SELinux label).
Flips F-03/P-18 / R-17 from "bench-verify pending" to bench-verified in the SSP
status line + register and the Annex §2.9 control row + R-17 register + summary,
mirroring the F-02 treatment. Rated Low. Residual (defence-in-depth, not blocking):
issue the per-environment NTS server cert, and exercise the cold-clock
nocerttimecheck bootstrap + active-spoof rejection.
433 lines
32 KiB
Markdown
433 lines
32 KiB
Markdown
# System Security Plan (SSP) — Diskless Fleet Boot System
|
||
|
||
> **Protective marking:** `OFFICIAL: Sensitive` *(sample marking — set per the
|
||
> organisation's classification of the highest-sensitivity data the system
|
||
> handles; an SSP that describes the security architecture is normally marked at
|
||
> or one level above the system's data classification.)*
|
||
>
|
||
> **A&A framework:** Australian Government — Protective Security Policy Framework
|
||
> (PSPF) + ASD *Information Security Manual* (ISM). This document is the **System
|
||
> Security Plan** required by the ISM *Guidelines for cyber security
|
||
> documentation* and is the primary input to the IRAP security assessment and the
|
||
> Authorising Officer's authorisation (ATO) decision.
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| System name | Diskless Fleet Boot System ("the fleet") |
|
||
| Document type | System Security Plan (SSP) |
|
||
| Version | 0.4 (DRAFT — pre-assessment) |
|
||
| Date | 2026-07-11 |
|
||
| Author / maintainer | System Owner (delegate) |
|
||
| 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. **v0.3 adds the fleet-management plane** (on-host `fleet-agent` telemetry over TPM-mTLS — bench-verified on hardware 2026-07-10; server-side manager with **WebAuthn-passkey** admin MFA + TPM enrolment broker) and July hardening changes (three local SELinux modules; fapolicyd overlay exec-guard fix). **v0.4** adds two host-identity/time hardening features (both implemented 2026-07-11): broker-mediated **SSH host certificates** (F-02/P-17 — **bench-verified 2026-07-11** on `comet-beacon-54`, clean build `28d31e4`) and **NTS authenticated time** (F-03/P-18 — **bench-verified 2026-07-12** on `comet-beacon-54`, clean build `5294860`). |
|
||
| 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); [Fleet-management design](fleet-management-design.md); [TPM enrolment design](tpm-enrolment-design.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
|
||
> annex are drafted against the ISM structure as understood to a January 2026
|
||
> baseline. The engagement specifies the **May 2026 ISM**. The ISM is reissued on
|
||
> a quarterly cadence and **control identifiers are added, retired and
|
||
> renumbered between releases.** Every `ISM-NNNN` identifier in Annex A is
|
||
> therefore **representative and MUST be validated by the IRAP assessor against
|
||
> the actual May 2026 release** before the assessment is relied upon. The
|
||
> *intent* of each control mapping is stable; the *number* may not be.
|
||
|
||
---
|
||
|
||
## 1. Purpose and scope
|
||
|
||
This SSP describes the security architecture, the security controls implemented,
|
||
and the residual risk of the **Diskless Fleet Boot System** — a fleet of
|
||
diskless workstations that network-boot a signed, immutable operating system over
|
||
the wire and hold **no persistent local state**. It supports an Australian
|
||
**Assessment and Authorisation (A&A)** process: it is the document an IRAP
|
||
assessor evaluates to produce the Security Assessment Report (SAR), and that the
|
||
Authorising Officer (AO) uses to make a risk-based **Authority to Operate (ATO)**
|
||
decision.
|
||
|
||
**In scope:** the boot chain (UEFI HTTP boot → signed UKI → dracut initramfs →
|
||
network authentication → encrypted root mount → verified read-only OS), the
|
||
runtime workstation OS image, the host's cryptographic identity (TPM), the
|
||
hardening baseline applied to the image, and the **on-host `fleet-agent`** (the
|
||
in-image telemetry client that streams host health to the management plane over
|
||
TPM-mTLS — new in v0.3; `files/agent/`).
|
||
|
||
**Out of scope (separately authorised — connected systems):** the lab serving
|
||
stack (DHCP/HTTP/NVMe-oF target, audit collector — `serving/`); the **server-side
|
||
fleet-management plane** (`serving/fleet-manager/` — the control-plane hub, its
|
||
admin web UI, the InfluxDB metrics store, and the Traefik ingress); the **TPM
|
||
enrolment broker** (`serving/enrol-broker/`) and the **step-ca fleet certificate
|
||
authority** it signs against; the 802.1X authenticator/RADIUS infrastructure; the
|
||
network fabric; and physical security of the facility. These are dependencies the
|
||
host connects to and are described here where the host interacts with them, but
|
||
each carries its own security documentation and authorisation.
|
||
|
||
## 2. System description
|
||
|
||
### 2.1 Overview
|
||
|
||
Each host is **diskless**: it has no installed operating system and no writable
|
||
persistent storage that participates in identity. At power-on it performs UEFI
|
||
**HTTP boot**, fetches a **signed Unified Kernel Image (UKI)**, and assembles a
|
||
running system whose root filesystem is an **immutable, cryptographically
|
||
verified image mounted over the network**. All host identity is derived **at
|
||
runtime from a hardware Trusted Platform Module (TPM)**; nothing host-specific
|
||
exists in any build artifact.
|
||
|
||
A release is a **signed UKI** plus a root image, packaged together as a
|
||
**FROM-scratch OCI artifact image** and pinned by digest in a deployment
|
||
manifest. One commit = one release = one digest = one manifest entry.
|
||
|
||
### 2.2 Boot and trust chain (control flow)
|
||
|
||
> **Boot transport (two paths, auto-selected):** HTTP-boot-capable firmware
|
||
> fetches the UKI directly over UEFI HTTP boot. Firmware **without** HTTP boot
|
||
> (e.g. HP EliteBook 820 G4) falls back to **PXE → iPXE → HTTP** (dnsmasq serves
|
||
> iPXE over TFTP, which chainloads the same UKI). Both land on the same signed
|
||
> UKI. **Lab status:** Secure Boot is currently **OFF** and the UKI/iPXE are
|
||
> **unsigned** — signing is wired in CI and the key procedure is documented
|
||
> ([secure-boot-keys.md](secure-boot-keys.md)) but not yet enforced (residual
|
||
> R-03/signing in Annex A).
|
||
|
||
1. **UEFI Secure Boot** (when enabled) measures and verifies the UKI signature
|
||
against the enrolled `db` key before execution. On the PXE/iPXE path the iPXE
|
||
binary is likewise verified against `db`; only the fleet's own `db` need be
|
||
enrolled (no Microsoft CA / shim).
|
||
2. **UKI (systemd-stub)** carries the kernel, the `--no-hostonly` initramfs, and
|
||
an **immutable, signed kernel command line** (includes the dm-verity root
|
||
hash and STIG kernel parameters). No GRUB.
|
||
3. **Initramfs (dracut)** brings up the NIC and performs **802.1X EAP-TLS**
|
||
network authentication using a **private key held in the TPM** (persistent
|
||
handle `0x81000100`); the client certificate is read from TPM NV index
|
||
`0x01800100`.
|
||
4. On authorisation, **MACsec** is established on the access link (link-layer
|
||
encryption/integrity); the host then obtains an IP **on the MACsec interface**
|
||
via DHCP.
|
||
5. The host connects its **root over NVMe/TCP**, maps it through **dm-verity**
|
||
(block-level integrity against the signed root hash in the UKI cmdline), and
|
||
mounts the **erofs** read-only root.
|
||
6. A **tmpfs (RAM) volatile overlay** (`systemd.volatile=overlay`) provides the
|
||
writable layer. It is discarded at power-off — the host returns to a known,
|
||
verified state every boot.
|
||
7. `switch-root` into the real system; NetworkManager renews the DHCP lease so
|
||
the network-mounted root stays alive; the host derives its NVMe `hostnqn` from
|
||
the TPM certificate serial and (kiosk builds) launches the locked-down kiosk.
|
||
Early in the running system the host also (a) syncs **CA-authenticated time**
|
||
(NTS, RFC 8915 — the NTP source's TLS certificate is verified against the fleet
|
||
CA, so a DHCP/NTP/DNS spoofer can only DoS, never shift the clock) and (b) gets
|
||
its **per-boot SSH host key signed into an OpenSSH host certificate** by the
|
||
fleet SSH CA — brokered through the enrol-broker host plane over TPM-identity
|
||
mTLS — so administrators trust the fleet through a single `@cert-authority` line
|
||
instead of per-boot trust-on-first-use.
|
||
8. **Post-boot management (v0.3):** the hardened **`fleet-agent`** service dials
|
||
the management plane and identifies with the **same TPM key/cert** used for
|
||
802.1X and the NVMe `hostnqn` ("one identity, three stages"), streaming host
|
||
health over mTLS. It is telemetry-only in v1 — it receives desired-state /
|
||
commands but **only logs** them (no host mutation). It is a
|
||
**post-switch-root** component only (not in the initramfs).
|
||
|
||
### 2.3 Authorisation boundary
|
||
|
||
The authorisation boundary is the **running workstation host**: the UKI, the
|
||
initramfs and its custom 802.1X/MACsec dracut module, the verified erofs root,
|
||
the tmpfs overlay, the TPM-backed identity, the hardened OS configuration, and the
|
||
in-image **`fleet-agent`**. The boundary's external interfaces are: (a) the
|
||
**access link** (802.1X-controlled port, MACsec-encrypted); (b) the **NVMe/TCP**
|
||
root storage session; (c) **outbound audit log** forwarding; (d) the **kiosk
|
||
application** endpoint the browser renders; (e) the **boot transport** (UEFI HTTP
|
||
boot, or PXE/TFTP→iPXE) that delivers the UKI; (f) **USB/peripheral** ports, now
|
||
mediated by USBGuard (§5.2); and (g) the **management plane** — an *outbound-only*
|
||
mTLS gRPC session from `fleet-agent` to the fleet-manager (`manager.fleet.lab:9600`,
|
||
across the OPNsense L3 hop from the host VLAN to the management network; no inbound
|
||
host port), authenticated with the host's TPM identity cert. Each crossing is a
|
||
control point addressed in Annex A.
|
||
|
||
### 2.4 Data and classification
|
||
|
||
- **Data at rest in the artifact:** none that is host-specific or sensitive. The
|
||
image is generic to the whole fleet by design (Architecture invariant #1 — *no
|
||
per-host state in any artifact, ever*).
|
||
- **Host identity / key material:** the EAP-TLS private key **never leaves the
|
||
TPM**; the certificate is read from TPM NV. Signing keys for the UKI are
|
||
CI/HSM-held and **never enter the build VM or the repository**.
|
||
- **Data in transit:** access link protected by **MACsec**; NVMe/TCP root and
|
||
audit-log offload currently **plaintext on an isolated lab LAN** (see residual
|
||
risk R-04, R-07 in Annex A). The **management-plane** telemetry stream is
|
||
**mTLS-encrypted** (fleet CA) end-to-end — unlike the NVMe/audit hops, it is not
|
||
plaintext. **NTP is now NTS-authenticated** (RFC 8915) — the time source's TLS
|
||
certificate is verified against the fleet CA, so the host clock cannot be spoofed
|
||
(F-03). Administrative **SSH host identity** is asserted by a **fleet-SSH-CA
|
||
certificate** (broker-signed at boot), replacing per-boot trust-on-first-use
|
||
(F-02).
|
||
- **Management telemetry (v0.3):** the agent sends host **health** (load/cpu/temp/
|
||
memory/tmpfs, uptime, NVMe-root state, 802.1X/MACsec + SELinux state, chrony
|
||
clock health, kiosk state) and **inventory facts** (image version, kernel,
|
||
cert-serial). This is **operational metadata, not user data**, and it carries **no
|
||
per-host secret** (identity is the reused TPM cert; the private key never leaves
|
||
the TPM). It is retained server-side (InfluxDB) — a **connected-system**
|
||
responsibility (see §1, R-14).
|
||
- **Data at rest in the overlay:** ephemeral, RAM-only, discarded at power-off.
|
||
|
||
The **system's data classification governs this SSP's marking and the required
|
||
ISM control set.** The classification of the data rendered by the kiosk
|
||
application and accessible from the workstation must be confirmed with the System
|
||
Owner; this draft assumes an **OFFICIAL / OFFICIAL: Sensitive** working
|
||
classification and should be re-baselined if the system processes PROTECTED or
|
||
above (which raises additional ISM control obligations, e.g. ASD-approved
|
||
cryptography enforcement, gateway controls, and stricter media handling).
|
||
|
||
## 3. Security governance and A&A roles
|
||
|
||
| Role | Responsibility (PSPF/ISM) | Assignment |
|
||
|---|---|---|
|
||
| **Authorising Officer (AO)** | Accepts residual risk; grants/denies/revokes the ATO. | *TBA — appoint before assessment* |
|
||
| **System Owner** | Accountable for the system's security posture and this SSP. | *TBA* |
|
||
| **Chief Information Security Officer (CISO)** | Organisational cyber security oversight; advises the AO. | *TBA* |
|
||
| **IRAP Assessor** | Independent assessment of control implementation effectiveness; produces the SAR. | *Engaged for assessment* |
|
||
| **System Manager / Administrators** | Day-to-day operation, patching, incident response, continuous monitoring. | Fleet platform team |
|
||
| **Build / release pipeline owner** | Integrity of the CI build, signing, and digest-pinned deployment. | Fleet platform team |
|
||
|
||
## 4. A&A process and status
|
||
|
||
This system follows the ISM A&A lifecycle:
|
||
|
||
1. **Define** the system, its boundary and data classification (this SSP §2).
|
||
2. **Select** the applicable ISM controls (Annex A, driven by classification).
|
||
3. **Implement** the controls (this SSP §5–§6; the codebase is the implementation
|
||
of record).
|
||
4. **Assess** — IRAP assessor evaluates effectiveness → **Security Assessment
|
||
Report (SAR)**.
|
||
5. **Authorise** — AO weighs residual risk (Annex A risk register) → **ATO**.
|
||
6. **Monitor** — continuous monitoring and a maintained **Plan of Action &
|
||
Milestones (POA&M)** (this repo's [TODO.md](TODO.md) is the working POA&M
|
||
source).
|
||
|
||
**Current status:** Pre-assessment **DRAFT (v0.3, updated 2026-07-10)**. The system
|
||
is functional in a lab configuration.
|
||
|
||
**Progress since v0.2 (2026-07-10):** the **fleet-management plane** was built and,
|
||
on the host side, **bench-verified end-to-end on real hardware** (`comet-beacon-54`):
|
||
the in-image **`fleet-agent`** streams health to the server over **mTLS using the
|
||
reused TPM identity** (telemetry-only — desired-state/commands are received but only
|
||
logged, zero host mutation). The server-side manager adds a **WebAuthn-passkey**
|
||
(phishing-resistant, origin-bound) admin plane — the first **human-admin MFA** on the
|
||
management plane — and a **TPM enrolment broker** (unauthenticated pre-auth CSR → OOB
|
||
fingerprint → admin-mTLS approve → step-ca sign) that births the per-host inventory
|
||
record. Its server-side server cert now **auto-renews** from the co-located CA. Host
|
||
hardening also advanced: **three local SELinux policy modules** were added (all
|
||
documented deviations — [stig-deviations.md](stig-deviations.md) #14–16), and a
|
||
**material fapolicyd finding was fixed (2026-07-04)** — the app-allow-listing exec
|
||
guard was effectively *inactive on the overlay root* (`overlay` missing from
|
||
`watch_fs`) and is now enforcing across the whole root (see §5.2). The server-side
|
||
plane (manager/broker/InfluxDB/step-ca) is a **connected system** pending its own
|
||
authorisation (R-14).
|
||
|
||
**Progress since v0.1 (2026-06-20):** DISA
|
||
STIG hardening applied and **bench-verified** on a real build (kiosk, key-only SSH,
|
||
audit offload, DHCP-named host, NVMe/verity root all good with hardening on);
|
||
USBGuard device control enabled + verified; admin confined to `staff_u`; **UEFI
|
||
Secure Boot signing verified enforcing end-to-end on real hardware** (CI-signed UKI
|
||
under SB on a VM/HTTP, and the signed iPXE→UKI chain under SB on an EliteBook 820
|
||
G4/PXE, with `db`/`KEK`/`PK` enrolled via `fleet-sb-enroll`); and — newly — a
|
||
**Wazuh SIEM** (dedicated multi-node, agentless) ingesting the fleet auditd stream
|
||
with a custom decoder/rules, **decode + alert bench-verified 2026-06-27**, lifting
|
||
the "Detect" pillar from log-collection-only to analysis + alerting. Several
|
||
controls remain **partial or deferred**, tracked as residual risks with treatments
|
||
(Annex A §3). The largest remaining gates on a production ATO: (a) the secure path
|
||
(**802.1X/MACsec**) is implemented but **not yet bench-verified** and is disabled
|
||
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
|
||
|
||
The ISM organises controls under four principles: **Govern, Protect, Detect,
|
||
Respond.** Annex A gives the line-by-line control cross-reference; this section
|
||
summarises the implementation posture.
|
||
|
||
### 5.1 Govern
|
||
- Documented architecture (design v2 + errata), enforced **architecture
|
||
invariants** ([CLAUDE.md](../CLAUDE.md)), and a maintained backlog/POA&M.
|
||
- Reproducible, **digest-pinned** releases; one release = one digest = one
|
||
manifest commit; rollback = revert the commit.
|
||
- Signing keys held outside the repo and build VM (CI/HSM).
|
||
- *Gaps:* formal SRMP, IRP, and continuous-monitoring plan to be authored;
|
||
A&A roles to be appointed (§3).
|
||
|
||
### 5.2 Protect
|
||
- **Identity & authentication:** mutual **802.1X EAP-TLS** with a
|
||
**non-exportable TPM key**; network access controlled at the switch port. The
|
||
**management-plane agent reuses the same TPM identity** for mTLS to the
|
||
fleet-manager (one non-exportable key backs 802.1X, the NVMe `hostnqn`, and the
|
||
agent stream — "one identity, three stages"), and the server keys inventory off
|
||
the verified cert serial, so a host can only ever report as itself.
|
||
- **Management-plane admin MFA (v0.3):** the server-side admin web UI enforces
|
||
**WebAuthn passkeys** — phishing-resistant, origin-bound, hardware-backed
|
||
MFA — behind a Traefik ingress that terminates a Let's Encrypt cert (DNS-01).
|
||
This is the first human-admin MFA in the system (the manager/broker admin planes
|
||
are a **connected system**, but the control is noted here as it closes the
|
||
long-standing "no admin MFA" gap for management operations; host SSH admin
|
||
remains key-only — R-05).
|
||
- **Link protection:** **MACsec** on the access link.
|
||
- **Authenticated time (NTS — v0.4):** chrony syncs only from an **NTS** (RFC 8915)
|
||
source whose NTS-KE TLS certificate is **fleet-CA-signed** (verified against the
|
||
same `radius-ca.pem` the host already trusts). The server name is derived at
|
||
runtime from the DHCP domain (`ntp.<domain>` — no baked FQDN, so a site-domain
|
||
change needs no rebuild), and the unauthenticated DHCP option-42 source is **not**
|
||
mixed in. A DHCP/NTP/DNS spoofer can therefore only cause **no-sync (DoS)**, never
|
||
shift the clock — closing the "unauthenticated time feeds every certificate-
|
||
validity decision" gap (F-03/P-18). `nocerttimecheck 1` lets an RTC-less cold boot
|
||
bootstrap the first measurement. Toggle `secure_ntp` (default true).
|
||
- **Boot & OS integrity:** **Secure Boot** + **signed UKI** with an **immutable
|
||
cmdline**; **dm-verity** read-only root (continuous cryptographic integrity);
|
||
**erofs** immutable filesystem; **reproducible** build (verity hash is a pure
|
||
function of inputs). Signing is **wired in CI** (`sbsign`/ukify via
|
||
`SB_KEY`/`SB_CERT` secrets) with a documented PK/KEK/db key + enrolment
|
||
procedure ([secure-boot-keys.md](secure-boot-keys.md)) and a baked, efitools-free
|
||
enrolment helper (`fleet-sb-enroll`); **not yet enforced in the lab** (SB OFF,
|
||
unsigned — see Annex A).
|
||
- **System hardening (DISA STIG applied + bench-verified 2026-06-20):** STIG
|
||
baseline via OpenSCAP/SSG with a documented tailoring + per-build deviations
|
||
report; all REVIEW rows triaged. **SELinux enforcing**; **fapolicyd**
|
||
application allow-listing (the exec guard for the writable RAM overlay dm-verity
|
||
cannot cover); **USBGuard enforcing** (`ImplicitPolicyTarget=block` + a
|
||
hardware-independent HID/hub allowlist + LinuxAudit — verified blocks USB mass
|
||
storage while keeping console input; device/removable-media control); **key-only
|
||
SSH**, root login disabled, hardened ciphers/MACs/KEX (note: STIG crypto policy
|
||
drops ed25519 → admin key must be ECDSA/RSA); **kiosk lockdown** (single locked
|
||
browser, no shell/navigation); **postfix removed** (no local MTA — audit-failure
|
||
notification rides the remote offload, not email). Three **local SELinux policy
|
||
modules** are shipped for architecture-specific allows, each a documented
|
||
deviation ([stig-deviations.md](stig-deviations.md) #14–16): `chrony_dhcp_dispatcher`
|
||
(NM-dispatcher chrony reload), `fapolicyd_tmpfs` (statfs the overlay upper), and
|
||
`fleet_agent_chronylog` (agent reads chrony's tracking log). No blanket
|
||
permissive domains; SELinux stays enforcing.
|
||
- **Application-control effectiveness fix (2026-07-04):** a bench finding showed
|
||
fapolicyd's exec guard was **effectively inactive on the root** — the diskless
|
||
root is `overlayfs`, which was **absent from fapolicyd's `watch_fs`**, so
|
||
fapolicyd marked no mounts and intercepted no exec on `/`, `/usr` or `/tmp`.
|
||
Adding `overlay` to `watch_fs` turned app-allow-listing **on for the whole
|
||
overlay root for the first time** — verified: a novel non-RPM binary in `/tmp`
|
||
is now denied (`FAN_DENY`), nothing legitimate broke. (Residual: path-based trust
|
||
doesn't catch a *modified trusted path* via copy-up — tracked as TODO #15 /
|
||
the `integrity=sha256` option — noted in stig-deviations #15.)
|
||
- **Privileged access:** single **key-only `wheel` admin**, root locked. The admin
|
||
is now **confined to the `staff_u` SELinux user** with a sudoers role/type
|
||
transition (`sysadm_r`/`sysadm_t`) so privilege elevation re-labels the SELinux
|
||
context (STIG `selinux_context_elevation_for_sudo`). Still **NOPASSWD** (the
|
||
account is passwordless/key-only) and fleet-generic — see R-05.
|
||
- **Administrative host-key trust (SSH host certificates — v0.4):** because the
|
||
overlay is ephemeral, sshd host keys are new every boot; rather than perpetual
|
||
trust-on-first-use, each host at boot gets its **per-boot host key signed into an
|
||
OpenSSH host certificate by the fleet SSH CA**, brokered through the
|
||
**enrol-broker host plane** over **TPM-identity mTLS** (the same non-exportable
|
||
TPM key that backs 802.1X and the NVMe `hostnqn`). Admins add **one
|
||
`@cert-authority` line** and thereafter verify every host against the fleet SSH
|
||
CA — no per-boot key pinning, and a LAN MITM of admin SSH becomes
|
||
client-detectable. step-ca stays behind the broker's single front door; the
|
||
client **fails open** to a bare (TOFU) key if the broker/CA is unreachable, so it
|
||
cannot brick admin access. Closes F-02/P-17. Toggle `enable_ssh_hostcert`
|
||
(default true).
|
||
- **No persistent attack surface:** diskless; overlay discarded each boot; no
|
||
per-host secrets in the image.
|
||
- *Gaps / decisions:* **FIPS OFF** (lab phase); **host firewall disabled** (the
|
||
workstation; the serving host's ufw is configured); NVMe/TCP and audit offload
|
||
**plaintext on the isolated LAN**; NOPASSWD admin; **placeholder RADIUS CA**;
|
||
signing not yet enforced (SB OFF). See Annex A residual risks.
|
||
|
||
### 5.3 Detect
|
||
- **auditd** enabled with STIG audit rules; kernel `audit=1` +
|
||
`audit_backlog_limit` in the signed cmdline. USBGuard device events logged via
|
||
the LinuxAudit backend. auditd `space_left_action` repointed to **syslog**
|
||
(no local MTA), so audit-volume alerts ride the remote offload.
|
||
- **Centralised log offload** via rsyslog (`audisp-syslog` → rsyslog `omfwd`,
|
||
disk-assisted queue) to a dedicated **audit collector** (`serving/audit-collector/`).
|
||
**Bench-verified end-to-end 2026-06-20** (records reach the collector,
|
||
per-source-host files).
|
||
- **SIEM analysis + alerting (Wazuh)** — the collector **relays** the auditd
|
||
stream to a **dedicated multi-node Wazuh** instance (`wazuh1.bitasylum.org`);
|
||
ingestion is **agentless** (no agent/state in the diskless image, invariant #1).
|
||
A custom **`fleet-auditd`** decoder + rules handle the STIG `name_format=hostname`
|
||
(`node=` prefix) and surface events in the `fleet_audit` group with severity by
|
||
type (auth, privilege/`USER_CMD`, SELinux/AVC). **Decode + alert bench-verified
|
||
2026-06-27** (`wazuh-logtest` + a live `sudo` surfacing `USER_CMD`/`CRED_*` in
|
||
the dashboard). Config is declarative (`serving/siem/`, mounted via
|
||
`/wazuh-config-mount`).
|
||
- **Fleet health telemetry (v0.3):** the `fleet-agent` streams host health
|
||
(resource pressure, NVMe-root/auth/SELinux/chrony/kiosk state, uptime) to the
|
||
manager over mTLS; the manager persists a time-series (InfluxDB) and flags
|
||
version-drift, SELinux-permissive, and reboot-pending in an admin dashboard. This
|
||
is an **operational-health** signal (complements the auditd/Wazuh **security-event**
|
||
path — different purpose, different data): e.g. a host reporting `SELinux:
|
||
permissive` or overlay RAM exhaustion is surfaced for the operator. The store and
|
||
dashboard are a **connected system** (server-side); the host-side contribution is
|
||
the read-only probe + mTLS stream.
|
||
- *Gaps:* both audit-offload hops (host→collector, collector→Wazuh) currently
|
||
**plaintext** (TLS planned, R-07); **log retention/archival** (ISM) not yet
|
||
configured; default Wazuh credentials to be rotated before production.
|
||
|
||
### 5.4 Respond
|
||
- Known-good recovery is **inherent**: a host returns to a verified state on
|
||
reboot; a bad release is rolled back by reverting one manifest commit (digest
|
||
pin).
|
||
- *Gaps:* formal **Incident Response Plan**, log-retention policy, and
|
||
break-glass/forensics procedure (the diskless model complicates live forensics
|
||
— RAM overlay is volatile) to be authored.
|
||
|
||
## 6. Essential Eight alignment (indicative)
|
||
|
||
The Essential Eight is mitigation guidance, not a substitute for the ISM, but the
|
||
AO will expect a maturity view:
|
||
|
||
| Mitigation | Posture | Notes |
|
||
|---|---|---|
|
||
| Application control | **Strong** | fapolicyd allow-listing + immutable verified root; only RPM-trusted (plus two trusted local binaries: kiosk-session, fleet-sb-enroll) executables run. USBGuard enforces device control on USB ports. |
|
||
| Patch applications | **Process** | Patching = rebuild + re-sign + redeploy a new digest; cadence/SLA to be defined. |
|
||
| Configure MS Office macros | **N/A** | No office suite; kiosk is a locked browser. |
|
||
| User application hardening | **Strong (kiosk)** | Chromium locked down via enterprise policy; no plugins/shell/nav. |
|
||
| Restrict admin privileges | **Partial** | Single key-only `wheel` admin, root locked, now **SELinux-confined to `staff_u`** with a sudo role/type transition (NOPASSWD, see R-05); **management-plane** admin actions now require a **WebAuthn passkey** (v0.3). Still no per-host/rotatable *host* access model. |
|
||
| Patch operating systems | **Process** | Same rebuild/redeploy model; immutable image means uniform, atomic OS updates. |
|
||
| Multi-factor authentication | **Strong (machine) + admin passkey** | Host auth is certificate + TPM-bound key (something-the-machine-has, non-exportable). **Human admin MFA is now enforced on the management-plane UI via WebAuthn passkeys** (phishing-resistant, origin-bound) — v0.3. Host SSH admin remains key-only (no separate human MFA — R-05). |
|
||
| Regular backups | **N/A (by design)** | Diskless, stateless hosts hold nothing to back up; recoverability is re-provisioning from a pinned digest. Backup applies to serving-side state, out of scope here. |
|
||
|
||
## 7. Residual risk summary
|
||
|
||
The full residual-risk register is **[Annex A §3](ssp-annex-a-ism-residual-risk.md#3-residual-risk-register)**.
|
||
The headline residual risks the AO must explicitly accept or treat before a
|
||
production ATO:
|
||
|
||
| ID | Residual risk | Rating (pre-treatment) | Disposition |
|
||
|---|---|---|---|
|
||
| R-01 | Secure path (802.1X/MACsec) not yet bench-verified; currently disabled in test builds. | **High** | Treat — verify before production authorisation. |
|
||
| R-02 | ~~`debug_shell=true` bakes a **passwordless root shell** on a tty.~~ **Removed 2026-07-11** (`poam-hardening`): the `debug_shell` variable and its provisioner were deleted from the template — no build can bake a debug shell. | **High → residual Low** | **Remediated** — assessor to verify absence on the assessed digest (POA&M P-02 M2). |
|
||
| R-03 | STIG hardening **applied + bench-verified** (2026-06-20); `enable_stig=true` is now **enforced by Packer variable validation** and CI fails closed on unsigned/placeholder-CA builds (2026-07-11). Residual: signing/SB must be confirmed on the *assessed* digest. | **Medium** | Treat — confirm signed + `enable_stig=true` on the assessed build (P-03/P-04/P-05). |
|
||
| R-04 | NVMe/TCP root traffic **plaintext** on the lab LAN. | **Medium** | Accept (isolated LAN) / treat for production. |
|
||
| R-05 | NOPASSWD key-only **host** admin (now `staff_u`-confined); no per-host/rotatable access model. (Management-plane admin MFA now enforced via WebAuthn passkeys — v0.3.) | **Medium** | Accept with compensating controls / roadmap. |
|
||
| R-06 | **FIPS off**; ASD-approved-cryptography conformance not yet asserted. | **Medium** | Treat — required for PROTECTED+; revisit with signing. |
|
||
| R-07 | Audit-log offload **plaintext** on both hops (host→collector, collector→Wazuh); **log retention not yet configured**. SIEM **analysis + alerting now in place** (Wazuh, decode+alert bench-verified 2026-06-27). | **Low–Medium** | Treat — TLS both hops + ISM retention/archival + rotate Wazuh creds 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-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). |
|
||
| R-14 | **Management/enrolment plane is a connected system, built but not yet separately authorised.** The host now trusts + streams to the fleet-manager and enrols via the broker/**step-ca fleet CA** (a new trust anchor + key material) whose one **unauthenticated pre-auth CSR endpoint** is a new server-side surface. Host-side exposure is limited (outbound-only mTLS, read-only telemetry, commands logged-not-applied in v1). | **Medium** | Treat — separate SSP/authorisation for the management plane (CA key protection, broker endpoint hardening, InfluxDB token/data, admin-plane exposure). |
|
||
| R-15 | **Deferred agent reconcile actuators.** v1 receives `DesiredState`/`Command` but only logs them; when actuation (apply kiosk_url / reboot / drain) is built, the agent becomes a **remote host-mutation channel** needing re-assessment. | **Low** (v1) | Treat at build time — assess the command/authZ path before enabling actuators. |
|
||
| R-16 | Per-boot SSH host keys made admin SSH perpetual **TOFU** (LAN MITM client-undetectable). **Remediated 2026-07-11**: broker-mediated **SSH host certificates** (`enable_ssh_hostcert=true`) — per-boot key signed by the fleet SSH CA via the enrol-broker host plane (TPM-mTLS); admins trust one `@cert-authority` line. **Bench-verified 2026-07-11 on clean build `28d31e4`** (comet-beacon-54: FQDN login by name, no TOFU, **survives reboot unattended**; SELinux clean). | **Low** | Treat — roll the `@cert-authority` anchor to admins; broker-side principal validation is a defence-in-depth TODO (F-02/P-17). |
|
||
| R-17 | Time source was **unauthenticated** (DHCP-handed NTP) — the clock feeds every certificate-validity decision. **Remediated 2026-07-11**: **NTS** (RFC 8915, `secure_ntp=true`) — fleet-CA-signed NTS-KE cert verified against `radius-ca.pem`; server name derived from the DHCP domain (no baked FQDN); a spoofer can only DoS. **Bench-verified 2026-07-12 on clean build `5294860`** (comet-beacon-54: `chronyc authdata` NTS, cookies > 0, unattended on a clean boot, sources read under enforcing SELinux). | **Low** | Treat — issue the per-env NTS cert; cold-clock (`nocerttimecheck`) + active-spoof rejection remain as defence-in-depth bench items (F-03/P-18). |
|
||
|
||
Each is detailed, ISM-cross-referenced, rated and assigned a treatment in Annex A.
|
||
|
||
## 8. Continuous monitoring and maintenance
|
||
|
||
- **Build-time assurance:** every release is reproducible (verity hash verified
|
||
stable across two builds), the UKI/rootfs roothash coupling is a hard CI gate,
|
||
and the STIG scan publishes a report + a deviations register per build.
|
||
- **Runtime monitoring:** auditd + centralised log offload; host returns to a
|
||
verified state each boot.
|
||
- **POA&M:** [docs/TODO.md](TODO.md) is the live working POA&M; items feed Annex A
|
||
treatments. The SSP and Annex A are re-baselined at each material architecture
|
||
change and at each scheduled A&A review.
|
||
|
||
---
|
||
|
||
*End of SSP. See [Annex A](ssp-annex-a-ism-residual-risk.md) for the ISM control
|
||
cross-reference and the full residual-risk register.*
|