uv hardener
Run av harden uv to apply this hardener and
av doctor uv to verify it.
av harden uv installs the reviewed official
uv 0.12.12 executable under
/opt/av/uv/0.12.12, preserving its Developer ID signature
and Hardened Runtime. It installs root-owned uv and
uvx launchers and a private keyring helper. AV
pins both the upstream archive and executable SHA-256 for arm64 and
x86_64. Updating the supported release requires another command-surface
review.
The Hardener imports the selected plaintext
credentials.toml into the protected
UV_CREDENTIALS Secret. This contains HTTP Basic
credentials, including tokens with the __token__ username.
Service paths and usernames remain distinct. Unknown formats, HTTP
services, bearer authentication, and duplicate entries are rejected
before migration. Existing AV values must match exactly; AV never
silently replaces them. The plaintext source is removed only after the
official installation verifies and the source still matches the imported
snapshot.
Native Keychain credentials, .netrc, URL credentials,
environment credentials, and other stores are not migrated. Those remain
independent Exposures and must be removed or migrated separately.
Hardening this store does not certify the absence of ambient
credentials. uv auth login still manages upstream stores;
it does not add credentials to AV custody.
Private indexes must provide a username (including
__token__ for token credentials), or set
authenticate = "always" on the index. For example:
[[tool.uv.index]]
name = "private"
url = "https://packages.example.com/simple/"
authenticate = "always"
The launcher enables UV_KEYRING_PROVIDER=subprocess. uv
otherwise skips subprocess lookup when no username is known. An explicit
CLI provider override can disable this integration. Registry URLs and
usernames are configuration; passwords remain in AV custody. No Python
keyring installation is required.
The launcher registers the complete arguments, initial working
directory, and live process with the menu app. Registration returns a
random nonce and grants no Secret Use. When uv requests a credential,
the menu app verifies the helper's original parent, registered PID/start
time/user/audit session, exact arguments, pinned live code identity,
Hardened Runtime, and current working directory. It binds the first
helper request to the Target's PID version, so another exec
cannot reuse the registration. Every credential request then goes
through the uv Authorization Gate and recording before release. The
nonce alone grants no authority. Unregistered and sibling processes
cannot use the registration. A direct child of uv can replace itself
with the signed helper and preserve its parent relationship. The nonce
binds the full operation; it does not isolate Python or package code
inside that operation. Even pip list can execute a selected
Python interpreter, so these command families are Unknown and require
Approval.
The keyring helper receives only the selected username/password, never the credential bundle. Selection requires HTTPS, the same host and port, a service path prefix at a segment boundary, and a matching username when specified. The most specific path wins; ambiguous usernames fail closed. Scheme-less host fallback is rejected to prevent an HTTP request from obtaining an HTTPS Secret.
The uv Gate defaults to Approval Required. No Python-capable
operation can be automically authorized, even under Full Access.
publish can be authorized by a Write Access policy because
it uploads existing distributions without running a selected Python
interpreter.
Reviewed credential-consuming commands
Reviewed against uv 0.12.12: the command surface, keyring protocol, and Python interpreter execution. Registration occurs only for these command families. A command that does not actually request keyring credentials produces no Secret Use or Approval.
| Commands | Classification | Credential use |
|---|---|---|
add, remove, sync,
lock, upgrade, tree,
export, audit |
Unknown; Approval Required | Resolve dependencies and update project/lock state |
version |
Unknown; Approval Required | Version changes may re-lock and sync |
venv / virtualenv / v |
Unknown; Approval Required | Install seed packages |
pip compile, pip install,
pip sync, pip uninstall |
Unknown; Approval Required | Resolve/install packages or fetch remote requirements |
pip list / pip ls, pip tree,
tool list / tool ls |
Unknown; Approval Required | Look up outdated package versions |
tool install, tool upgrade /
tool update |
Unknown; Approval Required | Resolve and install tools |
run, tool run / uvx,
check, build |
Unknown; Approval Required | Resolve dependencies before running arbitrary code |
publish |
Remote Write | Upload packages |
Help, version display, auth commands, cache, Python management,
workspace inspection, local pip inspection, init,
format, tool removal, and unknown commands receive no
registration. Unknown leading global options fail without AV
credentials. CLI options and alternate providers may disable the helper,
but cannot retrieve the protected Secret. uv auth token has
no AV credential store to dump. AV does not constrain a Target after it
receives a credential. uv's mutable configuration, TLS exceptions,
custom certificate roots, and proxies remain under its control. HTTPS
scope matching does not independently verify its TLS connection. See ADR
0046.
av doctor uv verifies the pinned executable, protected
installation paths, exact launchers, and private helper. Other
installations remain callable, but cannot use this credential helper
without a registered operation.
The dummy-only
keyring probe verifies both upstream response formats, direct parent
identity, plaintext schema, and auth token exclusion. It
does not exercise AV's signed XPC boundary.