Skip to content

Package Firewall MDM: migrate uv auth to named index + UV_INDEX_* (docs drift / CI parity) #15

Description

@tgowan-endor

Summary

Propose migrating uv Package Firewall auth from a literal credentialed index URL baked into uv.toml to a named index + UV_INDEX_* environment variables, matching Poetry/Maven (env-backed) and aligning MDM laptops with CI/CD.

This is not “make url = "{{ENDOR_PYPI_URL}}" expand at runtime.” That token is a generator fill today; uv does not interpolate ${…} / {{…}} inside TOML url values.

Current behavior (verified on main @ 80d201a)

Windows — package-firewall/powershell/templates/python.ps1

At install time the attributed credentialed URL replaces the block placeholder, then is written to %APPDATA%\uv\uv.toml:

# Fill the attributed index-url into the block content (pip/uv can't expand env vars).
$UV_BLOCK = $UV_BLOCK.Replace('{{ENDOR_PYPI_URL}}', $ENDOR_PYPI_URL)
…
# -- uv.toml --
# uv does NOT read pip.ini. %APPDATA%\uv\uv.toml is the user-level global config.
# The index-url is baked as a literal at install time -- see the fill above.

envvars.ps1 already states $ENDOR_PYPI_URL is not written to HKCU:\Environment — it only feeds the literal fill for pip/uv/go:

# $ENDOR_PYPI_URL / $ENDOR_GO_PROXY_URL are NOT written to HKCU (no runtime
# reader) — they only feed the literal fills in python.ps1 / go.ps1 below.

Poetry does get env-backed auth: POETRY_HTTP_BASIC_ENDOR_FIREWALL_USERNAME/PASSWORD in HKCU.

macOS / Linux — package-firewall/bash/templates/python.sh

Same bake pattern:

UV_BLOCK=${UV_BLOCK//'{{ENDOR_PYPI_URL}}'/"$ENDOR_PYPI_URL"}

Shared block (shared/blocks/uvtoml.txt and PowerShell copy):

[[index]]
url = "{{ENDOR_PYPI_URL}}"
default = true

shared/blocks/envsh.txt exports Poetry basic-auth vars but does not export ENDOR_PYPI_URL or any UV_INDEX_* vars.

Docs / comment drift (worth fixing in the same work)

Claim Reality
PowerShell README: uv credentials = `${ENDOR_PYPI_URL}` env var ref Install bakes full https://user:secret@factory… into uv.toml; ENDOR_PYPI_URL is not in HKCU
Bash README: env.sh exports ENDOR_PYPI_URL “used by uv”; uv.toml “references `${ENDOR_PYPI_URL}` envsh.txt has no ENDOR_PYPI_URL; install substitutes into the file
Bash python.sh L57: “uv supports ${VAR} env var expansion in uv.toml” Conflicts with L14 (“literal … baked”) and with uv behavior
README tables lumping uv.toml with “${VAR} references only — no credentials baked in” False for current uv path

Local check: a user-level uv.toml with url = "${ENDOR_PYPI_URL}" and ENDOR_PYPI_URL=https://pypi.org/simple/ did not resolve packages from PyPI (placeholder treated as opaque URL). A naked https://pypi.org/simple/ index worked. So “put ${ENDOR_PYPI_URL} in the TOML” is not a viable fix.

Proposed design (uv)

Write a naked named default index (namespace still generator-substituted):

[[index]]
name = "endor-firewall"
url = "https://factory.endorlabs.com/v1/namespaces/<namespace>/firewall/pypi/simple/"
default = true

Set (Windows HKCU:\Environment / Unix env.sh), parallel to Poetry:

UV_INDEX_ENDOR_FIREWALL_USERNAME=<attributed ENDOR_ATTR_USER>
UV_INDEX_ENDOR_FIREWALL_PASSWORD=<API secret>

(endor-firewallENDOR_FIREWALL per uv index auth.)

Keep user attribution by using the existing attributed Basic-auth username (ENDOR_ATTR_USER) as UV_INDEX_ENDOR_FIREWALL_USERNAME, same as today’s URL userinfo.

Optional: authenticate = "always" so missing env fails closed instead of trying unauthenticated Factory requests.

Why this is worth it

  1. Parity with Poetry/Maven — secrets in the env store; config file is non-secret (still namespace-bearing).
  2. Same pattern as CD — CI can use project [[tool.uv.index]] / runner uv.toml + UV_INDEX_ENDOR_FIREWALL_* secrets without embedding key material in files that get logged/copied.
  3. Rotation — redeploy updates env; uv.toml need not change when only the secret rotates (URL host/namespace unchanged).
  4. Corrects incorrect docs that already describe an env-ref world for uv.

Out of scope / leave as-is (unless follow-up)

  • pip — still cannot expand env vars in pip.ini / pip.conf; literal index-url remains appropriate.
  • Go GOPROXY — env file likewise needs a baked URL (or a different mechanism).
  • This issue is uv-first; other managers already use env where the tool allows.

Suggested implementation sketch

  1. Update shared/blocks/uvtoml.txt (+ PowerShell templates/blocks/uvtoml.txt if still duplicated) to named naked URL + name = "endor-firewall".
  2. Add UV_INDEX_ENDOR_FIREWALL_USERNAME / _PASSWORD to envvars.ps1 and shared/blocks/envsh.txt (values from attributed user + API secret).
  3. Stop filling {{ENDOR_PYPI_URL}} into the uv block in python.ps1 / python.sh (pip fill unchanged).
  4. Update remove.* to delete the new UV_INDEX_* keys.
  5. Fix bash/PowerShell READMEs + conflicting comments so they match behavior.
  6. Consider a short compat window: generator flag (UV_AUTH=url|env) or one-release dual-write so existing fleets don’t brick mid-redeploy.
  7. Document CI snippet in README (named index + pipeline secrets) so MDM and Secure SDLC tell one story.
  8. Validate attribution still appears correctly in Package Firewall logs when auth is via UV_INDEX_* (not URL-embedded userinfo).

Test plan

  • Windows: generated endor-python.ps1 → naked uv.toml + HKCU UV_INDEX_*; uv pip install / uv lock hits Factory; attribution OK in logs.
  • macOS/Linux: same via env.sh + ~/.config/uv/uv.toml.
  • Unset UV_INDEX_* → 401 from Factory (auth not somehow still in config).
  • Redeploy / remove scripts clean both block and env keys.
  • README claims match generated output (no ${ENDOR_PYPI_URL} fiction).

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions