chain-of-trust-design
Decision aid for bootstrap and verification chains — forces the 'what authenticates the authenticator' question; patterns for signed bootstrap, measured boot, recovery.
What this skill does
# chain-of-trust-design
Decision 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.
The skill exists to force the question almost everyone forgets: **what authenticates the code that authenticates everything else?**
## Triggers
Primary phrases match automatically. Alternates:
- "bootstrap signing" / "signed bootstrap"
- "evil maid" / "physical access attacker"
- "measured boot" / "TPM attestation"
- "verify the verifier"
- "unsigned scripts" / "is this script trusted"
- "first-run integrity"
- "USB boot integrity"
## When NOT to use this skill
- Networked TLS chain-of-trust (different domain — use a peer-reviewed PKI design)
- Code-signing for application updates *after* boot (use Sigstore, signify, or platform store; this skill is about the layer below)
- Software-supply-chain trust *upstream* of build (handled by `supply-chain-trust` skill — Tier 2)
---
## Section 1: The core question
Every system that processes secrets has a chain of code, where each link must trust the previous one. The chain typically looks like:
```
firmware → bootloader → kernel → init/userland → application → secrets
```
Or, in a portable-secrets context:
```
travel-host firmware → BIOS → USB boot → unlock.sh → LUKS unlock → install-pkgs.sh → secrets pipeline
```
For each arrow, ask: **what authenticates the next link?**
If 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:
- A **hardware root of trust** (TPM PCR measurement, Secure Boot pubkey in firmware), OR
- An **operator-carried secret** (a printed hash card, a signed binary on a piece of media you carry physically), OR
- An **assumption** (e.g., "the firmware is trusted") that is documented and accepted
If 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.
---
## Section 2: Anti-patterns (BLOCK on these)
### Circular trust
```
unlock.sh on FAT32 partition
↓ (verifies)
manifest.sha256 on FAT32 partition
↓ (lists hash of)
unlock.sh on FAT32 partition
```
Both files live on unauthenticated media. An evil-maid attacker swaps `unlock.sh` AND `manifest.sha256` consistently. Detection: zero. → **BLOCK**
### Unsigned bootstrap on writable media
Any executable on writable storage that runs before the integrity chain is established. → **BLOCK**
### "Override" prompt on integrity failure
```
[!] Manifest verification failed. Type Y to continue:
```
Operators 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)
### "We use SHA-256 of the scripts" without offline-signed pubkey
Hashing 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).
### Scripts that mount LUKS before integrity is verified
The unlock script IS the high-value target. Verify its integrity before running it, or you've gained no security from LUKS.
---
## Section 3: Pattern catalog
Pick at least one. The patterns are not mutually exclusive — defense in depth combines two or more.
### Pattern A: Signed bootstrap blob with offline key
**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).
```
USB layout:
/verify ← static, ~50 KB, embedded pubkey
/bootstrap.tar ← contains unlock.sh, install-pkgs.sh, .deb files, manifests
/bootstrap.tar.sig ← Ed25519 signature over bootstrap.tar
Operator runs:
./verify bootstrap.tar bootstrap.tar.sig && tar xf bootstrap.tar && ./unlock.sh
```
**What this gives you**: Evil-maid swap of `unlock.sh` requires also forging an Ed25519 signature → infeasible without HQ private key.
**What this does NOT give you**: Trust in `verify` itself. The verifier is on the unauthenticated media. Mitigations:
1. Make `verify` minimal and reproducibly built — anyone can audit it
2. Print a SHA-256 of `verify` on a card the operator carries; check before running
3. Better: combine with Pattern B or C
**Suggested defaults**:
- Signature: Ed25519 via libsodium or Rust `ring`
- Verifier build: Rust with `#![no_std]`, statically linked, reproducibly built
- Key custody: offline, hardware-token-protected (FIDO2 PRF or HSM)
**Vetted alternatives**:
- `signify` (OpenBSD) — minimal verifier already exists; use if you want zero custom code
- `minisign` — `signify` with extras (prehashed mode)
- Sigstore Cosign — heavier, network-aware; pick when you want transparency log integration
### Pattern B: Signed live image (Tails-style)
**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.
```
Travel host:
→ BIOS verifies bootloader signature (Secure Boot)
→ Bootloader verifies live-image signature
→ Live image kernel + userland is read-only
→ User USB plugs in for data only
Threat collapses to: trusted firmware + your USB.
```
**What this gives you**: Massive blast-radius reduction (review finding H4). The travel host stops being a trust dependency.
**What this does NOT give you**: Protection against firmware-level adversary or hardware implant. Combine with Pattern C.
**Suggested defaults**:
- Build: NixOS image (reproducible by construction) OR Tails (community-vetted, anonymity-focused)
- Signing: integrate with the distro's existing signing (NixOS: `nix-store --verify`; Debian-based: signed `Release` file)
- Boot: Secure Boot with operator-controlled keys (sbctl), not Microsoft's defaults
### Pattern C: Measured boot + TPM remote/local attestation
**Shape**: TPM measures every stage of boot into PCRs. Refuse to derive secrets if PCRs don't match a known-good set.
```
PCR measurements taken at:
PCR 0 — firmware
PCR 4 — bootloader
PCR 7 — Secure Boot policy
PCR 8 — kernel + initrd
PCR 9 — kernel command line
Unlock requires: TPM2_Unseal succeeds against the known-good PCR set
```
**What this gives you**: Binds secret access to a non-tampered boot chain. Evil-maid swap → PCRs change → unseal fails → no secrets.
**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").
**Suggested defaults**:
- Tooling: `systemd-cryptenroll --tpm2-pcrs=...`, `tpm2-tools`, `clevis` for higher-level sealing
- PCR set: 0, 2, 4, 7, 8 (firmware, option ROMs, bootloader, Secure Boot policy, kernel)
- Backup unseal: secondary path with hardware token (review finding H5: backup story)
### Pattern D: Printed hash card (operator-carried)
**Shape**: The operator carries a piece of paper (or laminated card) with a SHA-256 of the bootstrap blob. Manually compares before running.
```
Card:
bootstrap.tar.sig SHA-256:
a1b2 c3d4 e5f6 0708 1a2b 3c4d 5e6f 7081
9a8b 7c6d 5e4f 3021 1a2b 3c4d 5e6f 7080
Operator runs:
sha256sum bootstrap.tar.sig
# compares first/last 4 groups against card
```
**What this gives you**: A truly out-of-band trust anchor, immune to USB tampering.
**What this does NOT give you**: Operational ergonomics; it's tedious and skipped under time pressure. Use as a SECONDARY check, not the Related in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.