Files
SilverMetal/windows/iso-builder.md
sysadmin 3a30a0421e docs(windows): add ISO-builder design + scaffold the windows/ tree
Add windows/iso-builder.md: reproducible custom-packed-ISO pipeline design for
SilverMetal Enhanced - Windows on IoT Enterprise LTSC. Covers the licensing
frame (IoT = blessed channel for preinstalled custom images; self-apply stays a
builder), 7 build stages (verify/extract/DISM-service/inject-unattend/brand/
oscdimg-repack/attest), the offline-vs-first-boot-vs-firmware control split, an
honest reproducibility scope (pinned inputs + SBOM + attestation, NOT bit-
identical on Windows), and M0-M4 milestones.

Scaffold windows/ per the planned layout:
- installer/  build.ps1 (7-stage orchestrator, stages stubbed to M2),
              inputs.manifest.json (pinned-input schema), autounattend.xml
              (local-account OOBE), oem/SetupComplete.cmd (first-boot runner)
- hardening/  shared §A-H PowerShell modules + Verify-SilverMetalWindows.ps1
              (used by BOTH the ISO first-boot path and the self-apply track).
              BitLocker module enforces TPM+PIN and blocks TPM-only.
- policies/ wdac/ debloat/ stack-installer/ drivers/ tests/  scaffolded with
  READMEs; wdac/ documents audit->enforce; debloat/ flags Tiny11/NTLite as an
  anti-pattern; rename applocker/ -> wdac/ realised.

All 11 PowerShell scripts parse clean; manifest JSON + autounattend XML valid.
Module bodies are M1 scaffold (safe: log + policy-set; interactive/firmware
steps documented, not faked).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 15:35:13 +01:00

132 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SilverMetal Enhanced — Windows: ISO Builder
> **Status**: v1 design — 2026-06-08. Implements the productized SKU build for the hardening defined in [`hardening-spec.md`](hardening-spec.md). Reference device: GPD Pocket 4.
This document describes the **reproducible build pipeline** that turns an official Windows 11 IoT Enterprise LTSC ISO plus the SilverMetal config layer into a hardened, branded, UEFI-bootable **custom packed ISO**, with a signed build attestation.
It is bound by the same documents as the hardening spec: [`../docs/threat-model.md`](../docs/threat-model.md), [`../docs/design-principles.md`](../docs/design-principles.md), and [`../docs/trust-model.md`](../docs/trust-model.md).
## 1. Licensing frame (why this is legitimate)
Windows 11 **IoT Enterprise LTSC** is licensed through the OEM / embedded channel, whose explicit purpose is building **customized, locked-down, preinstalled images** on devices a solution-builder ships. Creating a custom packed image and preinstalling it on hardware we sell is the *intended, blessed* use — not a grey area.
| Track | Status under IoT Enterprise LTSC |
|---|---|
| **Preflashed SilverMetal SKU** (we sell the device) | ✅ Build + ship our custom image — licensed per device, intended use |
| **Self-apply free track** (user hardens own device) | ⚠️ No public prebuilt-ISO redistribution. Ships as a **builder** that consumes the user's own official ISO + license — the same `hardening/` modules, applied to their image |
The Microsoft ISO is therefore always an **input**, never committed to this repo. We ship *our layer*; the licensee provides the base.
> **Procurement note (verify before pricing the SKU):** IoT Enterprise LTSC is obtained via authorized OEM distributors; per-device licensing may carry minimum-order / agreement terms. Confirm with the distributor.
## 2. Inputs
All inputs are pinned by hash in [`installer/inputs.manifest.json`](installer/inputs.manifest.json):
| Input | Source | In repo? |
|---|---|---|
| Windows 11 IoT Enterprise LTSC ISO | Licensed (operator/distributor) | No — pinned by SHA-256 |
| GPD Pocket 4 driver pack | GPD (verified source) | `drivers/` or sourced manifest |
| SilverLABS Stack (native Windows builds) | Stack component repos / artifacts | Referenced by version |
| SilverMetal config layer | This repo (`hardening/`, `policies/`, `wdac/`, `debloat/`, `autounattend/`, `oem/`, branding) | Yes |
## 3. Build stages
Orchestrated by [`installer/build.ps1`](installer/build.ps1). Runs on a **Windows host with the Windows ADK** (DISM + `oscdimg`).
1. **Verify input** — assert the source ISO SHA-256 matches the pinned manifest (supply-chain integrity).
2. **Extract** — expand the ISO to a working directory.
3. **Service the WIM offline (DISM)**:
- Select the IoT Enterprise LTSC image index.
- `/Add-Driver` the GPD Pocket 4 driver pack (Strix Point GPU, sensors/auto-rotate, Wi-Fi, fingerprint).
- `/Add-Package` the latest cumulative update (slipstream).
- Trim residual provisioned appx (LTSC is already lean — minimal list in `debloat/`).
- Load offline registry hives → apply the **offline-able baseline** (telemetry floor, service disables) from `policies/`.
- Stage the Stack installers + first-boot payload into the image.
- Commit + unmount.
4. **Inject answer file + first-boot payload**:
- `autounattend.xml` — OOBE automation, **local account** (no MSA), regional settings, BitLocker-ready disk layout.
- `$OEM$\SetupComplete.cmd` — first-boot entry point that runs the online `hardening/` modules and installs the Stack.
5. **Brand** — boot/OOBE wallpaper + computer-name pattern from [`../shared/branding`](../shared/branding).
6. **Repack**`oscdimg` produces a UEFI-bootable ISO (efisys boot image, El Torito).
7. **Attest** — emit output ISO SHA-256, an **SBOM** (every component + version), and a signed build attestation (design-principle #4).
## 4. Where each hardening control is applied
The control domains in [`hardening-spec.md`](hardening-spec.md) split across three layers:
| Layer | Controls | Mechanism |
|---|---|---|
| **Baked offline (in WIM)** | Telemetry floor, service disables, appx trim, drivers, baseline registry policy, Stack staging | DISM + offline hive edits |
| **First-boot (online)** | Local account, VBS/HVCI/Credential Guard, ASR rules, **WDAC (audit)**, firewall, encrypted DNS, Stack + SilverVPN install, scheduled `Verify` task | `SetupComplete.cmd``hardening/` modules |
| **Interactive / firmware — NOT in ISO** | Secure Boot custom-key enrollment, **BitLocker PIN**, BIOS admin password | Operator at provisioning (SKU) or documented user step (self-apply). The ISO *enables* BitLocker and *forces* PIN enrollment; it cannot ship a PIN or touch firmware. |
**The `hardening/` modules are shared.** The same module set is invoked by the ISO's first-boot path *and* by the self-apply / milestone-1 standalone path. Write once, used both ways.
## 5. Reproducibility (honest scope)
Windows image servicing is **not bit-for-bit deterministic** the way the Linux ISO pipeline is (WIM internal timestamps, servicing-stack non-determinism). So for this product, "reproducible" means:
- **Pinned inputs** (every source hashed in the manifest)
- **Recorded tool versions** (ADK, DISM, servicing stack)
- **Output ISO SHA-256 + SBOM** published per build
- **Signed build attestation** linking published artifact ↔ published source + inputs
Bit-identical rebuild is a **stretch goal**, documented as such — we do not claim it (design-principle #2). This is weaker than the Linux line's reproducible-build guarantee, and we say so to buyers.
## 6. Directory layout
```
windows/
├── installer/
│ ├── build.ps1 # pipeline orchestrator
│ ├── inputs.manifest.json # pinned ISO SHA, driver-pack ver, Stack vers, tool vers
│ ├── autounattend/
│ │ └── autounattend.xml # OOBE automation + local account + disk layout
│ ├── oem/
│ │ └── SetupComplete.cmd # first-boot entry → runs hardening/ modules
│ └── README.md
├── hardening/ # §AH PowerShell modules + Verify ← SHARED (ISO + self-apply)
│ ├── 00-provisioning.ps1 # A
│ ├── 01-boot-firmware.ps1 # B (stages keys; firmware steps documented)
│ ├── 02-data-at-rest.ps1 # C (BitLocker TPM+PIN)
│ ├── 03-kernel-credential.ps1# D (VBS/HVCI/CredGuard/DMA)
│ ├── 04-app-control.ps1 # E (WDAC audit, ASR, Defender)
│ ├── 05-network-radios.ps1 # F (firewall, DNS, WiFi-only)
│ ├── 06-physical-lock.ps1 # G (lock-screen, DMA lock, cam/mic)
│ ├── 07-privacy-update.ps1 # H (telemetry trim, update integrity)
│ ├── 08-stack-install.ps1 # SilverLABS Stack
│ └── Verify-SilverMetalWindows.ps1
├── policies/ # GP/ADMX exports + offline .reg/.pol baseline
├── wdac/ # WDAC base policy (XML) + compiled .cip
├── debloat/ # appx removal list, service-disable scripts
├── stack-installer/ # Stack package builders/installers
├── drivers/ # GPD Pocket 4 driver pack (or sourced manifest)
└── tests/ # telemetry-leak test, hardening-baseline test
```
## 7. Milestones
| Milestone | Deliverable | Needs hardware? |
|---|---|---|
| **M0** | This design + scaffolded tree | No |
| **M1** | `autounattend.xml` + `hardening/` modules runnable standalone — hardens the Pocket 4 with no pipeline | Yes (the unit) |
| **M2** | DISM servicing + `oscdimg` repack → first packed ISO, built locally on a Windows + ADK box | Driver pack |
| **M3** | `.gitea/workflows/build-iso-windows.yaml` (Windows runner) + attestation/SBOM + telemetry-leak gate | Windows runner |
| **M4** | Branding, full Stack integration, all verification gates green | Stack Windows builds |
## 8. Build environment & deferred items
- **Build host**: Windows + Windows ADK (DISM + `oscdimg`). A Windows CI runner is required for M3 (mirrors the existing Linux `.gitea/workflows/build-iso-linux.yaml`).
- **Cross-build on Linux** (wimlib + xorriso) is possible but UEFI boot-file assembly is fiddly — **deferred**, Windows-runner path is canonical.
- **Stack Windows builds**: some Stack components are still "Linux MVP" per [`README.md`](README.md); their native Windows builds may lag M4.
- **Driver-pack sourcing**: confirm redistribution terms for the GPD Pocket 4 driver pack, or source at build time from the verified GPD location.
## 9. Open questions
Carried from [`hardening-spec.md`](hardening-spec.md) §8 (resolve on the physical unit), plus builder-specific:
1. Does the IoT Enterprise LTSC media expose the expected image index and OOBE bypass path for `autounattend.xml`?
2. Which Pocket 4 drivers are absent from a vanilla LTSC install and must be injected?
3. Does `oscdimg` produce a Pocket 4-bootable UEFI image with the device's firmware (test on the unit)?