auto-detect and stage corp TLS-inspection root CA before docker build

GE/Zscaler proxy inspection breaks npm ci silently, leaving node_modules
incomplete and vite missing at build time. Detect the root CA from the
host's chain to the npm registry and stage it as corp-root-ca.pem so the
Dockerfile trusts it; harmless on clean networks.
This commit is contained in:
benjamin.baker
2026-09-02 07:58:31 -04:00
parent 849bfb7bc2
commit 58040164c2

View File

@@ -98,6 +98,51 @@ function Test-Command {
return [bool](Get-Command $Name -ErrorAction SilentlyContinue)
}
# Detect a corporate TLS-inspection root CA (e.g. Zscaler) by inspecting the
# certificate chain the host uses to reach the npm registry, then stage it as
# corp-root-ca.pem in the build context so the Docker frontend build can trust
# it. On a clean network this simply stages a public root, which is harmless.
# Writes nothing and returns quietly when detection is not possible.
function Set-CorpRootCa {
param(
[Parameter(Mandatory)][string]$RepoRoot
)
$certPath = Join-Path $RepoRoot 'corp-root-ca.pem'
try {
$request = [System.Net.HttpWebRequest]::Create('https://registry.npmjs.org/')
$request.Method = 'HEAD'
$request.Timeout = 10000
try { $response = $request.GetResponse(); $response.Close() } catch { }
$cert = $request.ServicePoint.Certificate
if (-not $cert) {
Write-Warn 'Could not read the TLS certificate chain; skipping corp CA staging.'
return
}
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.ChainPolicy.RevocationMode = 'NoCheck'
$cert2 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($cert)
[void]$chain.Build($cert2)
$root = $chain.ChainElements[$chain.ChainElements.Count - 1].Certificate
$issuer = $root.Subject
$builder = New-Object System.Text.StringBuilder
[void]$builder.AppendLine('-----BEGIN CERTIFICATE-----')
[void]$builder.AppendLine([System.Convert]::ToBase64String($root.RawData, 'InsertLineBreaks'))
[void]$builder.AppendLine('-----END CERTIFICATE-----')
Set-Content -Path $certPath -Value $builder.ToString() -Encoding ASCII
Write-Ok "Staged corp-root-ca.pem from root CA: $issuer"
}
catch {
Write-Warn "Corp CA detection failed ($($_.Exception.Message)); continuing without it."
}
}
# Confirm a dependency, offering a winget install when it is missing. Returns
# $true when the dependency is present (or was just installed), $false when the
# dev declined or install failed.
@@ -246,6 +291,9 @@ try {
# --- 4. Build and start ---------------------------------------------------
Write-Step 'Detecting corporate TLS-inspection CA for the Docker build'
Set-CorpRootCa -RepoRoot $repoRoot
Write-Step "Building and starting the '$($config.Project)' stack"
$composeArgs = @(
'compose',