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>
This commit is contained in:
sysadmin
2026-06-08 15:35:13 +01:00
parent ea2de4339d
commit 3a30a0421e
23 changed files with 812 additions and 0 deletions

10
windows/debloat/README.md Normal file
View File

@@ -0,0 +1,10 @@
# windows/debloat
Residue removal for the lean IoT Enterprise LTSC base.
- `appx-remove.txt` — provisioned-package removal list (short by design; LTSC is already minimal).
- Service-disable lists are applied by [`../hardening/00-provisioning.ps1`](../hardening/00-provisioning.ps1) and [`07-privacy-update.ps1`](../hardening/07-privacy-update.ps1) (telemetry/feedback services only — never update/security services).
**Anti-pattern (do not do):** Tiny11/NTLite-style component amputation. It breaks
servicing and genuineness, violating design-principles #2 and #13. LTSC gives the
lean base without the breakage.

View File

@@ -0,0 +1,17 @@
# SilverMetal Enhanced - Windows : provisioned appx removal list.
# One package family name (or prefix) per line; '#' comments ignored.
# IoT Enterprise LTSC is already lean, so this list is intentionally SHORT and
# only targets residue. Do NOT remove servicing/Store-for-Business components
# that LTSC relies on. Verify per-build (TODO-M2).
#
# Removed offline in the WIM by build.ps1 (DISM /Remove-ProvisionedAppxPackage)
# and at first boot for the provisioned user where applicable.
Microsoft.Windows.Copilot
Microsoft.549981C3F5F10 # Cortana
Microsoft.BingWeather
Microsoft.BingNews
Microsoft.GamingApp
Microsoft.XboxGamingOverlay
Microsoft.MicrosoftSolitaireCollection
# TODO-M2: confirm against the actual LTSC media manifest before enabling removal.

15
windows/drivers/README.md Normal file
View File

@@ -0,0 +1,15 @@
# windows/drivers
GPD Pocket 4 driver pack, injected offline into the WIM (`DISM /Add-Driver`) by
`../installer/build.ps1` stage 3.
Targets the Pocket 4 hardware a vanilla LTSC install may lack: Strix Point GPU,
sensors / auto-rotate, Wi-Fi, fingerprint, modular-port controllers, fan/EC.
**Sourcing (M2):** confirm redistribution terms for the GPD driver pack. If
redistribution is not permitted, store a **sourced manifest** (URL + SHA-256 +
version, pinned in `../installer/inputs.manifest.json`) and fetch at build time
rather than committing the binaries.
Open question (hardening-spec §8): which drivers are actually absent from a
vanilla LTSC install — determine on the physical unit.

View File

@@ -0,0 +1,27 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain A: Provisioning baseline
De-cloud, debloat, telemetry -> Security floor. Idempotent.
Spec: ../hardening-spec.md (A) | SCAFFOLD (M1): verify on the unit.
#>
[CmdletBinding()] param()
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[A] Provisioning baseline'
# Telemetry floor (level 0 'Security' is honoured only on Enterprise/Education/LTSC).
$dc = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection'
New-Item -Path $dc -Force | Out-Null
Set-ItemProperty $dc -Name AllowTelemetry -Type DWord -Value 0
Set-ItemProperty $dc -Name DoNotShowFeedbackNotifications -Type DWord -Value 1
# Kill connected-experience / advertising / activity surfaces.
$svc = 'DiagTrack','dmwappushservice'
foreach ($s in $svc) { Get-Service $s -EA SilentlyContinue | Set-Service -StartupType Disabled -PassThru | Stop-Service -Force -EA SilentlyContinue }
# Advertising ID, Tailored experiences, Activity feed (machine policies).
$adv = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo'
New-Item $adv -Force | Out-Null; Set-ItemProperty $adv -Name DisabledByGroupPolicy -Type DWord -Value 1
# TODO-M1: Recall/Copilot/Cortana off; remove residual provisioned appx (Enterprise prototype);
# confirm no MSA bound (OOBE handled this via autounattend).
Write-Host ' [A] applied (telemetry=0, DiagTrack disabled, ad-ID off)'

View File

@@ -0,0 +1,23 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain B: Boot & firmware trust
Most of B is a FIRMWARE step (Secure Boot custom-key enrollment, BIOS admin
password) that an OS image cannot perform. This module STAGES our keys and
reports Secure Boot state; the enrollment itself is done in UEFI setup at
provisioning (SKU) or as a documented user step (self-apply).
Spec: ../hardening-spec.md (B) | SCAFFOLD (M1).
#>
[CmdletBinding()] param()
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[B] Boot & firmware trust'
try {
if (Confirm-SecureBootUEFI) { Write-Host ' Secure Boot: ENABLED' }
else { Write-Warning ' Secure Boot is DISABLED - enable + enrol custom keys in UEFI setup.' }
} catch { Write-Warning " Secure Boot state unavailable (legacy/CSM?): $_" }
# TODO-M1: stage SilverMetal PK/KEK/db (retain Microsoft UEFI CA for option ROMs) to a known path
# for KeyTool/manual enrollment; document the firmware-side procedure.
# REMINDER (manual, NOT scriptable here): set a BIOS admin password; disable PXE/legacy/CSM;
# verify enrolled keys survive a GPD BIOS update (open question, hardening-spec.md §8).
Write-Host ' [B] staged (firmware enrollment is a documented manual step)'

View File

@@ -0,0 +1,28 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain C: Data at rest (crown jewel)
BitLocker XTS-AES-256 with TPM + PIN. NEVER TPM-only: the faulTPM class
extracts the VMK from the AMD fTPM; a PIN forces an offline brute-force.
The PIN is set INTERACTIVELY by the user (cannot be shipped in an image).
Spec: ../hardening-spec.md (C) | SCAFFOLD (M1): run on the unit.
#>
[CmdletBinding()] param([string]$MountPoint = $env:SystemDrive)
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[C] Data at rest (BitLocker TPM+PIN)'
# Enforce TPM+PIN at startup and forbid cloud recovery escrow via policy.
$fve = 'HKLM:\SOFTWARE\Policies\Microsoft\FVE'
New-Item $fve -Force | Out-Null
Set-ItemProperty $fve -Name UseAdvancedStartup -Type DWord -Value 1 # require startup auth
Set-ItemProperty $fve -Name UseTPMPIN -Type DWord -Value 1 # TPM+PIN required
Set-ItemProperty $fve -Name UseTPM -Type DWord -Value 2 # TPM-only NOT allowed
Set-ItemProperty $fve -Name EnableNonTPM -Type DWord -Value 0
Set-ItemProperty $fve -Name MinimumPIN -Type DWord -Value 8 # enhanced PIN length
Set-ItemProperty $fve -Name OSEncryptionType -Type DWord -Value 1 # full (not used-space-only)
# No Microsoft-account / AD escrow of recovery key:
Set-ItemProperty $fve -Name OSManageDRA -Type DWord -Value 0
# TODO-M1 (interactive on the unit): prompt the user for a >=8-char enhanced PIN, then:
# Enable-BitLocker -MountPoint $MountPoint -EncryptionMethod XtsAes256 -TpmAndPinProtector -Pin $securePin
# Add a recovery password and store it OFFLINE (SilverKeys), never cloud-escrowed.
Write-Host " [C] policy set (TPM+PIN required, TPM-only blocked). PIN enrollment = interactive."

View File

@@ -0,0 +1,38 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain D: Kernel & credential isolation
VBS + HVCI + Credential Guard + LSA protection + Kernel DMA Protection.
The genuinely strong, hardware-backed part of hardened Windows.
Spec: ../hardening-spec.md (D) | SCAFFOLD (M1).
#>
[CmdletBinding()] param()
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[D] Kernel & credential isolation'
# VBS + HVCI (Memory Integrity)
$dg = 'HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard'
New-Item $dg -Force | Out-Null
Set-ItemProperty $dg -Name EnableVirtualizationBasedSecurity -Type DWord -Value 1
Set-ItemProperty $dg -Name RequirePlatformSecurityFeatures -Type DWord -Value 1 # Secure Boot
$hvci = "$dg\Scenarios\HypervisorEnforcedCodeIntegrity"
New-Item $hvci -Force | Out-Null
Set-ItemProperty $hvci -Name Enabled -Type DWord -Value 1
# Credential Guard
$lsacfg = "$dg\Scenarios\CredentialGuard"
New-Item $lsacfg -Force | Out-Null
Set-ItemProperty $lsacfg -Name Enabled -Type DWord -Value 1
# LSA protection (RunAsPPL)
$lsa = 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa'
Set-ItemProperty $lsa -Name RunAsPPL -Type DWord -Value 1
# Kernel DMA Protection: on AMD this is firmware-gated (ACPI IVRS DMA_REMAP bit).
# Block new DMA devices while locked as the compensating control (see Domain G).
$ki = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Kernel DMA Protection'
New-Item $ki -Force | Out-Null
Set-ItemProperty $ki -Name DeviceEnumerationPolicy -Type DWord -Value 0 # block until authorized
# TODO-M1: confirm msinfo32 reports VBS=Running + Credential Guard + HVCI after reboot;
# confirm whether Kernel DMA Protection shows On (IVRS bit) — open question §8.
Write-Host ' [D] policy set (VBS/HVCI/CredGuard/LSA-PPL/DMA). Effective after reboot.'

View File

@@ -0,0 +1,36 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain E: Application control
WDAC (App Control) AUDIT-first then enforce; Defender ASR at max; Defender
on for detection but sample submission OFF (privacy); SmartScreen; CFA.
Balanced posture = audit before enforce (don't brick the dev workflow).
Spec: ../hardening-spec.md (E) | SCAFFOLD (M1).
#>
[CmdletBinding()] param()
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[E] Application control'
# --- Defender: detection on, but do NOT exfiltrate user files ---
Set-MpPreference -MAPSReporting Advanced
Set-MpPreference -SubmitSamplesConsent 2 # 2 = never send samples
Set-MpPreference -PUAProtection Enabled
Set-MpPreference -EnableControlledFolderAccess Enabled
# --- ASR rules at max (Block) ---
$asr = @{
'BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550'=1 # block executable content from email/webmail
'9E6C4E1F-7D60-472F-BA1A-A39EF669E4B2'=1 # block credential stealing from lsass
'D4F940AB-401B-4EFC-AADC-AD5F3C50688A'=1 # block Office child processes
'3B576869-A4EC-4529-8536-B80A7769E899'=1 # block Office executable content creation
'5BEB7EFE-FD9A-4556-801D-275E5FFC04CC'=1 # block obfuscated scripts
'D3E037E1-3EB8-44C8-A917-57927947596D'=1 # block JS/VBS launching downloaded content
'B2B3F03D-6A65-4F7B-A9C7-1C7EF74A9BA4'=1 # block untrusted/unsigned from USB
}
foreach ($id in $asr.Keys) { Add-MpPreference -AttackSurfaceReductionRules_Ids $id -AttackSurfaceReductionRules_Actions $asr[$id] }
# --- WDAC: deploy base policy in AUDIT first ---
# TODO-M1: compile ..\wdac\silvermetal-base.xml -> .cip in AUDIT mode (option 3 'Audit Mode' set),
# stage to C:\Windows\System32\CodeIntegrity\CiPolicies\Active, CiTool --refresh.
# After a real-usage shakedown, regenerate from audit events and PROMOTE to enforce.
Write-Warning ' WDAC base policy authoring is M1 (audit) -> M2 (enforce). Not yet deployed.'
Write-Host ' [E] Defender+ASR applied; WDAC pending policy authoring.'

View File

@@ -0,0 +1,31 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain F: Network & radios
Distrust the network: firewall default-deny inbound, encrypted DNS, kill
LAN name-resolution leak vectors, WiFi-only (no baseband module). SilverVPN
always-on kill-switch is installed by 08-stack-install.ps1.
Spec: ../hardening-spec.md (F) | SCAFFOLD (M1).
#>
[CmdletBinding()] param()
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[F] Network & radios'
# Firewall: default-deny inbound on all profiles.
Set-NetFirewallProfile -Profile Domain,Public,Private -DefaultInboundAction Block -DefaultOutboundAction Allow -Enabled True
# Disable SMBv1 + LAN name-resolution leak vectors.
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart -EA SilentlyContinue | Out-Null
$dns = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient'
New-Item $dns -Force | Out-Null
Set-ItemProperty $dns -Name EnableMulticast -Type DWord -Value 0 # LLMNR off
$nbt = 'HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters'
Set-ItemProperty $nbt -Name NodeType -Type DWord -Value 2 # NetBIOS: P-node (no broadcast)
# Encrypted DNS (DoH) auto + WPAD off.
$doh = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient'
Set-ItemProperty $doh -Name DoHPolicy -Type DWord -Value 3 # require DoH
Set-Service WinHttpAutoProxySvc -StartupType Disabled -EA SilentlyContinue
# TODO-M1: configure DoH server template; verify NO WWAN adapter present (we do not fit the
# 4G/5G baseband module); disable Bluetooth radio unless in use.
Write-Host ' [F] firewall default-deny, SMB1 off, LLMNR/NetBIOS/WPAD off, DoH required.'

View File

@@ -0,0 +1,32 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain G: Physical & lock-screen hygiene
Theft is threat #1 for a pocket device. Short auto-lock, PIN on wake, block
DMA while locked, prefer hibernate, no HW kill switch (software cam/mic).
Spec: ../hardening-spec.md (G) | SCAFFOLD (M1).
#>
[CmdletBinding()] param()
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[G] Physical & lock-screen hygiene'
# Auto-lock: machine inactivity limit (seconds) + require password on wake.
$sys = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
New-Item $sys -Force | Out-Null
Set-ItemProperty $sys -Name InactivityTimeoutSecs -Type DWord -Value 120 # lock after 2 min idle
$pol = 'HKLM:\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51'
New-Item $pol -Force | Out-Null
Set-ItemProperty $pol -Name ACSettingIndex -Type DWord -Value 1 # require password on wake (AC)
Set-ItemProperty $pol -Name DCSettingIndex -Type DWord -Value 1 # ... and on battery
# Block new DMA-capable devices while the screen is locked (compensates if firmware
# Kernel DMA Protection is absent - see Domain D / open question §8).
$fve = 'HKLM:\SOFTWARE\Policies\Microsoft\FVE'
New-Item $fve -Force | Out-Null
Set-ItemProperty $fve -Name DisableExternalDMAUnderLock -Type DWord -Value 1
# Prefer hibernate over sleep (keys not left resident in RAM as long).
powercfg /hibernate on 2>$null
# TODO-M1: set lid-close + idle -> hibernate via powercfg; deny camera/mic per-app
# (Device Manager disable is the stopgap; the Pocket 4 has NO hardware kill switch).
# NOTE: SilverDuress (Stack, v1.1) provides duress-PIN / panic-wipe - installed by module 08.
Write-Host ' [G] auto-lock=120s, password-on-wake, DMA-blocked-while-locked, hibernate on.'

View File

@@ -0,0 +1,36 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Domain H: Privacy minimisation & update integrity
Trim telemetry tasks/services at GP+service+firewall layers. Do NOT block
Microsoft domains in the hosts file (breaks Windows Update; violates
design-principle #13). Keep Windows Update ON. Publish residual telemetry.
Spec: ../hardening-spec.md (H) | SCAFFOLD (M1).
#>
[CmdletBinding()] param()
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[H] Privacy minimisation & update integrity'
# Disable telemetry/feedback scheduled tasks (keep update/time/security tasks).
$tasks = @(
'\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser'
'\Microsoft\Windows\Application Experience\ProgramDataUpdater'
'\Microsoft\Windows\Customer Experience Improvement Program\Consolidator'
'\Microsoft\Windows\Customer Experience Improvement Program\UsbCeip'
'\Microsoft\Windows\Feedback\Siuf\DmClient'
)
foreach ($t in $tasks) { Disable-ScheduledTask -TaskPath (Split-Path $t) -TaskName (Split-Path $t -Leaf) -EA SilentlyContinue | Out-Null }
# CEIP off.
$sqm = 'HKLM:\SOFTWARE\Policies\Microsoft\SQMClient\Windows'
New-Item $sqm -Force | Out-Null; Set-ItemProperty $sqm -Name CEIPEnable -Type DWord -Value 0
# Windows Update STAYS ON (update-or-die). We minimise telemetry, never patching.
Get-Service wuauserv | Set-Service -StartupType Automatic
# Guard: assert the hosts file contains no Microsoft update/licensing domains (anti-footgun).
$hosts = Get-Content "$env:windir\System32\drivers\etc\hosts" -EA SilentlyContinue
if ($hosts -match 'microsoft\.com|windowsupdate|msftncsi|login\.live') {
Write-Warning ' hosts file blocks Microsoft domains - REMOVE (breaks Windows Update).'
}
# TODO-M1: run tests\telemetry-leak test; document the irreducible residual (we publish, not claim zero).
Write-Host ' [H] telemetry tasks/CEIP off; Windows Update preserved.'

View File

@@ -0,0 +1,27 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | SilverLABS Application Stack
The Stack is the spine (design-principle #7). Install native Windows builds
and set SilverBrowser default + SilverVPN always-on kill-switch.
Spec: ../hardening-spec.md (#4) | SCAFFOLD (M4): some components are
Linux-MVP today (windows/README.md) - their Windows builds may lag.
#>
[CmdletBinding()] param([string]$StackDir = "$PSScriptRoot\..\stack-installer")
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
Write-Host '[Stack] SilverLABS Application Stack'
# Component -> hardening-spec mapping:
# SilverBrowser (A,H) default browser | SilverVPN (F) always-on kill-switch
# SilverSync (A) replaces OneDrive | SilverChat (F) E2EE over VPN
# SilverDuress (G) duress/panic-wipe | SilverKeys (C,A) pwd/2FA + offline BL recovery key
$components = 'SilverBrowser','SilverVPN','SilverSync','SilverChat','SilverDuress','SilverKeys'
foreach ($c in $components) {
# TODO-M4: install $StackDir\$c\*.msi/.exe silently; verify signature against the
# SilverLABS signing key (trust-model.md) before install.
Write-Warning " $c install pending native Windows build (M4)."
}
# TODO-M4: set SilverBrowser as default http/https handler; enable SilverVPN kill-switch
# (no plaintext fallback); register SilverDuress.
Write-Host ' [Stack] mapping staged; installs land at M4.'

View File

@@ -0,0 +1,59 @@
#Requires -Version 5.1
<# SilverMetal Enhanced - Windows | Verification
Asserts the hardening-spec.md verification gates and emits a report. Evidence
before assertions: each check reports the observed value, not a claim.
Spec: ../hardening-spec.md (§6) | SCAFFOLD (M1): fill remaining gates.
Exit code 0 = all pass; non-zero = count of failed gates.
#>
[CmdletBinding()] param([string]$ReportPath = "$env:ProgramData\SilverMetal\verify-report.json")
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Continue'
$results = [ordered]@{}
function Test-Gate { param([string]$Name,[scriptblock]$Check)
try { $v = & $Check; $results[$Name] = @{ pass = [bool]$v.pass; detail = $v.detail } }
catch { $results[$Name] = @{ pass = $false; detail = "error: $_" } }
}
Test-Gate 'Telemetry=Security(0)' {
$v = (Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection' -Name AllowTelemetry -EA Stop).AllowTelemetry
@{ pass = ($v -eq 0); detail = "AllowTelemetry=$v" }
}
Test-Gate 'BitLocker XtsAes256 + TpmPin' {
$bl = Get-BitLockerVolume -MountPoint $env:SystemDrive -EA Stop
$hasPin = ($bl.KeyProtector.KeyProtectorType -contains 'TpmPin')
@{ pass = ($bl.ProtectionStatus -eq 'On' -and $bl.EncryptionMethod -eq 'XtsAes256' -and $hasPin)
detail = "$($bl.ProtectionStatus)/$($bl.EncryptionMethod)/TpmPin=$hasPin" }
}
Test-Gate 'VBS + HVCI + CredentialGuard running' {
$dg = Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard -EA Stop
$svc = $dg.SecurityServicesRunning
@{ pass = (($svc -contains 1) -and ($svc -contains 2)); detail = "running=$($svc -join ',')" }
}
Test-Gate 'WDAC enforced' {
$dg = Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard -EA Stop
@{ pass = ($dg.CodeIntegrityPolicyEnforcementStatus -eq 2)
detail = "enforcement=$($dg.CodeIntegrityPolicyEnforcementStatus) (2=enforced,1=audit)" }
}
Test-Gate 'Secure Boot enabled' {
@{ pass = (Confirm-SecureBootUEFI); detail = 'Confirm-SecureBootUEFI' }
}
Test-Gate 'Firewall default-deny inbound' {
$p = Get-NetFirewallProfile -EA Stop
@{ pass = -not ($p.DefaultInboundAction -contains 'Allow'); detail = ($p.DefaultInboundAction -join ',') }
}
Test-Gate 'Windows Update healthy' {
$s = Get-Service wuauserv -EA Stop
@{ pass = ($s.StartType -ne 'Disabled'); detail = "$($s.Status)/$($s.StartType)" }
}
# TODO-M1: VPN kill-switch egress test; telemetry-leak capture; Stack functional check.
$pass = ($results.Values | Where-Object { $_.pass }).Count
$fail = ($results.Values | Where-Object { -not $_.pass }).Count
New-Item (Split-Path $ReportPath) -ItemType Directory -Force -EA SilentlyContinue | Out-Null
$results | ConvertTo-Json -Depth 4 | Set-Content $ReportPath
$results.GetEnumerator() | ForEach-Object {
$c = if ($_.Value.pass) { 'Green' } else { 'Red' }
Write-Host ("[{0}] {1} - {2}" -f ($(if($_.Value.pass){'PASS'}else{'FAIL'}), $_.Key, $_.Value.detail)) -ForegroundColor $c
}
Write-Host "`n$pass passed, $fail failed. Report: $ReportPath"
exit $fail

View File

@@ -0,0 +1,17 @@
# windows/installer
The custom packed-ISO build pipeline. See [`../iso-builder.md`](../iso-builder.md) for the design.
| File | Role |
|---|---|
| `build.ps1` | Pipeline orchestrator (7 stages). Run on Windows + Windows ADK. |
| `inputs.manifest.json` | Pinned inputs — base ISO SHA-256, driver-pack/Stack/tool versions. The Microsoft ISO is an **input, never committed**. |
| `autounattend/autounattend.xml` | OOBE automation — local account (no MSA), regional, BitLocker-ready disk layout, hands off to first-boot. |
| `oem/SetupComplete.cmd` | First-boot entry point — runs the shared `../hardening/` modules, then schedules `Verify`. |
**Usage (M2+):**
```powershell
.\build.ps1 -SourceIso 'D:\Win11_IoT_Enterprise_LTSC_x64.iso'
```
Current status: **M0 scaffold** — stages 27 throw `NotImplemented` until M2/M3.

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SilverMetal Enhanced - Windows : Windows 11 IoT Enterprise LTSC answer file.
Purpose: automate OOBE, force a LOCAL account (no Microsoft Account / no cloud
key escrow), set regional defaults, prepare a BitLocker-ready disk layout, and
hand off to $OEM$\SetupComplete.cmd for first-boot hardening.
SCAFFOLD (M0). Disk layout + image selectors are filled at M2 against the
licensed media. Do NOT embed product keys, PINs, or secrets here.
Design: ../../iso-builder.md Controls: ../../hardening-spec.md (domains A, C)
-->
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SetupUILanguage><UILanguage>en-GB</UILanguage></SetupUILanguage>
<InputLocale>0809:00000809</InputLocale>
<SystemLocale>en-GB</SystemLocale>
<UILanguage>en-GB</UILanguage>
<UserLocale>en-GB</UserLocale>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<!-- TODO-M2: DiskConfiguration (GPT, ESP + MSR + Windows), single GPT disk, BitLocker-ready.
ImageInstall/OSImage/InstallFrom MetaData = IoT Enterprise LTSC index (see inputs.manifest.json). -->
<UserData>
<ProductKey><!-- TODO-M2: IoT Enterprise LTSC key, build-time injected; NOT committed --></ProductKey>
<AcceptEula>true</AcceptEula>
</UserData>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens> <!-- force local account -->
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<ProtectYourPC>3</ProtectYourPC> <!-- disable "send data" express settings -->
</OOBE>
<UserAccounts>
<!-- TODO-M2: provision a local admin (no MSA). Password set at provisioning, not committed. -->
<LocalAccounts>
<LocalAccount wcm:action="add" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<Name>silvermetal</Name>
<Group>Administrators</Group>
<DisplayName>SilverMetal</DisplayName>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<Order>1</Order>
<CommandLine>cmd /c C:\Windows\Setup\Scripts\SetupComplete.cmd</CommandLine>
<Description>SilverMetal first-boot hardening</Description>
</SynchronousCommand>
</FirstLogonCommands>
</component>
</settings>
</unattend>

100
windows/installer/build.ps1 Normal file
View File

@@ -0,0 +1,100 @@
#Requires -Version 5.1
<#
.SYNOPSIS
SilverMetal Enhanced - Windows : custom packed ISO build pipeline.
.DESCRIPTION
Turns an official Windows 11 IoT Enterprise LTSC ISO (an INPUT, never
redistributed) plus the SilverMetal config layer into a hardened, branded,
UEFI-bootable ISO with a signed build attestation.
Design: ../iso-builder.md Controls: ../hardening-spec.md
Build host requirement: Windows + Windows ADK (DISM + oscdimg).
.NOTES
SCAFFOLD (M0). Stage bodies are stubbed; they are fleshed out at M2.
Each stage maps 1:1 to iso-builder.md section 3.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)] [string] $SourceIso, # licensed IoT Enterprise LTSC ISO
[string] $Manifest = "$PSScriptRoot\inputs.manifest.json",
[string] $WorkDir = "$env:TEMP\silvermetal-build",
[string] $OutputIso = "$PSScriptRoot\out\SilverMetal-Enhanced-Windows.iso",
[switch] $SkipInputVerify
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Write-Stage { param([string]$Msg) Write-Host "==> $Msg" -ForegroundColor Cyan }
# --- 1. Verify input -------------------------------------------------------
function Invoke-VerifyInput {
Write-Stage 'Stage 1: verify input ISO against pinned manifest'
$m = Get-Content $Manifest -Raw | ConvertFrom-Json
$expected = $m.baseImage.isoSha256
if ($SkipInputVerify -or $expected -like 'TODO*') {
Write-Warning 'Input hash not pinned yet (M2). Skipping verification.'
return
}
$actual = (Get-FileHash -Algorithm SHA256 -Path $SourceIso).Hash
if ($actual -ne $expected) { throw "Source ISO SHA-256 mismatch.`n expected: $expected`n actual: $actual" }
Write-Host ' ISO hash verified.'
}
# --- 2. Extract ------------------------------------------------------------
function Invoke-Extract {
Write-Stage 'Stage 2: extract ISO to work dir'
# TODO-M2: mount $SourceIso, copy contents to $WorkDir\iso, export install.wim to $WorkDir\wim
throw 'NotImplemented (M2): extract'
}
# --- 3. Service the WIM offline (DISM) -------------------------------------
function Invoke-ServiceWim {
Write-Stage 'Stage 3: offline-service install.wim (drivers, updates, debloat, baseline policy, Stack staging)'
# TODO-M2: DISM /Mount-Image; /Add-Driver (windows\drivers); /Add-Package (cumulative);
# remove appx from windows\debloat; load offline hives + apply windows\policies baseline;
# stage Stack + $OEM$ payload; /Unmount-Image /Commit
throw 'NotImplemented (M2): service WIM'
}
# --- 4. Inject answer file + first-boot payload ----------------------------
function Invoke-InjectUnattend {
Write-Stage 'Stage 4: inject autounattend.xml + $OEM$\SetupComplete.cmd + hardening modules'
# TODO-M2: copy autounattend\autounattend.xml to ISO root; lay $OEM$\SetupComplete.cmd
# + windows\hardening\* into the image so first boot can run them
throw 'NotImplemented (M2): inject unattend'
}
# --- 5. Brand --------------------------------------------------------------
function Invoke-Brand {
Write-Stage 'Stage 5: apply branding (boot/OOBE wallpaper, computer-name pattern)'
# TODO-M4: from ..\..\shared\branding
Write-Warning ' Branding deferred to M4.'
}
# --- 6. Repack -------------------------------------------------------------
function Invoke-Repack {
Write-Stage 'Stage 6: repack UEFI-bootable ISO via oscdimg'
# TODO-M2: oscdimg -m -o -u2 -udfver102 -bootdata:2#... -> $OutputIso
throw 'NotImplemented (M2): repack'
}
# --- 7. Attest -------------------------------------------------------------
function Invoke-Attest {
Write-Stage 'Stage 7: emit SHA-256 + SBOM + signed build attestation'
# TODO-M3: hash $OutputIso; build SBOM from manifest + tool versions; sign (trust-model.md)
throw 'NotImplemented (M3): attest'
}
# --- orchestrate -----------------------------------------------------------
Invoke-VerifyInput
Invoke-Extract
Invoke-ServiceWim
Invoke-InjectUnattend
Invoke-Brand
Invoke-Repack
Invoke-Attest
Write-Host "`nBuild complete: $OutputIso" -ForegroundColor Green

View File

@@ -0,0 +1,38 @@
{
"$comment": "Pinned inputs for a reproducible SilverMetal Enhanced - Windows ISO build. The base Windows ISO is licensed and NEVER committed; it is referenced by SHA-256 only. Fill the TODO hashes/versions at M2 against the actual licensed media and driver pack.",
"schemaVersion": 1,
"product": "SilverMetal Enhanced - Windows",
"referenceDevice": "GPD Pocket 4 (AMD Ryzen AI 9 HX 370 / Strix Point)",
"baseImage": {
"edition": "Windows 11 IoT Enterprise LTSC",
"arch": "x64",
"isoSha256": "TODO-M2-pin-against-licensed-media",
"wimImageName": "Windows 11 IoT Enterprise LTSC",
"wimImageIndex": null
},
"driverPack": {
"name": "GPD Pocket 4 driver pack",
"version": "TODO-M2",
"sha256": "TODO-M2",
"source": "https://gpd.hk (verify) — confirm redistribution terms"
},
"cumulativeUpdate": {
"kb": "TODO-M2-latest-at-build",
"sha256": "TODO-M2"
},
"stack": {
"$comment": "Native Windows builds; some components are Linux-MVP per windows/README.md and may lag.",
"SilverBrowser": "TODO",
"SilverVPN": "from SilverLABS/SilverVPN (MAUI Windows client)",
"SilverSync": "TODO",
"SilverChat": "from SilverVPN.Client.Chat",
"SilverDuress": "TODO",
"SilverKeys": "TODO"
},
"tooling": {
"$comment": "Recorded for the build attestation (reproducibility scope: pinned inputs + recorded tools + output SHA + SBOM; not bit-identical).",
"windowsAdk": "TODO-M2",
"dism": "TODO-M2",
"oscdimg": "TODO-M2"
}
}

View File

@@ -0,0 +1,32 @@
@echo off
REM ===========================================================================
REM SilverMetal Enhanced - Windows : first-boot entry point.
REM Invoked once by autounattend.xml FirstLogonCommands. Runs the shared
REM hardening/ modules in order, logs to disk, then schedules verification.
REM
REM The hardening/ modules are staged into C:\Windows\Setup\Scripts\hardening
REM by build.ps1 (stage 4). They are SHARED with the self-apply track.
REM
REM Design: ../../iso-builder.md Controls: ../../hardening-spec.md
REM SCAFFOLD (M0): module bodies stubbed; safe to run (modules log and no-op
REM until implemented at M1).
REM ===========================================================================
set LOG=C:\Windows\Setup\Scripts\silvermetal-firstboot.log
set HARD=C:\Windows\Setup\Scripts\hardening
echo [%DATE% %TIME%] SilverMetal first-boot start >> "%LOG%"
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"$ErrorActionPreference='Stop';" ^
"Get-ChildItem '%HARD%\0*.ps1' | Sort-Object Name | ForEach-Object {" ^
" Write-Host \"--> $($_.Name)\";" ^
" & $_.FullName *>> '%LOG%'" ^
"}" >> "%LOG%" 2>&1
REM Register the verification task to run after the first full boot/login.
schtasks /Create /TN "SilverMetal\Verify" /SC ONLOGON /RL HIGHEST /F ^
/TR "powershell -NoProfile -ExecutionPolicy Bypass -File %HARD%\Verify-SilverMetalWindows.ps1" >> "%LOG%" 2>&1
echo [%DATE% %TIME%] SilverMetal first-boot done >> "%LOG%"
exit /b 0

131
windows/iso-builder.md Normal file
View File

@@ -0,0 +1,131 @@
# 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)?

View File

@@ -0,0 +1,9 @@
# windows/policies
Group Policy / ADMX exports and the **offline-applicable baseline** (`.reg` / `.pol`)
that `build.ps1` applies into the WIM via offline hive editing (telemetry floor,
service disables). The online/runtime policy is applied by the `../hardening/`
modules at first boot.
Populated at **M2** by exporting the prototype unit's applied policy
(`LGPO.exe` / registry export) after the `hardening/` modules run on the device.

View File

@@ -0,0 +1,16 @@
# windows/stack-installer
Native Windows installers for the SilverLABS Application Stack, staged into the
image and run by [`../hardening/08-stack-install.ps1`](../hardening/08-stack-install.ps1).
| Component | hardening-spec mapping | Status |
|---|---|---|
| SilverBrowser | A, H (default browser) | Linux MVP — Windows build TBD |
| SilverVPN | F (always-on kill-switch) | Existing — MAUI Windows client (`SilverLABS/SilverVPN`) |
| SilverSync | A (replaces OneDrive) | Linux MVP — Windows build TBD |
| SilverChat | F (E2EE over VPN) | Existing (`SilverVPN.Client.Chat`) |
| SilverDuress | G (duress / panic-wipe) | v1.1 |
| SilverKeys | C, A (pwd/2FA + offline BL recovery key) | v1.1 |
Installers must be **signature-verified against the SilverLABS signing key**
([`../../docs/trust-model.md`](../../docs/trust-model.md)) before install. Lands at **M4**.

14
windows/tests/README.md Normal file
View File

@@ -0,0 +1,14 @@
# windows/tests
Verification gates for a SilverMetal Enhanced — Windows build
([`../hardening-spec.md`](../hardening-spec.md) §6).
| Test | What it proves | Status |
|---|---|---|
| **Hardening-baseline** | All control gates pass | [`../hardening/Verify-SilverMetalWindows.ps1`](../hardening/Verify-SilverMetalWindows.ps1) (M1) |
| **Telemetry-leak** | Captures egress on a clean build; classifies every Microsoft contact; **publishes the residual** (we do not claim zero) | TODO-M3 |
| **VPN kill-switch** | Tunnel-drop → zero egress | TODO-M1 |
| **Update path** | A test update applies + rolls back (update-or-die) | TODO-M3 |
The telemetry-leak test is the honesty gate: it documents the minimum-feasible
Microsoft contact that remains, per design-principle #2.

11
windows/wdac/README.md Normal file
View File

@@ -0,0 +1,11 @@
# windows/wdac
WDAC (App Control for Business) policy — the **primary**, kernel-enforced
application-control engine for SilverMetal Enhanced — Windows. AppLocker is the
documented fallback only.
**Workflow (design-principle: balanced / audit-first):**
1. **M1** — author `silvermetal-base.xml` and deploy in **AUDIT** mode on the prototype unit; run real workloads; collect `CodeIntegrity` audit events.
2. **M2** — regenerate the policy from audit events (Windows + Stack + approved dev tools signed/allowed), compile to `.cip`, and **PROMOTE to ENFORCE**.
The base policy ships pre-authored in the SKU; the prototype builds it from its own audit logs. See [`../hardening-spec.md`](../hardening-spec.md) Domain E.