[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C2EEQYQ4H4TA25RMPVS67P":3,"skill-same:01M6C2EEQYQ4H4TA25RMPVS67P":82},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":57,"ownerHtmlUrl":58,"ownerBlogUrl":59,"ownerDescription":60,"updatedAt":61,"install":62,"resources":75},"01M6C2EEQYQ4H4TA25RMPVS67P","chain-of-trust-design",null,"Decision aid for bootstrap and verification chains — forces the 'what authenticates the authenticator' question; patterns for signed bootstrap, measured boot, recovery.","jmagly\u002Faiwg","jmagly","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1159087?v=4","01M6C10AK8N2WCSQN11FYGTJWN","Joseph Magly","01M6C10AQ8A2RMED1Y1BSVY7NF",229,"MIT","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fchain-of-trust-design\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43],"design","chain of trust design","trust","chain","boot","bootstrap","verification","recovery","decision","question","patterns","for","2026-11-10 10:12:30",false,"---\nnamespace: aiwg\nname: chain-of-trust-design\nplatforms: [all]\ndescription: \"Decision aid for bootstrap and verification chains — forces the 'what authenticates the authenticator' question; patterns for signed bootstrap, measured boot, recovery.\"\n\n---\n\n# chain-of-trust-design\n\nDecision aid for the integrity chain that protects a system from first byte executed to first secret derived. Use this skill when designing or reviewing any system that has a \"boot\" step, an \"unlock\" step, or a \"first run\" step where code outside your trust boundary must be trusted to load code inside it.\n\nThe skill exists to force the question almost everyone forgets: **what authenticates the code that authenticates everything else?**\n\n## Triggers\n\nPrimary phrases match automatically. Alternates:\n\n- \"bootstrap signing\" \u002F \"signed bootstrap\"\n- \"evil maid\" \u002F \"physical access attacker\"\n- \"measured boot\" \u002F \"TPM attestation\"\n- \"verify the verifier\"\n- \"unsigned scripts\" \u002F \"is this script trusted\"\n- \"first-run integrity\"\n- \"USB boot integrity\"\n\n## When NOT to use this skill\n\n- Networked TLS chain-of-trust (different domain — use a peer-reviewed PKI design)\n- Code-signing for application updates *after* boot (use Sigstore, signify, or platform store; this skill is about the layer below)\n- Software-supply-chain trust *upstream* of build (handled by `supply-chain-trust` skill — Tier 2)\n\n---\n\n## Section 1: The core question\n\nEvery system that processes secrets has a chain of code, where each link must trust the previous one. The chain typically looks like:\n\n```\nfirmware → bootloader → kernel → init\u002Fuserland → application → secrets\n```\n\nOr, in a portable-secrets context:\n\n```\ntravel-host firmware → BIOS → USB boot → unlock.sh → LUKS unlock → install-pkgs.sh → secrets pipeline\n```\n\nFor each arrow, ask: **what authenticates the next link?**\n\nIf the answer is \"the previous link verifies a manifest\" — fine, but then ask: **what authenticates the previous link?** Trace it all the way back. The chain MUST terminate at:\n\n- A **hardware root of trust** (TPM PCR measurement, Secure Boot pubkey in firmware), OR\n- An **operator-carried secret** (a printed hash card, a signed binary on a piece of media you carry physically), OR\n- An **assumption** (e.g., \"the firmware is trusted\") that is documented and accepted\n\nIf the chain terminates in a circular reference — \"the manifest verifies the scripts, the scripts verify the manifest\" — you have **no chain of trust at all**. This is the failure mode in review finding B3.\n\n---\n\n## Section 2: Anti-patterns (BLOCK on these)\n\n### Circular trust\n\n```\nunlock.sh on FAT32 partition\n  ↓ (verifies)\nmanifest.sha256 on FAT32 partition\n  ↓ (lists hash of)\nunlock.sh on FAT32 partition\n```\n\nBoth files live on unauthenticated media. An evil-maid attacker swaps `unlock.sh` AND `manifest.sha256` consistently. Detection: zero. → **BLOCK**\n\n### Unsigned bootstrap on writable media\n\nAny executable on writable storage that runs before the integrity chain is established. → **BLOCK**\n\n### \"Override\" prompt on integrity failure\n\n```\n[!] Manifest verification failed. Type Y to continue:\n```\n\nOperators learn to autoresponse-Y. The override defeats the integrity check on the exact pathway integrity matters most: when something is wrong. → **BLOCK** (see `degraded-mode-design` skill, Tier 2, for the multi-step ceremony alternative)\n\n### \"We use SHA-256 of the scripts\" without offline-signed pubkey\n\nHashing is not signing. Anyone with write access to the manifest can replace it. Hashing only authenticates if the hash itself is delivered through a separately-trusted channel (printed card, hardware-fused).\n\n### Scripts that mount LUKS before integrity is verified\n\nThe unlock script IS the high-value target. Verify its integrity before running it, or you've gained no security from LUKS.\n\n---\n\n## Section 3: Pattern catalog\n\nPick at least one. The patterns are not mutually exclusive — defense in depth combines two or more.\n\n### Pattern A: Signed bootstrap blob with offline key\n\n**Shape**: Ship `bootstrap.tar` plus `bootstrap.tar.sig` plus a small static-linked verifier (`verify`) on the same media. The verifier has an embedded ed25519 public key. The private key is offline (HQ, hardware-stored).\n\n```\nUSB layout:\n  \u002Fverify              ← static, ~50 KB, embedded pubkey\n  \u002Fbootstrap.tar       ← contains unlock.sh, install-pkgs.sh, .deb files, manifests\n  \u002Fbootstrap.tar.sig   ← Ed25519 signature over bootstrap.tar\n\nOperator runs:\n  .\u002Fverify bootstrap.tar bootstrap.tar.sig && tar xf bootstrap.tar && .\u002Funlock.sh\n```\n\n**What this gives you**: Evil-maid swap of `unlock.sh` requires also forging an Ed25519 signature → infeasible without HQ private key.\n\n**What this does NOT give you**: Trust in `verify` itself. The verifier is on the unauthenticated media. Mitigations:\n\n1. Make `verify` minimal and reproducibly built — anyone can audit it\n2. Print a SHA-256 of `verify` on a card the operator carries; check before running\n3. Better: combine with Pattern B or C\n\n**Suggested defaults**:\n- Signature: Ed25519 via libsodium or Rust `ring`\n- Verifier build: Rust with `#![no_std]`, statically linked, reproducibly built\n- Key custody: offline, hardware-token-protected (FIDO2 PRF or HSM)\n\n**Vetted alternatives**:\n- `signify` (OpenBSD) — minimal verifier already exists; use if you want zero custom code\n- `minisign` — `signify` with extras (prehashed mode)\n- Sigstore Cosign — heavier, network-aware; pick when you want transparency log integration\n\n### Pattern B: Signed live image (Tails-style)\n\n**Shape**: The \"operating environment\" is itself the signed thing. Boot from a signed read-only image; the USB you carry only contributes data, not code.\n\n```\nTravel host:\n  → BIOS verifies bootloader signature (Secure Boot)\n  → Bootloader verifies live-image signature\n  → Live image kernel + userland is read-only\n  → User USB plugs in for data only\n\nThreat collapses to: trusted firmware + your USB.\n```\n\n**What this gives you**: Massive blast-radius reduction (review finding H4). The travel host stops being a trust dependency.\n\n**What this does NOT give you**: Protection against firmware-level adversary or hardware implant. Combine with Pattern C.\n\n**Suggested defaults**:\n- Build: NixOS image (reproducible by construction) OR Tails (community-vetted, anonymity-focused)\n- Signing: integrate with the distro's existing signing (NixOS: `nix-store --verify`; Debian-based: signed `Release` file)\n- Boot: Secure Boot with operator-controlled keys (sbctl), not Microsoft's defaults\n\n### Pattern C: Measured boot + TPM remote\u002Flocal attestation\n\n**Shape**: TPM measures every stage of boot into PCRs. Refuse to derive secrets if PCRs don't match a known-good set.\n\n```\nPCR measurements taken at:\n  PCR 0    — firmware\n  PCR 4    — bootloader\n  PCR 7    — Secure Boot policy\n  PCR 8    — kernel + initrd\n  PCR 9    — kernel command line\n\nUnlock requires: TPM2_Unseal succeeds against the known-good PCR set\n```\n\n**What this gives you**: Binds secret access to a non-tampered boot chain. Evil-maid swap → PCRs change → unseal fails → no secrets.\n\n**What this does NOT give you**: Anything if the TPM is compromised, the firmware is malicious, or the operator is coerced into running with sealed values that match a malicious chain (\"seal your secret to my malicious kernel\").\n\n**Suggested defaults**:\n- Tooling: `systemd-cryptenroll --tpm2-pcrs=...`, `tpm2-tools`, `clevis` for higher-level sealing\n- PCR set: 0, 2, 4, 7, 8 (firmware, option ROMs, bootloader, Secure Boot policy, kernel)\n- Backup unseal: secondary path with hardware token (review finding H5: backup story)\n\n### Pattern D: Printed hash card (operator-carried)\n\n**Shape**: The operator carries a piece of paper (or laminated card) with a SHA-256 of the bootstrap blob. Manually compares before running.\n\n```\nCard:\n  bootstrap.tar.sig SHA-256:\n  a1b2 c3d4 e5f6 0708 1a2b 3c4d 5e6f 7081\n  9a8b 7c6d 5e4f 3021 1a2b 3c4d 5e6f 7080\n\nOperator runs:\n  sha256sum bootstrap.tar.sig\n  # compares first\u002Flast 4 groups against card\n```\n\n**What this gives you**: A truly out-of-band trust anchor, immune to USB tampering.\n\n**What this does NOT give you**: Operational ergonomics; it's tedious and skipped under time pressure. Use as a SECONDARY check, not the only one.\n\n**Suggested defaults**:\n- Compare a prefix and suffix (first 4 + last 4 hex groups), not the full hash — operators won't read 64 hex digits accurately\n- Card laminated, signed by HQ, dated, with revocation procedure documented\n\n---\n\n## Section 4: Decision matrix\n\n```\n                              Pattern A      Pattern B      Pattern C      Pattern D\n                              (signed       (signed live   (measured      (printed\n                              blob)         image)         boot\u002FTPM)      hash card)\n\nDefeats evil-maid swap        YES           YES            YES            partial*\nDefeats compromised host      no            YES            YES            no\nDefeats firmware compromise   no            no             partial**      YES\nRecovery if hardware fails    moderate      easy           hard           moderate\nOperator burden               low           lowest         low            HIGH\nHardware dependency           none          UEFI\u002FSB        TPM 2.0        none\nGreenfield-friendly           YES           YES            YES            yes\nRetrofit-friendly             yes           moderate       moderate       yes\n\n*  Pattern D detects evil-maid only if the operator actually checks\n** Pattern C with operator-controlled Secure Boot keys; otherwise firmware compromise unseals secrets\n```\n\n**Recommended starting point**: combine Pattern B (signed live image) + Pattern A (signed user-data blob). The live image is the trusted environment; the USB user-data has a signed manifest validated against an HQ Ed25519 pubkey embedded in the live image. This is the answer for review finding B3 + H4.\n\n---\n\n## Section 5: Trust anchor inventory (mandatory exercise)\n\nBefore declaring any chain-of-trust design complete, fill out:\n\n| Anchor | What is it? | Who controls it? | Compromise impact |\n|---|---|---|---|\n| HQ signing key | Ed25519 private key for bootstrap signing | HQ ops, hardware token | Total: attacker can sign malicious bootstrap |\n| Operator USB | The physical USB device | Operator | Loss alone: nothing (LUKS at rest); loss + travel host compromise: partial |\n| Travel host firmware | UEFI + Secure Boot keys | … | … |\n| TPM PCR baseline | Known-good PCR set sealed at provisioning | HQ + per-device | … |\n| Operator-carried card | Printed hash | Operator | Detection of out-of-band tampering |\n\nEvery anchor MUST be:\n\n1. **Identified**: who or what holds it\n2. **Protected**: how is it kept from being lost or copied\n3. **Rotatable**: what is the procedure when it's lost or compromised\n4. **Tested**: have you actually run the rotation procedure?\n\nIf any row has \"TBD\" in any column, the design is not complete.\n\n---\n\n## Section 6: The \"verify the verifier\" recursion\n\nFor every signed component, you have to answer \"what verifies the signer?\". The recursion terminates at one of:\n\n1. **Hardware** — a key fused into firmware (Secure Boot, TPM endorsement key)\n2. **Physical** — something the operator carries (a printed key fingerprint, a signed binary on physically separate media)\n3. **Documented assumption** — explicitly stated and accepted\n\nA common failure mode is **incomplete recursion**: stating \"the bootstrap is signed by HQ\" without saying how the operator validates HQ's pubkey. The pubkey must:\n\n- Be embedded in a verifier whose integrity is established by some other means (Pattern D card, Secure Boot embedded firmware, etc.), AND\n- Be rotatable when compromise is suspected\n\nIf you can't draw this recursion ending at hardware or physical, the chain is incomplete.\n\n---\n\n## Section 7: Recovery and rotation\n\nA chain of trust must include:\n\n| Procedure | Documented? | Tested? |\n|---|---|---|\n| Operator USB lost | … | … |\n| Travel host fails \u002F unavailable | … | … |\n| HQ signing key compromise | … | … |\n| TPM hardware failure | … | … |\n| Firmware update breaks PCR seal | … | … |\n| Bootstrap pubkey rotation | … | … |\n\n**Untested procedures don't exist.** Every project should run a tabletop exercise (review recommendation #10) walking through \"USB stolen but keys retained\" and \"USB plus one key stolen\" before declaring the design production-ready.\n\n---\n\n## Section 8: Worked example — review finding B3\n\nOriginal design:\n```\nunlock.sh + install-pkgs.sh on FAT32 (unencrypted)\nchecksum.manifest on FAT32 (unencrypted)\nunlock.sh \"verifies\" checksum.manifest — but checksum.manifest names unlock.sh\n```\n\nWhat this skill flags:\n- Section 2 anti-pattern: **circular trust** → BLOCK\n- Section 5: no trust anchor inventory exists\n- Section 6: recursion does not terminate at hardware or physical anchor\n\nRemediation options (review's \"pick at least one\"):\n1. **Pattern A only**: ship `unlock.sh.sig` + a static `verify` binary + an embedded Ed25519 pubkey. Operator runs `.\u002Fverify` first.\n2. **Pattern B**: boot the travel host from a signed live image. The image embeds the HQ pubkey. The USB only carries `unlock.sh.sig` + encrypted data.\n3. **Pattern C**: enroll the LUKS unlock against TPM PCR measurements; if `unlock.sh` is swapped, PCRs change, unseal fails.\n4. **Pattern D as backup**: print SHA-256 of `verify` (or of `unlock.sh.sig`) on a card the operator carries.\n\nThe strongest combination: **B + A + D**. Live image gives you trusted environment; signed user-data gives you tamper-evidence on the USB; printed card gives you an out-of-band sanity check.\n\n---\n\n## Section 9: Output format\n\nWhen this skill is invoked as part of a review, produce findings in this format:\n\n```markdown\n### Finding: \u003CSHORT-NAME>\n\n**Severity**: BLOCK | HIGH | MEDIUM | LOW\n**Location**: \u003Cfile or component>\n**Section**: Chain-of-trust design, \u003Csection reference>\n\n**Issue**: \u003Cwhat's broken in the chain>\n\n**Trust anchor inventory** (if relevant):\n- Anchor 1: …\n- Anchor 2: …\n- Missing: \u003Cwhat isn't anchored>\n\n**Remediation**:\n\u003Cconcrete pattern recommendation, A\u002FB\u002FC\u002FD combination>\n\n**References**:\n- \u003CNIST SP 800-193, NIST SP 800-147, RFC, etc.>\n```\n\nWhen a `chain-of-trust-design.md` (template — see `templates\u002Fchain-of-trust-design.md`) is being created, this skill drives the **Trust anchors**, **Boot chain diagram**, **Verification matrix**, **Recovery and rotation**, and **Open assumptions** sections.\n\n---\n\n## Related\n\n- **Companion skill**: `crypto-primitive-selection` (you'll use it for choosing the signing primitive)\n- **Tier 2 skill**: `physical-threat-modeling` (enumerates evil-maid, DMA, hostile peripheral threats this skill mitigates)\n- **Tier 2 skill**: `degraded-mode-design` (override-prompt anti-pattern remediation)\n- **Agent**: `secure-bootstrap-reviewer` — narrow-scope reviewer that loads this skill on activation\n- **Template**: `chain-of-trust-design.md`\n\n## Standards referenced\n\n- NIST SP 800-147 (BIOS Protection Guidelines)\n- NIST SP 800-155 (BIOS Integrity Measurement Guidelines)\n- NIST SP 800-193 (Platform Firmware Resiliency Guidelines)\n- TCG TPM 2.0 Library Specification\n- UEFI Secure Boot specification\n- Reproducible Builds (`reproducible-builds.org`)\n","# chain-of-trust-design\n\nDecision aid for the integrity chain that protects a system from first byte executed to first secret derived. Use this skill when designing or reviewing any system that has a \"boot\" step, an \"unlock\" step, or a \"first run\" step where code outside your trust boundary must be trusted to load code inside it.\n\nThe skill exists to force the question almost everyone forgets: **what authenticates the code that authenticates everything else?**\n\n## Triggers\n\nPrimary phrases match automatically. Alternates:\n\n- \"bootstrap signing\" \u002F \"signed bootstrap\"\n- \"evil maid\" \u002F \"physical access attacker\"\n- \"measured boot\" \u002F \"TPM attestation\"\n- \"verify the verifier\"\n- \"unsigned scripts\" \u002F \"is this script trusted\"\n- \"first-run integrity\"\n- \"USB boot integrity\"\n\n## When NOT to use this skill\n\n- Networked TLS chain-of-trust (different domain — use a peer-reviewed PKI design)\n- Code-signing for application updates *after* boot (use Sigstore, signify, or platform store; this skill is about the layer below)\n- Software-supply-chain trust *upstream* of build (handled by `supply-chain-trust` skill — Tier 2)\n\n---\n\n## Section 1: The core question\n\nEvery system that processes secrets has a chain of code, where each link must trust the previous one. The chain typically looks like:\n\n```\nfirmware → bootloader → kernel → init\u002Fuserland → application → secrets\n```\n\nOr, in a portable-secrets context:\n\n```\ntravel-host firmware → BIOS → USB boot → unlock.sh → LUKS unlock → install-pkgs.sh → secrets pipeline\n```\n\nFor each arrow, ask: **what authenticates the next link?**\n\nIf the answer is \"the previous link verifies a manifest\" — fine, but then ask: **what authenticates the previous link?** Trace it all the way back. The chain MUST terminate at:\n\n- A **hardware root of trust** (TPM PCR measurement, Secure Boot pubkey in firmware), OR\n- An **operator-carried secret** (a printed hash card, a signed binary on a piece of media you carry physically), OR\n- An **assumption** (e.g., \"the firmware is trusted\") that is documented and accepted\n\nIf the chain terminates in a circular reference — \"the manifest verifies the scripts, the scripts verify the manifest\" — you have **no chain of trust at all**. This is the failure mode in review finding B3.\n\n---\n\n## Section 2: Anti-patterns (BLOCK on these)\n\n### Circular trust\n\n```\nunlock.sh on FAT32 partition\n  ↓ (verifies)\nmanifest.sha256 on FAT32 partition\n  ↓ (lists hash of)\nunlock.sh on FAT32 partition\n```\n\nBoth files live on unauthenticated media. An evil-maid attacker swaps `unlock.sh` AND `manifest.sha256` consistently. Detection: zero. → **BLOCK**\n\n### Unsigned bootstrap on writable media\n\nAny executable on writable storage that runs before the integrity chain is established. → **BLOCK**\n\n### \"Override\" prompt on integrity failure\n\n```\n[!] Manifest verification failed. Type Y to continue:\n```\n\nOperators learn to autoresponse-Y. The override defeats the integrity check on the exact pathway integrity matters most: when something is wrong. → **BLOCK** (see `degraded-mode-design` skill, Tier 2, for the multi-step ceremony alternative)\n\n### \"We use SHA-256 of the scripts\" without offline-signed pubkey\n\nHashing is not signing. Anyone with write access to the manifest can replace it. Hashing only authenticates if the hash itself is delivered through a separately-trusted channel (printed card, hardware-fused).\n\n### Scripts that mount LUKS before integrity is verified\n\nThe unlock script IS the high-value target. Verify its integrity before running it, or you've gained no security from LUKS.\n\n---\n\n## Section 3: Pattern catalog\n\nPick at least one. The patterns are not mutually exclusive — defense in depth combines two or more.\n\n### Pattern A: Signed bootstrap blob with offline key\n\n**Shape**: Ship `bootstrap.tar` plus `bootstrap.tar.sig` plus a small static-linked verifier (`verify`) on the same media. The verifier has an embedded ed25519 public key. The private key is offline (HQ, hardware-stored).\n\n```\nUSB layout:\n  \u002Fverify              ← static, ~50 KB, embedded pubkey\n  \u002Fbootstrap.tar       ← contains unlock.sh, install-pkgs.sh, .deb files, manifests\n  \u002Fbootstrap.tar.sig   ← Ed25519 signature over bootstrap.tar\n\nOperator runs:\n  .\u002Fverify bootstrap.tar bootstrap.tar.sig && tar xf bootstrap.tar && .\u002Funlock.sh\n```\n\n**What this gives you**: Evil-maid swap of `unlock.sh` requires also forging an Ed25519 signature → infeasible without HQ private key.\n\n**What this does NOT give you**: Trust in `verify` itself. The verifier is on the unauthenticated media. Mitigations:\n\n1. Make `verify` minimal and reproducibly built — anyone can audit it\n2. Print a SHA-256 of `verify` on a card the operator carries; check before running\n3. Better: combine with Pattern B or C\n\n**Suggested defaults**:\n- Signature: Ed25519 via libsodium or Rust `ring`\n- Verifier build: Rust with `#![no_std]`, statically linked, reproducibly built\n- Key custody: offline, hardware-token-protected (FIDO2 PRF or HSM)\n\n**Vetted alternatives**:\n- `signify` (OpenBSD) — minimal verifier already exists; use if you want zero custom code\n- `minisign` — `signify` with extras (prehashed mode)\n- Sigstore Cosign — heavier, network-aware; pick when you want transparency log integration\n\n### Pattern B: Signed live image (Tails-style)\n\n**Shape**: The \"operating environment\" is itself the signed thing. Boot from a signed read-only image; the USB you carry only contributes data, not code.\n\n```\nTravel host:\n  → BIOS verifies bootloader signature (Secure Boot)\n  → Bootloader verifies live-image signature\n  → Live image kernel + userland is read-only\n  → User USB plugs in for data only\n\nThreat collapses to: trusted firmware + your USB.\n```\n\n**What this gives you**: Massive blast-radius reduction (review finding H4). The travel host stops being a trust dependency.\n\n**What this does NOT give you**: Protection against firmware-level adversary or hardware implant. Combine with Pattern C.\n\n**Suggested defaults**:\n- Build: NixOS image (reproducible by construction) OR Tails (community-vetted, anonymity-focused)\n- Signing: integrate with the distro's existing signing (NixOS: `nix-store --verify`; Debian-based: signed `Release` file)\n- Boot: Secure Boot with operator-controlled keys (sbctl), not Microsoft's defaults\n\n### Pattern C: Measured boot + TPM remote\u002Flocal attestation\n\n**Shape**: TPM measures every stage of boot into PCRs. Refuse to derive secrets if PCRs don't match a known-good set.\n\n```\nPCR measurements taken at:\n  PCR 0    — firmware\n  PCR 4    — bootloader\n  PCR 7    — Secure Boot policy\n  PCR 8    — kernel + initrd\n  PCR 9    — kernel command line\n\nUnlock requires: TPM2_Unseal succeeds against the known-good PCR set\n```\n\n**What this gives you**: Binds secret access to a non-tampered boot chain. Evil-maid swap → PCRs change → unseal fails → no secrets.\n\n**What this does NOT give you**: Anything if the TPM is compromised, the firmware is malicious, or the operator is coerced into running with sealed values that match a malicious chain (\"seal your secret to my malicious kernel\").\n\n**Suggested defaults**:\n- Tooling: `systemd-cryptenroll --tpm2-pcrs=...`, `tpm2-tools`, `clevis` for higher-level sealing\n- PCR set: 0, 2, 4, 7, 8 (firmware, option ROMs, bootloader, Secure Boot policy, kernel)\n- Backup unseal: secondary path with hardware token (review finding H5: backup story)\n\n### Pattern D: Printed hash card (operator-carried)\n\n**Shape**: The operator carries a piece of paper (or laminated card) with a SHA-256 of the bootstrap blob. Manually compares before running.\n\n```\nCard:\n  bootstrap.tar.sig SHA-256:\n  a1b2 c3d4 e5f6 0708 1a2b 3c4d 5e6f 7081\n  9a8b 7c6d 5e4f 3021 1a2b 3c4d 5e6f 7080\n\nOperator runs:\n  sha256sum bootstrap.tar.sig\n  # compares first\u002Flast 4 groups against card\n```\n\n**What this gives you**: A truly out-of-band trust anchor, immune to USB tampering.\n\n**What this does NOT give you**: Operational ergonomics; it's tedious and skipped under time pressure. Use as a SECONDARY check, not the only one.\n\n**Suggested defaults**:\n- Compare a prefix and suffix (first 4 + last 4 hex groups), not the full hash — operators won't read 64 hex digits accurately\n- Card laminated, signed by HQ, dated, with revocation procedure documented\n\n---\n\n## Section 4: Decision matrix\n\n```\n                              Pattern A      Pattern B      Pattern C      Pattern D\n                              (signed       (signed live   (measured      (printed\n                              blob)         image)         boot\u002FTPM)      hash card)\n\nDefeats evil-maid swap        YES           YES            YES            partial*\nDefeats compromised host      no            YES            YES            no\nDefeats firmware compromise   no            no             partial**      YES\nRecovery if hardware fails    moderate      easy           hard           moderate\nOperator burden               low           lowest         low            HIGH\nHardware dependency           none          UEFI\u002FSB        TPM 2.0        none\nGreenfield-friendly           YES           YES            YES            yes\nRetrofit-friendly             yes           moderate       moderate       yes\n\n*  Pattern D detects evil-maid only if the operator actually checks\n** Pattern C with operator-controlled Secure Boot keys; otherwise firmware compromise unseals secrets\n```\n\n**Recommended starting point**: combine Pattern B (signed live image) + Pattern A (signed user-data blob). The live image is the trusted environment; the USB user-data has a signed manifest validated against an HQ Ed25519 pubkey embedded in the live image. This is the answer for review finding B3 + H4.\n\n---\n\n## Section 5: Trust anchor inventory (mandatory exercise)\n\nBefore declaring any chain-of-trust design complete, fill out:\n\n| Anchor | What is it? | Who controls it? | Compromise impact |\n|---|---|---|---|\n| HQ signing key | Ed25519 private key for bootstrap signing | HQ ops, hardware token | Total: attacker can sign malicious bootstrap |\n| Operator USB | The physical USB device | Operator | Loss alone: nothing (LUKS at rest); loss + travel host compromise: partial |\n| Travel host firmware | UEFI + Secure Boot keys | … | … |\n| TPM PCR baseline | Known-good PCR set sealed at provisioning | HQ + per-device | … |\n| Operator-carried card | Printed hash | Operator | Detection of out-of-band tampering |\n\nEvery anchor MUST be:\n\n1. **Identified**: who or what holds it\n2. **Protected**: how is it kept from being lost or copied\n3. **Rotatable**: what is the procedure when it's lost or compromised\n4. **Tested**: have you actually run the rotation procedure?\n\nIf any row has \"TBD\" in any column, the design is not complete.\n\n---\n\n## Section 6: The \"verify the verifier\" recursion\n\nFor every signed component, you have to answer \"what verifies the signer?\". The recursion terminates at one of:\n\n1. **Hardware** — a key fused into firmware (Secure Boot, TPM endorsement key)\n2. **Physical** — something the operator carries (a printed key fingerprint, a signed binary on physically separate media)\n3. **Documented assumption** — explicitly stated and accepted\n\nA common failure mode is **incomplete recursion**: stating \"the bootstrap is signed by HQ\" without saying how the operator validates HQ's pubkey. The pubkey must:\n\n- Be embedded in a verifier whose integrity is established by some other means (Pattern D card, Secure Boot embedded firmware, etc.), AND\n- Be rotatable when compromise is suspected\n\nIf you can't draw this recursion ending at hardware or physical, the chain is incomplete.\n\n---\n\n## Section 7: Recovery and rotation\n\nA chain of trust must include:\n\n| Procedure | Documented? | Tested? |\n|---|---|---|\n| Operator USB lost | … | … |\n| Travel host fails \u002F unavailable | … | … |\n| HQ signing key compromise | … | … |\n| TPM hardware failure | … | … |\n| Firmware update breaks PCR seal | … | … |\n| Bootstrap pubkey rotation | … | … |\n\n**Untested procedures don't exist.** Every project should run a tabletop exercise (review recommendation #10) walking through \"USB stolen but keys retained\" and \"USB plus one key stolen\" before declaring the design production-ready.\n\n---\n\n## Section 8: Worked example — review finding B3\n\nOriginal design:\n```\nunlock.sh + install-pkgs.sh on FAT32 (unencrypted)\nchecksum.manifest on FAT32 (unencrypted)\nunlock.sh \"verifies\" checksum.manifest — but checksum.manifest names unlock.sh\n```\n\nWhat this skill flags:\n- Section 2 anti-pattern: **circular trust** → BLOCK\n- Section 5: no trust anchor inventory exists\n- Section 6: recursion does not terminate at hardware or physical anchor\n\nRemediation options (review's \"pick at least one\"):\n1. **Pattern A only**: ship `unlock.sh.sig` + a static `verify` binary + an embedded Ed25519 pubkey. Operator runs `.\u002Fverify` first.\n2. **Pattern B**: boot the travel host from a signed live image. The image embeds the HQ pubkey. The USB only carries `unlock.sh.sig` + encrypted data.\n3. **Pattern C**: enroll the LUKS unlock against TPM PCR measurements; if `unlock.sh` is swapped, PCRs change, unseal fails.\n4. **Pattern D as backup**: print SHA-256 of `verify` (or of `unlock.sh.sig`) on a card the operator carries.\n\nThe strongest combination: **B + A + D**. Live image gives you trusted environment; signed user-data gives you tamper-evidence on the USB; printed card gives you an out-of-band sanity check.\n\n---\n\n## Section 9: Output format\n\nWhen this skill is invoked as part of a review, produce findings in this format:\n\n```markdown\n### Finding: \u003CSHORT-NAME>\n\n**Severity**: BLOCK | HIGH | MEDIUM | LOW\n**Location**: \u003Cfile or component>\n**Section**: Chain-of-trust design, \u003Csection reference>\n\n**Issue**: \u003Cwhat's broken in the chain>\n\n**Trust anchor inventory** (if relevant):\n- Anchor 1: …\n- Anchor 2: …\n- Missing: \u003Cwhat isn't anchored>\n\n**Remediation**:\n\u003Cconcrete pattern recommendation, A\u002FB\u002FC\u002FD combination>\n\n**References**:\n- \u003CNIST SP 800-193, NIST SP 800-147, RFC, etc.>\n```\n\nWhen a `chain-of-trust-design.md` (template — see `templates\u002Fchain-of-trust-design.md`) is being created, this skill drives the **Trust anchors**, **Boot chain diagram**, **Verification matrix**, **Recovery and rotation**, and **Open assumptions** sections.\n\n---\n\n## Related\n\n- **Companion skill**: `crypto-primitive-selection` (you'll use it for choosing the signing primitive)\n- **Tier 2 skill**: `physical-threat-modeling` (enumerates evil-maid, DMA, hostile peripheral threats this skill mitigates)\n- **Tier 2 skill**: `degraded-mode-design` (override-prompt anti-pattern remediation)\n- **Agent**: `secure-bootstrap-reviewer` — narrow-scope reviewer that loads this skill on activation\n- **Template**: `chain-of-trust-design.md`\n\n## Standards referenced\n\n- NIST SP 800-147 (BIOS Protection Guidelines)\n- NIST SP 800-155 (BIOS Integrity Measurement Guidelines)\n- NIST SP 800-193 (Platform Firmware Resiliency Guidelines)\n- TCG TPM 2.0 Library Specification\n- UEFI Secure Boot specification\n- Reproducible Builds (`reproducible-builds.org`)\n",{"name":5,"namespace":49,"platforms":50,"description":7},"aiwg",[51],"all","main","6754967c344ccb087a8de06972f55a41067b291b","agentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fchain-of-trust-design",36,"https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg","https:\u002F\u002Faiwg.io","https:\u002F\u002Fgithub.com\u002Fjmagly","https:\u002F\u002Fintegrolabs.io","ml\u002Fai, industrial automation, safety\u002Fsecurity, ssi\r\n\r\nmagly.net\r\nintegrolabs.io\r\naiwg.io\r\nfortemi.com\r\npagenary.com\r\nbytecask.com","2026-11-14 10:46:34",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add jmagly\u002Faiwg --skill chain-of-trust-design",{"tool":68,"command":69},"bunx","bunx skills add jmagly\u002Faiwg --skill chain-of-trust-design",{"tool":71,"command":72},"pnpm","pnpm dlx skills add jmagly\u002Faiwg --skill chain-of-trust-design","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fchain-of-trust-design\u002FSKILL.md",true,[76],{"path":77,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":80,"sourceHtmlUrl":81},"assets\u002Freport.mplstyle","ASSET","资产文件",1037,"https:\u002F\u002Fgithub.com\u002FMuvon\u002Foctomind-tap\u002Fblob\u002Fmaster\u002Fskills\u002Fanalytical-report\u002Fassets\u002Freport.mplstyle",[83,110,134,140,147,161],{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":90,"publishedAt":44},"01M70QA0BSYJ49EES9V4RE8QH1","host-hardening","Read-only system hardening baseline and plan-first host hardening recommendations for SSH, Docker bind addresses, firewall persistence, datastores, exporters and audit retention.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[89],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[91,92,93,94,95,96,97,98,99,38,100,101,102,103,104,105,106,107,108,109],"host","host hardening","hardening","read","re","recommendations","remediation","plan","port","Bash","access","only","retention","audit","never","firewall","bind","secrets","request",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":120,"publishedAt":44},"01M70PNT2Z4HMZPRBTAF6073NN","exposure-analysis","Read-only firewall analysis and effective host exposure reconstruction for Docker published ports, UFW bypass, stale rules, CDN scope, IPv6 asymmetry and external probe allowlists.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fforensics\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[116,119],{"categoryNo":117,"categoryName":118,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[121,122,123,94,124,99,125,126,100,127,91,128,102,129,130,105,106,131,132,133],"exposure analysis","analysis","unknown","credentials","collection","ufw","ports","internet","local","scope","reconstruction","operator","write",{"skillNo":135,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":139,"publishedAt":44},"01M70P8QATMPKA78E4FT5D2TNA","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[138],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[93,91,92,101,94,109,97,96,104,98,99,38,100,108,102,103,95,105,106,107],{"skillNo":141,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":146,"publishedAt":44},"01M70NMPVJ5H0JH131P60FW4R8","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fforensics-complete\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[144,145],{"categoryNo":117,"categoryName":118,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[122,121,105,124,99,125,100,123,91,128,102,129,130,94,106,127,126,131,132,133],{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":154,"publishedAt":44},"01M6CB4DDR0B4NNCFK7ZK7449H","fixture-skill","Exercise rule delivery.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Frule-delivery\u002Fskills\u002Ffixture-skill\u002FSKILL.md",[153],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[155,156,157,158,159,160],"fixture skill","fixture","rule","delivery","true","exercise",{"skillNo":162,"name":163,"nameZh":6,"description":164,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":165,"categories":166,"keywords":168,"publishedAt":44},"01M6CB4AVK1W76MFMPP0JP32CJ","pi-local","Pi-local duplicate-precedence fixture.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fproviders\u002Fpi\u002Fproject\u002F.pi\u002Fskills\u002Fpi-local\u002FSKILL.md",[167],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[169,170,129,171,156],"pi","pi local","duplicate"]