-
Notifications
You must be signed in to change notification settings - Fork 1
System supply chain
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 sudoLike 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 prefixsudo—fettlelives in~/.local/bin, which isn't on root'sPATH. fettle elevates itself, so plainfettle sys-audit …works. (If you wantsudo fettleto 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.
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