Skip to content

System supply chain

Paul Asadoorian edited this page Aug 12, 2026 · 2 revisions

System supply-chain — sys-audit

The seam with compromise-check: this action judges Secure Boot posture; the compromise check reads the same state and only states it, as the context its boot-chain findings need. A clean bootloader configuration on a machine where nothing verifies the bootloader proves much less than it looks like it does, so neither result should be read without the other.

A port of the Eclypsium firmware/boot-chain cheat-sheet. Most checks need root, so chipsec is configured, not auto-detected. It ships as a git checkout (python3 /opt/chipsec/chipsec_main.py), as a distro package (/usr/bin/chipsec_main), and as a pip entry point wherever that interpreter keeps scripts — three layouts whose invocations differ, so a path alone would not be enough. fettle used to search only for the checkout and reported "not found" on a machine where chipsec was installed and working. Set it once:

[secure]
chipsec_cmd = ["/usr/bin/chipsec_main"]
# ...or, for a git checkout:  ["python3", "/opt/chipsec/chipsec_main.py"]

Unset, the firmware category says plainly that it did not run, and names the setting.

It runs chipsec's whole default set (~33 modules, ~5s), not a hardcoded pair. fettle used to run exactly common.me_mfg_mode and common.bios_wp, chosen when the only target was Intel — and on an AMD workstation both are NOT APPLICABLE, so the check produced nothing while the default set found an unprotected flash and Secure Boot disabled. chipsec decides what applies to your platform better than a fixed list can. Results are read from its JSON output, not scraped from its prose.

"Not applicable" is reported as a coverage gap, not a pass. On a platform chipsec does not recognise — an AMD Ryzen here — 26 of 33 modules had no register definitions to work from, and fettle says so and marks the remaining verdicts provisional:

! Platform: chipsec does NOT recognise this platform — every verdict below is
  provisional, and the checks it skipped were skipped for want of register
  definitions, not because they passed
✗ common.rom_armor: FAILED
! common.secureboot.variables: warning
  Chipsec modules: 33 run — 2 passed, 26 not applicable

chipsec loads its own kernel driver (modprobe chipsec) to read MSRs, PCI config space and SPI. Setting chipsec_cmd is what opts you in.

Exit status: 1 when the scan found something needing attention, 0 otherwise — so it is usable in cron and CI. A warning (Secure Boot disabled, no TPM, an optional tool absent) does not fail the run: those are facts about the machine you may have chosen. A check that ran and failed, or integrity that does not verify, does.

sys-audit elevates itself (prompting for sudo) — just run fettle sys-audit, no sudo prefix needed. Pass --user to stay unprivileged (partial results).

fettle sys-audit --list              # list categories (no elevation)
fettle sys-audit --all               # run everything (prompts for sudo)
fettle sys-audit secureboot tpm      # run specific categories
fettle sys-audit -v microcode        # verbose (raw tool output)
fettle sys-audit --user hardware     # run as your user, no sudo

Like the other checks, a local scan saves a report to ~/.fettle/reports/<host>/sys-audit-<ts>.{txt,json}, so it appears in fettle report (see HTML report); a sys-audit remote <host> scan fetches its report back to the controller. Run with sudo/--all for the fullest results — many checks only produce real output as root.

sudo: fettle: command not found? Don't prefix sudofettle lives in ~/.local/bin, which isn't on root's PATH. fettle elevates itself, so plain fettle sys-audit … works. (If you want sudo fettle to work, also symlink it onto a system path: sudo ln -sf ~/src/fettle/bin/fettle /usr/local/bin/fettle.)

Category Checks
secureboot Secure Boot state + the 2026 Microsoft cert-expiry matrix (2011 vs 2023 KEK/db certs, migration status)
bios BIOS/UEFI vendor, version, date; motherboard info
firmware chipsec's full default module set — SPI/BIOS write protection, SMM, Secure Boot variables, ROM Armor, debug interfaces, and ~25 more (needs [secure] chipsec_cmd + root)
fwupd firmware devices, available updates, HSI security attributes
intel-me MEI device, ME firmware version, ME PCI controller
microcode CPU microcode revision + /sys vulnerability mitigations
tpm TPM device, version, DMI info, TPM2 capabilities
hardware inxi/lspci hardware inventory, memory modules
storage per-device model / firmware / serial via smartctl

A check that could not run says so. Several verdicts are derived from a tool's output, so fettle distinguishes three outcomes: a real result; UNKNOWN — <tool> failed (an error, because a security check that didn't run is a finding, not a pass); and a neutral Unknown when the tool ran fine but reported no verdict — e.g. a chipsec module that doesn't apply to your hardware, which shouldn't be red. Likewise the Secure Boot certificate matrix skips rather than reporting "Not present" when a UEFI variable can't be read, since absent and unreadable are not the same thing.

Remote scanning

Scan a host over SSH without installing anything on it. fettle builds a single-file zipapp of itself (pure stdlib → runs under any python3), scps it to the target, runs it over ssh -t, and cleans up — preserving the remote exit code. The target only needs a python3 interpreter; the scanner doesn't read the TOML config, so it runs fine on older Pythons (e.g. Ubuntu 22.04's 3.10, which has no tomllib).

fettle sys-audit remote server1 all               # host from ~/.ssh/config
fettle sys-audit remote --sudo admin@host2 tpm    # prompt once for remote sudo
fettle sys-audit remote -v gateway secureboot     # -v forwarded to the remote run

Clone this wiki locally