From 1f07da2e126af45e8423feb8392bd69bdd288c40 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 7 May 2026 09:30:52 -0400 Subject: [PATCH] tools: upgrade Get-InfisicalSecret to stream separation, drop banner regex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Earlier fix (commit 047125b) filtered the infisical CLI's "A new release of infisical is available" upgrade banner from captured output via regex matching. That worked but coupled the filter to specific banner-pattern strings — a future banner shape ("Update available" / "New version detected" / a localized message) would slip through and break NTLM Type1 auth again. The principled fix is to stop capturing stderr at all. PowerShell's call operator (`&`) keeps stdout and stderr on separate streams unless explicitly merged; the previous code's `2>&1` was the actual mistake. Without it, the banner stays in the error stream (visible on the console for diagnostics) and the captured `$value` contains only the script's stdout — which for `Get-Secret.ps1` is just the secret value from `infisical secrets get --plain`. Verified: live re-run of F54 (lmx_write_complete_live) passes post-change with `MX_TEST_DOMAIN='DESKTOP-6JL3KKO'` clean and the banner visibly logged to console (stderr) above each [SET] line. No regex coupling to a specific banner-pattern remains. Co-Authored-By: Claude Opus 4.7 (1M context) --- tools/Setup-LiveProbeEnv.ps1 | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/tools/Setup-LiveProbeEnv.ps1 b/tools/Setup-LiveProbeEnv.ps1 index 4dacce9..10c5d70 100644 --- a/tools/Setup-LiveProbeEnv.ps1 +++ b/tools/Setup-LiveProbeEnv.ps1 @@ -67,28 +67,24 @@ function Set-LiveEnvVar { function Get-InfisicalSecret { param([string]$Key, [string]$Env = 'infrastructure', [string]$Path = '/windows-hosts') + # Capture stdout only — the infisical CLI writes its + # "A new release of infisical is available" upgrade banner (and any + # transient diagnostic noise) to STDERR. We deliberately do NOT use + # `2>&1` here so that banner stays in the error stream (visible on + # the console for diagnostics) and never pollutes the secret value. + # An earlier version of this function used `2>&1` plus a regex-based + # banner filter; that approach was brittle to future banner shapes, + # so it was replaced with stream separation. If a real error needs + # to be surfaced, $LASTEXITCODE catches it below. try { - $value = & $GetSecret -Key $Key -Env $Env -Path $Path 2>&1 - if ($LASTEXITCODE -ne 0 -or -not $value) { - throw "Get-Secret returned empty for $Env$Path/$Key (exit code $LASTEXITCODE)" + $value = & $GetSecret -Key $Key -Env $Env -Path $Path + if ($LASTEXITCODE -ne 0) { + throw "Get-Secret exit code $LASTEXITCODE for $Env$Path/$Key" } - # The infisical CLI occasionally writes an upgrade-available banner - # ("A new release of infisical is available: ...") to stderr; the - # `2>&1` redirect above merges it into the value stream. Filter - # those banner lines so they don't pollute the returned secret. - # Take the last non-empty, non-banner line — the actual secret - # value is always the final line of `infisical secrets get --plain`. - $clean = ($value | Out-String) -split "(`r`n|`n)" | - ForEach-Object { $_.Trim() } | - Where-Object { - $_ -and - ($_ -notmatch '^A new release of infisical is available') -and - ($_ -notmatch '^Please upgrade ') - } - if (-not $clean) { - throw "Get-Secret produced no usable line for $Env$Path/$Key after banner filtering" + if (-not $value) { + throw "Get-Secret returned empty stdout for $Env$Path/$Key" } - return ($clean | Select-Object -Last 1) + return ($value | Out-String).Trim() } catch { throw "Failed to fetch $Env$Path/$Key from Infisical: $_" }