-
Notifications
You must be signed in to change notification settings - Fork 0
fix(phase4): track Windows acceptance host provisioning and repair bootstrap #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # The per-site operator public key is never committed to this public repository. | ||
| authorized_key.pub | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> | ||
| <settings pass="windowsPE"> | ||
| <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | ||
| <SetupUILanguage><UILanguage>en-US</UILanguage></SetupUILanguage> | ||
| <InputLocale>en-US</InputLocale><SystemLocale>en-US</SystemLocale><UILanguage>en-US</UILanguage><UserLocale>en-US</UserLocale> | ||
| </component> | ||
| <component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | ||
| <DriverPaths> | ||
| <PathAndCredentials wcm:action="add" wcm:keyValue="1"><Path>E:\vioscsi\w11\amd64</Path></PathAndCredentials> | ||
| <PathAndCredentials wcm:action="add" wcm:keyValue="2"><Path>E:\NetKVM\w11\amd64</Path></PathAndCredentials> | ||
|
Comment on lines
+10
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Define the required VirtIO media and drive order. Lines 10-11 require the VirtIO driver tree on Require and document a third medium with Windows on 🤖 Prompt for AI Agents |
||
| </DriverPaths> | ||
| </component> | ||
| <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | ||
| <DiskConfiguration> | ||
| <Disk wcm:action="add"><DiskID>0</DiskID><WillWipeDisk>true</WillWipeDisk> | ||
| <CreatePartitions> | ||
| <CreatePartition wcm:action="add"><Order>1</Order><Type>EFI</Type><Size>260</Size></CreatePartition> | ||
| <CreatePartition wcm:action="add"><Order>2</Order><Type>MSR</Type><Size>16</Size></CreatePartition> | ||
| <CreatePartition wcm:action="add"><Order>3</Order><Type>Primary</Type><Extend>true</Extend></CreatePartition> | ||
| </CreatePartitions> | ||
| <ModifyPartitions> | ||
| <ModifyPartition wcm:action="add"><Order>1</Order><PartitionID>1</PartitionID><Format>FAT32</Format><Label>System</Label></ModifyPartition> | ||
| <ModifyPartition wcm:action="add"><Order>2</Order><PartitionID>3</PartitionID><Format>NTFS</Format><Label>Windows</Label></ModifyPartition> | ||
| </ModifyPartitions> | ||
| </Disk> | ||
| </DiskConfiguration> | ||
| <ImageInstall><OSImage><InstallFrom><MetaData wcm:action="add"><Key>/IMAGE/INDEX</Key><Value>6</Value></MetaData></InstallFrom><InstallTo><DiskID>0</DiskID><PartitionID>3</PartitionID></InstallTo></OSImage></ImageInstall> | ||
| <UserData><AcceptEula>true</AcceptEula><FullName>1Helm</FullName><Organization>1Helm acceptance</Organization></UserData> | ||
| <DynamicUpdate><Enable>false</Enable><WillShowUI>OnError</WillShowUI></DynamicUpdate> | ||
| </component> | ||
| </settings> | ||
| <settings pass="specialize"> | ||
| <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | ||
| <ComputerName>ONEHELM-WIN</ComputerName><TimeZone>UTC</TimeZone><RegisteredOwner>1Helm</RegisteredOwner><RegisteredOrganization>1Helm acceptance</RegisteredOrganization> | ||
| </component> | ||
| </settings> | ||
| <settings pass="oobeSystem"> | ||
| <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | ||
| <Reseal><Mode>Audit</Mode></Reseal> | ||
| </component> | ||
| </settings> | ||
| <settings pass="auditUser"> | ||
| <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> | ||
| <RunSynchronous> | ||
| <RunSynchronousCommand wcm:action="add"><Order>1</Order><Description>Provision retained 1Helm acceptance host</Description><Path>powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$v=(Get-Volume -FileSystemLabel ONEHELM); & ($v.DriveLetter + ':\setup.ps1')"</Path><WillReboot>Never</WillReboot></RunSynchronousCommand> | ||
| </RunSynchronous> | ||
| </component> | ||
| </settings> | ||
| </unattend> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # Retained Windows acceptance-host provisioning | ||
|
|
||
| These files build the bootstrap ISO for the dedicated Windows 11 Phase 4 | ||
| acceptance host described in `docs/phase4-platform-acceptance.md`. They were | ||
| previously carried only as a pre-built ISO on the hypervisor, so a rebuild could | ||
| not be reviewed or reproduced. They are tracked here for that reason. | ||
|
|
||
| Nothing here publishes a release, creates a tag, deploys the website, or touches | ||
| production data or services. | ||
|
|
||
| ## What it does | ||
|
|
||
| `Autounattend.xml` partitions the disk (GPT, EFI + MSR + NTFS), installs the Pro | ||
| image, sets the computer name and UTC timezone, then reseals into **audit mode** | ||
| and runs `setup.ps1` during the `auditUser` pass. | ||
|
|
||
| `setup.ps1` installs the VirtIO network and serial drivers plus the QEMU guest | ||
| agent, enables OpenSSH Server pinned to the operator's public key (supplied at build | ||
| time, see below) with password authentication off, disables sleep and hibernate, and records | ||
| `C:\1HelmAcceptance\ready.json`. It is idempotent: an existing `ready.json` | ||
| makes it exit 0 immediately. | ||
|
|
||
| ## Build | ||
|
|
||
| ```sh | ||
| ./build-unattend-iso.sh 1helm-windows-unattend.iso /path/to/operator_key.pub | ||
| ``` | ||
|
|
||
| The operator public key is **not** committed: this repository is public, and | ||
| publishing which key is authorized as Administrator on the acceptance host is | ||
| needless disclosure. Pass it at build time (or via | ||
| `HELM_ACCEPTANCE_AUTHORIZED_KEY`); the build stages it as `authorized_key.pub` | ||
| on the ISO and `setup.ps1` refuses to continue without it. `.gitignore` keeps a | ||
| local copy out of git. | ||
|
|
||
| Two constraints are load-bearing: | ||
|
|
||
| - `-iso-level 4` — at genisoimage's default level the ISO9660 namespace | ||
| truncates `Autounattend.xml` to `AUTOUNAT.XML`, which Windows Setup does not | ||
| recognize as an answer file. | ||
| - Volume label `ONEHELM` — the `auditUser` pass locates `setup.ps1` with | ||
| `Get-Volume -FileSystemLabel ONEHELM`. | ||
|
|
||
| ## Host VM shape | ||
|
|
||
| The acceptance workflow restores an accepted clean snapshot before every job, so | ||
| the VM must actually be able to snapshot. Proxmox always creates the **TPM state | ||
| volume as raw**, and a raw volume on directory storage blocks snapshots for the | ||
| whole VM even when every other disk is qcow2. Place the disks as qcow2 and put | ||
| the small `tpmstate0` volume on snapshot-capable storage (thin-LVM), which keeps | ||
| TPM 2.0 and Secure Boot intact so no Windows 11 requirement bypass is needed. | ||
|
|
||
| Verify before installing anything: | ||
|
|
||
| ```sh | ||
| qm snapshot <vmid> probe && qm delsnapshot <vmid> probe | ||
| ``` | ||
|
|
||
| ## Windows 11 25H2 answer-file caveat | ||
|
|
||
| On build 26200 (25H2) the new setup engine (`setuphost.exe`) does **not** | ||
| auto-apply `Autounattend.xml` from a secondary disc, and `setup.exe /unattend:` | ||
| is ignored. The answer file is readable from WinPE — it simply is not consumed, | ||
| so setup falls through to the interactive product-key page. | ||
|
|
||
| Working alternative on affected media: from the WinPE shell (Shift+F10), | ||
| partition with `diskpart`, apply the image with | ||
| `dism /apply-image /imagefile:<media>:\sources\install.wim /index:6 /applydir:W:\`, | ||
| copy `Autounattend.xml` to `W:\Windows\Panther\unattend.xml`, then | ||
| `bcdboot W:\Windows /s S: /f UEFI`. First boot still runs `specialize`, | ||
| `oobeSystem` and `auditUser`, so the computer name, audit reseal and | ||
| `setup.ps1` all still apply. | ||
|
|
||
| Note that WinPE on this media has no `curl`, no `taskkill`, and no configured | ||
| network, so stage anything you need on the bootstrap ISO itself. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| #!/usr/bin/env bash | ||
| # Build the retained Windows acceptance-host bootstrap ISO. | ||
| # | ||
| # Attach the result as a second CD-ROM alongside the Windows installation media | ||
| # on the dedicated Phase 4 acceptance VM. It carries the answer file and the | ||
| # first-boot bootstrap; it publishes nothing and contains no credentials beyond | ||
| # the operator's own SSH public key in setup.ps1. | ||
| set -euo pipefail | ||
|
|
||
| here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| out="${1:-1helm-windows-unattend.iso}" | ||
| key="${2:-${HELM_ACCEPTANCE_AUTHORIZED_KEY:-}}" | ||
|
|
||
| if [ -z "$key" ] || [ ! -f "$key" ]; then | ||
| echo "usage: build-unattend-iso.sh [out.iso] <path-to-authorized-key.pub>" >&2 | ||
| echo " or: HELM_ACCEPTANCE_AUTHORIZED_KEY=/path/to/key.pub build-unattend-iso.sh [out.iso]" >&2 | ||
| echo "The operator public key is deliberately not committed to this public repository." >&2 | ||
| exit 2 | ||
| fi | ||
|
|
||
| stage="$(mktemp -d)" | ||
| trap 'rm -rf "$stage"' EXIT | ||
|
|
||
| cp "$here/Autounattend.xml" "$here/setup.ps1" "$stage/" | ||
| printf 'Retained Windows acceptance bootstrap for 1Helm.\n' > "$stage/1helm-acceptance.txt" | ||
| install -m 0644 "$key" "$stage/authorized_key.pub" | ||
|
|
||
| # -iso-level 4 keeps long file names. At genisoimage's default level the | ||
| # ISO9660 namespace truncates Autounattend.xml to AUTOUNAT.XML, which Windows | ||
| # Setup does not recognize as an answer file. | ||
| # | ||
| # The volume label MUST remain ONEHELM: the auditUser pass in Autounattend.xml | ||
| # locates setup.ps1 via Get-Volume -FileSystemLabel ONEHELM. | ||
| genisoimage -quiet -iso-level 4 -J -r -V ONEHELM -o "$out" "$stage" | ||
|
|
||
| echo "wrote $out" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| $ErrorActionPreference = "Stop" | ||
| $root = "C:\1HelmAcceptance" | ||
| New-Item -ItemType Directory -Force -Path $root | Out-Null | ||
| $log = Join-Path $root "bootstrap.log" | ||
| Start-Transcript -Path $log -Append | ||
| try { | ||
| if (Test-Path (Join-Path $root "ready.json")) { exit 0 } | ||
|
|
||
| $virtio = Get-Volume | Where-Object { $_.DriveLetter -and (Test-Path ("{0}:\guest-agent\qemu-ga-x86_64.msi" -f $_.DriveLetter)) } | Select-Object -First 1 | ||
| if (-not $virtio) { throw "VirtIO 0.1.271 media was not found." } | ||
| $drive = "{0}:" -f $virtio.DriveLetter | ||
| & pnputil.exe /add-driver "$drive\NetKVM\w11\amd64\*.inf" /subdirs /install | ||
| if ($LASTEXITCODE -notin 0, 3010) { throw "NetKVM driver install failed: $LASTEXITCODE" } | ||
| # The QEMU guest agent reaches the host over a VirtIO serial port. Without | ||
| # this driver the QEMU-GA service still starts and reports Running, while the | ||
| # host side ("qm agent <vmid> ping") stays dead and there is no guest-exec | ||
| # channel to provision the host with. | ||
| & pnputil.exe /add-driver "$drive\vioserial\w11\amd64\*.inf" /subdirs /install | ||
| if ($LASTEXITCODE -notin 0, 3010) { throw "VirtIO serial driver install failed: $LASTEXITCODE" } | ||
| & msiexec.exe /i "$drive\guest-agent\qemu-ga-x86_64.msi" /qn /norestart | ||
| if ($LASTEXITCODE -notin 0, 3010) { throw "QEMU guest agent install failed: $LASTEXITCODE" } | ||
|
Comment on lines
+13
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
file='ops/platform-acceptance/windows-host/setup.ps1'
rg -n -C 4 '3010|/norestart|ready\.json|Restart-Computer|shutdown\.exe' "$file"
if ! rg -qE 'Restart-Computer|shutdown\.exe.*[/-]r' "$file"; then
echo 'No explicit restart exists for an accepted 3010 result.' >&2
exit 1
fiRepository: gitcommit90/1Helm Length of output: 2426 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
file='ops/platform-acceptance/windows-host/setup.ps1'
printf '%s\n' '--- setup.ps1 ---'
cat -n "$file" | sed -n '1,75p'
printf '%s\n' '--- references to setup.ps1 and ready.json ---'
rg -n -C 3 'setup\.ps1|ready\.json|bootstrap\.log|QEMU-GA|Start-Service' . \
-g '!node_modules' -g '!dist' -g '!build'Repository: gitcommit90/1Helm Length of output: 15357 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
setup = Path("ops/platform-acceptance/windows-host/setup.ps1").read_text()
unattend = Path("ops/platform-acceptance/windows-host/Autounattend.xml").read_text()
accepted_3010 = [
line for line in setup.splitlines()
if "3010" in line and "-notin" in line
]
restart_calls = [
line for line in setup.splitlines()
if "Restart-Computer" in line or "shutdown.exe" in line
]
ready_writes = [
(i + 1, line) for i, line in enumerate(setup.splitlines())
if "ready.json" in line and "Set-Content" in line
]
print(f"accepted_3010_checks={len(accepted_3010)}")
print(f"explicit_restart_calls={len(restart_calls)}")
print(f"ready_writes={ready_writes}")
print(f"unattend_will_reboot_never={'<WillReboot>Never</WillReboot>' in unattend}")
print("accepted_3010_checks:")
for line in accepted_3010:
print(line.strip())
PYRepository: gitcommit90/1Helm Length of output: 670 Do not publish readiness after exit code 3010. When any installation returns 🤖 Prompt for AI Agents |
||
|
|
||
| $capability = Get-WindowsCapability -Online | Where-Object Name -Like "OpenSSH.Server*" | Select-Object -First 1 | ||
| if (-not $capability) { throw "Windows did not expose the OpenSSH Server capability." } | ||
| if ($capability.State -ne "Installed") { Add-WindowsCapability -Online -Name $capability.Name | Out-Null } | ||
|
|
||
| New-Item -ItemType Directory -Force -Path "C:\ProgramData\ssh" | Out-Null | ||
| # The authorized key is supplied per site on the bootstrap media rather than | ||
| # committed to this public repository. build-unattend-iso.sh stages it. | ||
| $keySource = Join-Path $PSScriptRoot "authorized_key.pub" | ||
| if (-not (Test-Path $keySource)) { throw "authorized_key.pub is missing from the bootstrap media; see ops/platform-acceptance/windows-host/README.md" } | ||
| $authorizedKey = (Get-Content -Raw $keySource).Trim() | ||
| if ($authorizedKey -notmatch '^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp[0-9]+) ') { throw "authorized_key.pub is not an OpenSSH public key" } | ||
| Set-Content -Encoding ascii -Path "C:\ProgramData\ssh\administrators_authorized_keys" -Value $authorizedKey | ||
| & icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F" | Out-Null | ||
| $config = "C:\ProgramData\ssh\sshd_config" | ||
| if (Test-Path $config) { | ||
| $text = Get-Content -Raw $config | ||
| $text = [regex]::Replace($text, '(?m)^\s*#?\s*PasswordAuthentication\s+.*$', 'PasswordAuthentication no') | ||
| $text = [regex]::Replace($text, '(?m)^\s*#?\s*PubkeyAuthentication\s+.*$', 'PubkeyAuthentication yes') | ||
| Set-Content -Encoding ascii -Path $config -Value $text | ||
| } | ||
|
Comment on lines
+37
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
file='ops/platform-acceptance/windows-host/setup.ps1'
rg -n -C 3 'PasswordAuthentication|PubkeyAuthentication|sshd_config|sshd -t' "$file"
# Expected after the fix: explicit fallback insertion for absent directives
# and an `sshd -t` validation before Start-Service sshd.
rg -n 'sshd -t' "$file"Repository: gitcommit90/1Helm Length of output: 1007 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
file='ops/platform-acceptance/windows-host/setup.ps1'
printf '%s\n' '--- setup.ps1 ---'
nl -ba "$file" | sed -n '1,130p'
printf '%s\n' '--- relevant call sites and configuration setup ---'
rg -n -C 3 'Add-WindowsCapability|OpenSSH|sshd_config|New-NetFirewallRule|Start-Service|Set-Service|ready\.json|3010|reboot' \
ops/platform-acceptance/windows-hostRepository: gitcommit90/1Helm Length of output: 213 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
file='ops/platform-acceptance/windows-host/setup.ps1'
printf '%s\n' '--- setup.ps1 ---'
awk '{ printf "%5d %s\n", NR, $0 }' "$file" | sed -n '1,130p'
printf '%s\n' '--- relevant call sites and configuration setup ---'
rg -n -C 3 'Add-WindowsCapability|OpenSSH|sshd_config|New-NetFirewallRule|Start-Service|Set-Service|ready\.json|3010|reboot' \
ops/platform-acceptance/windows-hostRepository: gitcommit90/1Helm Length of output: 12548 🌐 Web query:
💡 Result: When you first install and start the OpenSSH Server on Windows 11, the sshd_config file is automatically generated by the service at %ProgramData%\ssh\sshd_config [1][2][3]. By default, the OpenSSH Server is configured to allow both password-based authentication and public key authentication [4]. Specifically, the generated configuration file defaults to the following settings for these authentication methods: PubkeyAuthentication yes [4] PasswordAuthentication yes [4] To modify these settings, you can edit the %ProgramData%\ssh\sshd_config file with a text editor (run as an administrator) and change the values to no [5][4]. After modifying the file, you must restart the OpenSSH SSH Server service (using the Services app or PowerShell) for the changes to take effect [5][6]. For security, especially if you intend to disable password authentication in favor of key-based authentication, ensure you have correctly configured the authorized_keys files. Note that Windows OpenSSH enforces specific Access Control List (ACL) permissions on these files; they must be owned by the user or the SYSTEM account, and other users must not have write access to them [3][7]. Additionally, if you are using an administrator account, the server looks for authorized keys in a specific location at %ProgramData%\ssh\administrators_authorized_keys by default, rather than the user's home directory [3][8]. Citations:
🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
path = Path("ops/platform-acceptance/windows-host/setup.ps1")
text = path.read_text()
assert "if (Test-Path $config)" in text
assert "Start-Service sshd" in text
assert text.index("if (Test-Path $config)") < text.index("Start-Service sshd")
assert "PasswordAuthentication no" in text
assert "PubkeyAuthentication yes" in text
# Model both replacements with a configuration that omits both directives.
config = "Host *\n AuthorizedKeysFile .ssh/authorized_keys\n"
updated = re.sub(
r"(?m)^\s*#?\s*PasswordAuthentication\s+.*$",
"PasswordAuthentication no",
config,
)
updated = re.sub(
r"(?m)^\s*#?\s*PubkeyAuthentication\s+.*$",
"PubkeyAuthentication yes",
updated,
)
assert "PasswordAuthentication no" not in updated
assert "PubkeyAuthentication yes" not in updated
print("Absent directives remain absent; service start follows the conditional rewrite.")
PYRepository: gitcommit90/1Helm Length of output: 235 Broken Authentication (CWE-287): Improper Authentication Reachability: External · Exploitability: Moderate Append the SSH authentication directives. When 🤖 Prompt for AI Agents |
||
| Set-Service sshd -StartupType Automatic | ||
| Start-Service sshd | ||
| # Add-WindowsCapability already creates OpenSSH-Server-In-TCP, but scoped to | ||
| # the Private profile only. A freshly bridged VM is categorized Public, so a | ||
| # bare existence check short-circuits and leaves port 22 unreachable even | ||
| # though sshd reports Running. Ensure the rule exists AND covers every profile. | ||
| if (Get-NetFirewallRule -Name OpenSSH-Server-In-TCP -ErrorAction SilentlyContinue) { | ||
| Set-NetFirewallRule -Name OpenSSH-Server-In-TCP -Enabled True -Profile Any | ||
| } else { | ||
| New-NetFirewallRule -Name OpenSSH-Server-In-TCP -DisplayName "OpenSSH Server (sshd)" -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -Profile Any | Out-Null | ||
| } | ||
| Set-Service QEMU-GA -StartupType Automatic | ||
| Start-Service QEMU-GA | ||
| powercfg.exe /change standby-timeout-ac 0 | Out-Null | ||
| powercfg.exe /change hibernate-timeout-ac 0 | Out-Null | ||
| $record = [ordered]@{ ready = $true; computer = $env:COMPUTERNAME; build = [Environment]::OSVersion.Version.ToString(); at = (Get-Date).ToUniversalTime().ToString("o") } | ||
| Set-Content -Encoding utf8 -Path (Join-Path $root "ready.json") -Value ($record | ConvertTo-Json -Compress) | ||
| } finally { | ||
| Stop-Transcript | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: gitcommit90/1Helm
Length of output: 155
🏁 Script executed:
Repository: gitcommit90/1Helm
Length of output: 5986
Information Disclosure (CWE-200): Exposure of Sensitive Information to an Unauthorized Actor
Reachability: Internal
Ignore the generated bootstrap ISO.
The default
1helm-windows-unattend.isocontainsauthorized_key.pubfor Administrator SSH access but is not ignored. Add the ISO to.gitignoreor write it outside the worktree.Proposed fix
authorized_key.pub +1helm-windows-unattend.iso📝 Committable suggestion
🤖 Prompt for AI Agents