diff --git a/package-firewall/bash/templates/js.sh b/package-firewall/bash/templates/js.sh index b1b07bb..3519079 100644 --- a/package-firewall/bash/templates/js.sh +++ b/package-firewall/bash/templates/js.sh @@ -9,7 +9,7 @@ # Block content is defined in shared/blocks/npmrc.txt, yarnrc_classic.txt, yarnrc.txt. # ${ENDOR_...} values in those files are env var refs — tools expand them at runtime. # -# Auth note: .npmrc uses _auth, _username, _password (base64-encoded key:secret). +# Auth note: .npmrc uses _auth, username, _password (attributed-user credentials). # _authToken causes 401 for bun. _auth is verified working for all tools above. # # Yarn classic reads .npmrc for auth and .yarnrc for registry — both written here. @@ -21,14 +21,6 @@ echo "[endor-js] ── JavaScript package managers ───────── # ── .npmrc ──────────────────────────────────────────────────────────────────── # Covers: npm (all versions), pnpm (8.x–11.x), yarn classic (1.x), bun (all versions) -# Swap to the attributed user (shared block stays Windows-safe). Needed for -# bun: its last-write-wins .npmrc parsing would otherwise drop attribution. -NPMRC_BLOCK=${NPMRC_BLOCK//'${ENDOR_API_KEY_ID}'/'${ENDOR_ATTR_USER}'} -if [[ "$NPMRC_BLOCK" != *'${ENDOR_ATTR_USER}'* ]]; then - echo "[endor-js] WARNING: attribution swap did not match — shared/blocks/npmrc.txt changed?" >&2 - _ENDOR_WARNED=1 -fi - warn_if_key_conflict \ "$USER_HOME/.npmrc" \ "^registry=" \ @@ -65,13 +57,6 @@ echo "[endor-js] covers: yarn classic (1.x)" # Uses npmAuthIdent (plain "user:secret") — confirmed working with Endor firewall. # Yarn berry supports ${VAR} expansion in .yarnrc.yml values (yarn 3+). -# Swap to the attributed user (shared block stays Windows-safe). -YARNRC_BLOCK=${YARNRC_BLOCK//'${ENDOR_API_KEY_ID}'/'${ENDOR_ATTR_USER}'} -if [[ "$YARNRC_BLOCK" != *'${ENDOR_ATTR_USER}'* ]]; then - echo "[endor-js] WARNING: attribution swap did not match — shared/blocks/yarnrc.txt changed?" >&2 - _ENDOR_WARNED=1 -fi - warn_if_key_conflict \ "$USER_HOME/.yarnrc.yml" \ "^npmRegistryServer:" \ diff --git a/package-firewall/bash/templates/maven.sh b/package-firewall/bash/templates/maven.sh index 717019b..2e4f870 100644 --- a/package-firewall/bash/templates/maven.sh +++ b/package-firewall/bash/templates/maven.sh @@ -12,13 +12,6 @@ echo "" echo "[endor-maven] ── Maven ────────────────────────────────────────────────────────" -# Swap to the attributed user (shared block stays Windows-safe). -MAVEN_BLOCK=${MAVEN_BLOCK//'${env.ENDOR_API_KEY_ID}'/'${env.ENDOR_ATTR_USER}'} -if [[ "$MAVEN_BLOCK" != *'${env.ENDOR_ATTR_USER}'* ]]; then - echo "[endor-maven] WARNING: attribution swap did not match — shared/blocks/mavensettings.txt changed?" >&2 - _ENDOR_WARNED=1 -fi - MAVEN_SETTINGS="$USER_HOME/.m2/settings.xml" # warn if the admin already defines a mirror/server outside an Endor block -- diff --git a/package-firewall/powershell/generate.ps1 b/package-firewall/powershell/generate.ps1 index 9f2fc74..46d5533 100644 --- a/package-firewall/powershell/generate.ps1 +++ b/package-firewall/powershell/generate.ps1 @@ -60,26 +60,23 @@ $ENDOR_API_KEY_ID = $env:ENDOR_API_KEY_ID $ENDOR_API_SECRET = $env:ENDOR_API_SECRET $FQDN = if ($env:ENDOR_FQDN) { $env:ENDOR_FQDN.TrimEnd('/') } else { 'https://factory.endorlabs.com' } +# Reject credential characters that would corrupt generated scripts/URLs. +if ("${ENDOR_API_KEY_ID}${ENDOR_API_SECRET}" -match '[^A-Za-z0-9+/=_.-]') { + Write-Error 'ENDOR_API_KEY_ID / ENDOR_API_SECRET contain unsupported characters' + exit 1 +} + # -- Compute derived values ---------------------------------------------------- +# Credentials are NOT precomputed here. The per-machine attributed username +# (@) only exists on the developer's machine, so all +# auth values are computed at install time by templates/envvars.ps1. Only +# machine-independent values are derived here. $FQDN_HOST = $FQDN -replace '^https?://', '' $TRUSTED_HOST = $FQDN_HOST -replace ':.*', '' $NPM_REGISTRY_URL = "$FQDN/v1/namespaces/$ENDOR_NAMESPACE/firewall/npm/" $NPM_REGISTRY_HOST = "$FQDN_HOST/v1/namespaces/$ENDOR_NAMESPACE/firewall/npm/" - -$_bytes = [System.Text.Encoding]::UTF8.GetBytes("${ENDOR_API_KEY_ID}:${ENDOR_API_SECRET}") -$NPM_AUTH_B64 = [System.Convert]::ToBase64String($_bytes) -$_secretBytes = [System.Text.Encoding]::UTF8.GetBytes($ENDOR_API_SECRET) -$API_SECRET_B64 = [System.Convert]::ToBase64String($_secretBytes) -Remove-Variable _bytes, _secretBytes - -$PYPI_URL = "$FQDN/v1/namespaces/$ENDOR_NAMESPACE/firewall/pypi/simple/" -$PIP_INDEX_URL = "https://${ENDOR_API_KEY_ID}:${ENDOR_API_SECRET}@${FQDN_HOST}/v1/namespaces/$ENDOR_NAMESPACE/firewall/pypi/simple/" - -$GO_PROXY_URL = "https://${ENDOR_API_KEY_ID}:${ENDOR_API_SECRET}@${FQDN_HOST}/v1/namespaces/$ENDOR_NAMESPACE/firewall/go/,direct" - -# Maven keeps credentials in a block via ${env.*}, so — unlike Go — no -# credentials are baked into this URL. +$PYPI_URL = "$FQDN/v1/namespaces/$ENDOR_NAMESPACE/firewall/pypi/simple/" $MAVEN_REGISTRY_URL = "$FQDN/v1/namespaces/$ENDOR_NAMESPACE/firewall/maven/" # -- Output directory ---------------------------------------------------------- @@ -91,18 +88,18 @@ New-Item -ItemType Directory -Path $OutDir -Force | Out-Null function Invoke-Substitute { param([string]$Content) $r = $Content - $r = $r.Replace('{{NAMESPACE}}', $ENDOR_NAMESPACE) - $r = $r.Replace('{{API_KEY_ID}}', $ENDOR_API_KEY_ID) - $r = $r.Replace('{{API_SECRET}}', $ENDOR_API_SECRET) - $r = $r.Replace('{{FQDN}}', $FQDN) - $r = $r.Replace('{{NPM_REGISTRY_URL}}', $NPM_REGISTRY_URL) - $r = $r.Replace('{{NPM_REGISTRY_HOST}}', $NPM_REGISTRY_HOST) - $r = $r.Replace('{{NPM_AUTH_B64}}', $NPM_AUTH_B64) - $r = $r.Replace('{{API_SECRET_B64}}', $API_SECRET_B64) - $r = $r.Replace('{{PYPI_URL}}', $PYPI_URL) - $r = $r.Replace('{{PIP_INDEX_URL}}', $PIP_INDEX_URL) - $r = $r.Replace('{{TRUSTED_HOST}}', $TRUSTED_HOST) - $r = $r.Replace('{{GO_PROXY_URL}}', $GO_PROXY_URL) + # Attribution tokens ({{PIP_INDEX_URL}}, {{ENDOR_PYPI_URL}}, {{GO_PROXY_URL}}, + # {{NPM_AUTH_B64}}) are NOT substituted here — the generated scripts fill + # them at install time from the values computed in envvars.ps1. + $r = $r.Replace('{{NAMESPACE}}', $ENDOR_NAMESPACE) + $r = $r.Replace('{{API_KEY_ID}}', $ENDOR_API_KEY_ID) + $r = $r.Replace('{{API_SECRET}}', $ENDOR_API_SECRET) + $r = $r.Replace('{{FQDN}}', $FQDN) + $r = $r.Replace('{{FQDN_HOST}}', $FQDN_HOST) + $r = $r.Replace('{{NPM_REGISTRY_URL}}', $NPM_REGISTRY_URL) + $r = $r.Replace('{{NPM_REGISTRY_HOST}}', $NPM_REGISTRY_HOST) + $r = $r.Replace('{{PYPI_URL}}', $PYPI_URL) + $r = $r.Replace('{{TRUSTED_HOST}}', $TRUSTED_HOST) $r = $r.Replace('{{MAVEN_REGISTRY_URL}}', $MAVEN_REGISTRY_URL) $r } @@ -148,6 +145,17 @@ function Get-ScriptHeader { $r } +# Warning footer appended to install scripts (MDM alert hook, mirrors bash). +$ScriptFooter = @' + +# -- Exit non-zero if any warnings were emitted (MDM alert hook) -- +if ($EndorWarned) { + Write-Host '' + Write-Warning '[endor] Script completed with warnings -- review output above.' + exit 1 +} +'@ + # Build-Script