Sigroom Docs

Windows Secure WSL Setup

Start here for Windows. Sigroom keeps the normal Ubuntu distribution unchanged and imports a separate signed appliance for windows.wsl2.runsc.

draftWindows operators and release administratorsVerified 2026-08-02

Choose One Setup Path

GoalWhat the user runsTrust source
Sigroom already runs on localhost in ordinary Ubuntu WSLRun onboard-wsl-hacp.ps1 once from native Windows PowerShell. It boots Ubuntu and invokes its Bash worker automatically.A reviewed appliance may be tested locally, or a separately consented development identity may build one. The wizard still runs unsigned source as setup-l4-windows.source.ps1 and is never the shared or production bootstrap.
Connect to hosted Sigroom or an enterprise HTTPS originDownload the production bootstrap set, verify the detached evidence signature with the independently pinned descriptor, verify Authenticode and the signer-certificate pin, then invoke setup-l4-windows.ps1 from disk.A timestamped Authenticode installer, release-key-signed evidence, a published HACP_RUNTIME_APPLIANCE/2 release, and separately reviewed pins.
Build or publish a production applianceUse the release-maintainer pipeline, then publish only signed outputs and public trust material.Offline, HSM, KMS, or otherwise organization-controlled signing identities reviewed outside client onboarding.
Do not install linux.runsc.l4 from a normal WSL shell.Failed seccomp or network-isolation probes are never waived. The supported Windows route is the dedicated windows.wsl2.runsc appliance.

Choose The Source Toolkit Or Signed Production Set

For source/local development, obtain sigroom-wsl-hacp-onboarding.zip and its checksum from Sigroom's Downloads page. The checksum detects transfer corruption; it is not a signature or publisher identity. The ZIP and setup-l4-windows.source.ps1 are explicitly unsigned source and do not replace a full checkout. The signed setup-l4-windows.ps1 is never inside that ZIP. Hosted clients separately download setup-l4-windows.ps1, its Authenticode evidence and evidence signature, the signer declaration, sigroom-appliance-release-verification-key.json, and sigroom-appliance-release-public.pem. They independently obtain both the expected signer-certificate SHA-256 and exact verification-descriptor file SHA-256. The descriptor authenticates the RSA key used to verify the detached evidence signature before evidence is parsed; native validation then requires Get-AuthenticodeSignature status Valid and verifies the actual signer certificate. Never use iwr | iex. The links below are public examples; self-hosted deployments serve the same bounded filenames from their own API origin. Internal workers are linked for source audit and are not separate onboarding steps. Downloads contain no production private signing keys, provider credentials, enrollment secrets, or invented TPM trust bundle.

DistributionFileRole
Source ZIP and raw sourceonboard-wsl-hacp.ps1The sole interactive localhost entrypoint. Run it from native Windows PowerShell with a full Sigroom checkout in ordinary Ubuntu WSL.
Signed production download onlysetup-l4-windows.ps1The externally Authenticode-signed hosted installer. It is published only with matching release-key-signed evidence and is never inside the source ZIP.
Source ZIP and raw sourcesetup-l4-windows.source.ps1Unsigned source for review and explicit localhost development consent; never a hosted installer.
Source ZIP and raw sourceexport-windows-bootstrap-authenticode-evidence.ps1Windows release-host evidence exporter; not an end-user installer.
Source ZIP and raw sourceretire-l4-windows-appliance.ps1The evidence-gated retirement command for a marked appliance.
Source ZIP and raw sourceonboard-wsl-hacp.shAn internal ordinary-Ubuntu worker invoked by the PowerShell entrypoint; do not run it separately.
Source ZIP and raw sourcesetup-wsl-hacp-e2e.shAn internal CI and recovery wrapper. Hosted use requires the complete signed bootstrap set; its localhost source exception is explicit and never creates the canonical hosted filename.
Source ZIP and raw sourcecomplete-managed-onboarding.shA measured guest worker invoked by the Windows installer; do not enter the appliance to run it.

Localhost: Run One PowerShell Command

Keep the raw local Sigroom stack running in the ordinary Ubuntu distro. Launch this command in a native Windows PowerShell window so the host process survives any mirrored-networking WSL restart. The wizard asks for missing paths, features, consent to run the exact checked-in source under its .source.ps1 name, L4/L5 choice, enrollment, and optional model-broker settings in the same terminal. Hosted releases do not use that development exception.

powershell
powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File "\\wsl.localhost\<Ubuntu-distro>\home\<linux-user>\code\teamwork\ops\hacp-control\onboard-wsl-hacp.ps1"
Resume instead of starting over.Exit code 10 means Windows or WSL must restart. Exit code 11 means enrollment awaits a different administrator's approval. Rerun the identical PowerShell command in either case.

Hosted Or Enterprise: Verify Before Execution

Download every file to disk; never pipe a web response into execution. Obtain both the signer-certificate SHA-256 and verification-descriptor file SHA-256 from administrator-controlled channels independent of the download bucket. Hash the descriptor before parsing it, bind it to the PEM, and verify the exact evidence bytes with RSA-PSS-SHA256 before parsing evidence. Get-AuthenticodeSignature must then be Valid and SignerCertificate.RawData must match the independent signer pin. Published checksum files are comparison aids, not independent pins. The deployed Downloads page consumes windows_wsl_setup_endpoints from the API catalog and passes -ApiUrl from API_PUBLIC_URL, -GatewayUrl from GATEWAY_PUBLIC_URL, and -ArtifactUrl from API_PUBLIC_URL. Manual self-hosted commands may use a different reviewed artifact origin.

powershell
$ExpectedSignerSha256 = (Read-Host 'Paste the independently reviewed installer signer-certificate SHA-256').Trim().ToLowerInvariant()
$ExpectedDescriptorSha256 = (Read-Host 'Paste the independently reviewed verification-descriptor file SHA-256').Trim().ToLowerInvariant()
if ($ExpectedSignerSha256 -notmatch '^sha256:[0-9a-f]{64}$' -or $ExpectedDescriptorSha256 -notmatch '^sha256:[0-9a-f]{64}$') { throw 'Invalid independent release pin' }
$DescriptorPath = Resolve-Path '.\sigroom-appliance-release-verification-key.json'
$ActualDescriptorSha256 = 'sha256:' + (Get-FileHash -Algorithm SHA256 -LiteralPath $DescriptorPath).Hash.ToLowerInvariant()
if ($ActualDescriptorSha256 -cne $ExpectedDescriptorSha256) { throw 'Unexpected release-verification descriptor' }
$Descriptor = Get-Content -Raw -LiteralPath $DescriptorPath | ConvertFrom-Json
if ($Descriptor.schema_version -ne 'HACP_WINDOWS_RELEASE_VERIFICATION_KEY/1' -or $Descriptor.signature_algorithm -ne 'RSA-PSS-SHA256' -or $Descriptor.public_key_pem_filename -ne 'sigroom-appliance-release-public.pem' -or $Descriptor.jwk.kty -ne 'RSA') { throw 'Invalid release-verification descriptor' }
$ActualPemSha256 = 'sha256:' + (Get-FileHash -Algorithm SHA256 -LiteralPath '.\sigroom-appliance-release-public.pem').Hash.ToLowerInvariant()
if ($ActualPemSha256 -cne $Descriptor.public_key_pem_sha256) { throw 'Release PEM does not match the pinned descriptor' }
function ConvertFrom-Base64Url([string]$Value) { $Value = $Value.Replace('-', '+').Replace('_', '/'); switch ($Value.Length % 4) { 0 {} 2 {$Value += '=='} 3 {$Value += '='} default {throw 'Invalid base64url'} }; [Convert]::FromBase64String($Value) }
$Parameters = New-Object Security.Cryptography.RSAParameters
$Parameters.Modulus = ConvertFrom-Base64Url ([string]$Descriptor.jwk.n)
$Parameters.Exponent = ConvertFrom-Base64Url ([string]$Descriptor.jwk.e)
if ($Parameters.Modulus.Length -lt 256 -or $Parameters.Modulus.Length -gt 1024 -or $Parameters.Exponent.Length -lt 1 -or $Parameters.Exponent.Length -gt 8) { throw 'RSA key is outside supported bounds' }
$EvidenceBytes = [IO.File]::ReadAllBytes((Resolve-Path '.\setup-l4-windows.ps1.authenticode.json').Path)
$EvidenceSignatureBytes = [IO.File]::ReadAllBytes((Resolve-Path '.\setup-l4-windows.ps1.authenticode.json.sig').Path)
$Verifier = New-Object Security.Cryptography.RSACng
try { $Verifier.ImportParameters($Parameters); $EvidenceSignatureValid = $Verifier.VerifyData($EvidenceBytes, $EvidenceSignatureBytes, [Security.Cryptography.HashAlgorithmName]::SHA256, [Security.Cryptography.RSASignaturePadding]::Pss) } finally { $Verifier.Dispose() }
if (-not $EvidenceSignatureValid) { throw 'Invalid detached Authenticode evidence signature' }
$Evidence = [Text.Encoding]::UTF8.GetString($EvidenceBytes) | ConvertFrom-Json
$Installer = Resolve-Path '.\setup-l4-windows.ps1'
$InstallerSha256 = 'sha256:' + (Get-FileHash -Algorithm SHA256 -LiteralPath $Installer).Hash.ToLowerInvariant()
if ($Evidence.schema_version -ne 'HACP_WINDOWS_BOOTSTRAP_AUTHENTICODE/1' -or $Evidence.signer_certificate_sha256 -cne $ExpectedSignerSha256 -or $Evidence.signed_file_sha256 -cne $InstallerSha256) { throw 'Installer does not match signed evidence' }
$Signature = Get-AuthenticodeSignature -LiteralPath $Installer
if ([string]$Signature.Status -ne 'Valid' -or -not $Signature.SignerCertificate) { throw 'Invalid Sigroom Authenticode signature' }
$Sha256 = [Security.Cryptography.SHA256]::Create()
try { $ActualSignerSha256 = 'sha256:' + (($Sha256.ComputeHash($Signature.SignerCertificate.RawData) | ForEach-Object { $_.ToString('x2') }) -join '') } finally { $Sha256.Dispose() }
if ($ActualSignerSha256 -cne $ExpectedSignerSha256) { throw 'Unexpected Authenticode signer' }
& $Installer -ManifestUrl 'https://api.example.com/downloads/runtime-appliance.json' -PublicKey '.\sigroom-appliance-release-public.pem' -ApiUrl 'https://api.example.com' -GatewayUrl 'wss://gateway.example.com/hacp/v1' -ArtifactUrl 'https://api.example.com' -Json

Production Signing Inputs Are Reviewed Outputs

Production signing happens before onboarding. Railway fails closed unless it receives an externally Authenticode-signed installer, Windows verification evidence, an RSA-PSS signature over that evidence from the appliance release key, the exact signer-certificate pin, and the reviewed appliance release/public key. The client and deployment host never receive private signing keys.

Supplied to onboardingKept outside onboarding
Timestamped Authenticode-signed setup-l4-windows.ps1 plus HACP_WINDOWS_BOOTSTRAP_AUTHENTICODE/1 evidence and detached evidence signatureAuthenticode certificate private key and appliance release private key
Signed and unexpired HACP_RUNTIME_APPLIANCE/2 manifest, detached signature, measured WSL image, SBOM, provenance, and Authenticode-valid TPM brokerRSA-PSS manifest private key and Authenticode certificate private key
RSA public key plus deterministic verification descriptor with an independently reviewed descriptor-file fingerprintSilent production key creation or replacement
Reviewed TPM manufacturer roots and intermediates when L5 is enabledUnknown endorsement roots, software-provider evidence, or an installer-generated trust decision
Published signed GeneSYS release advertising windows.wsl2.runscGeneSYS release private key on an ordinary end-user Windows machine
Development signing is not production signing.The localhost wizard can create development-only identities after explicit consent. Never promote those identities or artifacts, and never use -CreateDevelopmentRelease for a shared, hosted, or production release.

Release Team: Export Windows Verification Evidence

On an isolated Windows signing host, Authenticode-sign the reviewed setup-l4-windows.ps1 with the approved certificate and trusted timestamp service. Then run the evidence exporter against the exact checked-in source. The appliance release-signing service signs the resulting JSON bytes with RSA-PSS-SHA256 using the same exact RSA private key whose public key verifies runtime-appliance.json. Never move either private key to Railway or an onboarding machine.

powershell
.\scripts\release\export-windows-bootstrap-authenticode-evidence.ps1 `
  -SignedInstaller '.\release\setup-l4-windows.ps1' `
  -UnsignedSource '.\ops\hacp-control\setup-l4-windows.ps1' `
  -ExpectedSignerSha256 'sha256:<reviewed signer certificate SHA-256>' `
  -ReleaseSigningKeyId 'appliance-release-primary' `
  -OutputPath '.\release\setup-l4-windows.ps1.authenticode.json'

Release Team: Supply Every Reviewed Deployment Input

Production fails before tool installation, secret generation, packaging, upload, or deploy when this set is missing or partial. Production mode is the default regardless of the Railway environment name; source-only publication requires an explicit release-maintainer opt-in and never advertises a runnable hosted command. Staging verifies the evidence signature, complete installer hash and size, valid/timestamped/code-signing assertions, independently configured signer pin, and normalized payload equality with repository source. The detailed hosted guide contains the RSA-PSS evidence-signing command.

bash
scripts/ops/bootstrap-railway-release.sh --apply \
  --windows-bootstrap-release-mode production \
  --appliance-release-dir /reviewed/runtime-appliance-release \
  --appliance-public-key /reviewed/sigroom-appliance-release-public.pem \
  --windows-bootstrap-signed-installer /reviewed/setup-l4-windows.ps1 \
  --windows-bootstrap-authenticode-evidence /reviewed/setup-l4-windows.ps1.authenticode.json \
  --windows-bootstrap-authenticode-evidence-signature /reviewed/setup-l4-windows.ps1.authenticode.json.sig \
  --windows-bootstrap-signer-sha256 'sha256:<reviewed signer certificate SHA-256>'

Continue With The Detailed Guide

Source Material

  • docs/deployment/runtimes/windows-wsl2/README.md
  • docs/contracts/windows-bootstrap-authenticode-v1.md
  • docs/deployment/runtimes/windows-wsl2/operator-guide.md
  • docs/deployment/runtimes/windows-wsl2/local-development-walkthrough.md
  • docs/deployment/runtimes/windows-wsl2/hosted-deployment.md
  • ops/hacp-control/onboard-wsl-hacp.ps1
  • ops/hacp-control/onboard-wsl-hacp.sh
  • ops/hacp-control/setup-l4-windows.ps1
  • ops/hacp-control/setup-wsl-hacp-e2e.sh
  • ops/hacp-control/retire-l4-windows-appliance.ps1
  • ops/hacp-control/appliance/complete-managed-onboarding.sh
  • scripts/release/export-windows-bootstrap-authenticode-evidence.ps1
  • scripts/release/stage-windows-bootstrap-release.mjs