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-firewall → ENDOR_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
- Parity with Poetry/Maven — secrets in the env store; config file is non-secret (still namespace-bearing).
- 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.
- Rotation — redeploy updates env;
uv.toml need not change when only the secret rotates (URL host/namespace unchanged).
- 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
- Update
shared/blocks/uvtoml.txt (+ PowerShell templates/blocks/uvtoml.txt if still duplicated) to named naked URL + name = "endor-firewall".
- Add
UV_INDEX_ENDOR_FIREWALL_USERNAME / _PASSWORD to envvars.ps1 and shared/blocks/envsh.txt (values from attributed user + API secret).
- Stop filling
{{ENDOR_PYPI_URL}} into the uv block in python.ps1 / python.sh (pip fill unchanged).
- Update
remove.* to delete the new UV_INDEX_* keys.
- Fix bash/PowerShell READMEs + conflicting comments so they match behavior.
- Consider a short compat window: generator flag (
UV_AUTH=url|env) or one-release dual-write so existing fleets don’t brick mid-redeploy.
- Document CI snippet in README (named index + pipeline secrets) so MDM and Secure SDLC tell one story.
- Validate attribution still appears correctly in Package Firewall logs when auth is via
UV_INDEX_* (not URL-embedded userinfo).
Test plan
References
Summary
Propose migrating uv Package Firewall auth from a literal credentialed index URL baked into
uv.tomlto 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 TOMLurlvalues.Current behavior (verified on
main@80d201a)Windows —
package-firewall/powershell/templates/python.ps1At install time the attributed credentialed URL replaces the block placeholder, then is written to
%APPDATA%\uv\uv.toml:envvars.ps1already states$ENDOR_PYPI_URLis not written toHKCU:\Environment— it only feeds the literal fill for pip/uv/go:Poetry does get env-backed auth:
POETRY_HTTP_BASIC_ENDOR_FIREWALL_USERNAME/PASSWORDin HKCU.macOS / Linux —
package-firewall/bash/templates/python.shSame bake pattern:
UV_BLOCK=${UV_BLOCK//'{{ENDOR_PYPI_URL}}'/"$ENDOR_PYPI_URL"}Shared block (
shared/blocks/uvtoml.txtand PowerShell copy):shared/blocks/envsh.txtexports Poetry basic-auth vars but does not exportENDOR_PYPI_URLor anyUV_INDEX_*vars.Docs / comment drift (worth fixing in the same work)
`${ENDOR_PYPI_URL}` env var refhttps://user:secret@factory…intouv.toml;ENDOR_PYPI_URLis not in HKCUenv.shexportsENDOR_PYPI_URL“used by uv”; uv.toml “references`${ENDOR_PYPI_URL}`”envsh.txthas noENDOR_PYPI_URL; install substitutes into the filepython.shL57: “uv supports${VAR}env var expansion in uv.toml”uv.tomlwith “${VAR}references only — no credentials baked in”Local check: a user-level
uv.tomlwithurl = "${ENDOR_PYPI_URL}"andENDOR_PYPI_URL=https://pypi.org/simple/did not resolve packages from PyPI (placeholder treated as opaque URL). A nakedhttps://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):
Set (Windows
HKCU:\Environment/ Unixenv.sh), parallel to Poetry:(
endor-firewall→ENDOR_FIREWALLper uv index auth.)Keep user attribution by using the existing attributed Basic-auth username (
ENDOR_ATTR_USER) asUV_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
[[tool.uv.index]]/ runneruv.toml+UV_INDEX_ENDOR_FIREWALL_*secrets without embedding key material in files that get logged/copied.uv.tomlneed not change when only the secret rotates (URL host/namespace unchanged).Out of scope / leave as-is (unless follow-up)
pip.ini/pip.conf; literalindex-urlremains appropriate.GOPROXY— env file likewise needs a baked URL (or a different mechanism).Suggested implementation sketch
shared/blocks/uvtoml.txt(+ PowerShelltemplates/blocks/uvtoml.txtif still duplicated) to named naked URL +name = "endor-firewall".UV_INDEX_ENDOR_FIREWALL_USERNAME/_PASSWORDtoenvvars.ps1andshared/blocks/envsh.txt(values from attributed user + API secret).{{ENDOR_PYPI_URL}}into the uv block inpython.ps1/python.sh(pip fill unchanged).remove.*to delete the newUV_INDEX_*keys.UV_AUTH=url|env) or one-release dual-write so existing fleets don’t brick mid-redeploy.UV_INDEX_*(not URL-embedded userinfo).Test plan
endor-python.ps1→ nakeduv.toml+ HKCUUV_INDEX_*;uv pip install/uv lockhits Factory; attribution OK in logs.env.sh+~/.config/uv/uv.toml.UV_INDEX_*→ 401 from Factory (auth not somehow still in config).${ENDOR_PYPI_URL}fiction).References
python.ps1uv sectionpython.shshared/blocks/uvtoml.txt