Skip to content

Add a 1-day package cooldown to managed-python (AWS supply-chain guidance) #5

Description

TLDR

Apply the package-cooldown guidance from the AWS Security Blog post Secure your npm and pip package updates in Amazon Linux to managed-python: ship a 1-day cooldown on package resolution by default, so freshly-published (potentially compromised) releases are not picked up during the window when malicious versions are most likely to still be undetected.

Why

Recent supply-chain attacks (Shai-Hulud and friends) follow a predictable shape: an attacker publishes a malicious version, and it gets pulled into builds within minutes. Detection and yanking typically happen within hours. A short cooldown means we simply are not in the blast radius for the riskiest window - at the cost of installing yesterday's release instead of today's.

managed-python is the front door to Python tooling for everyone using $REDMATTER_UV / $REDMATTER_PYTHON, so a single change here raises the floor for every script and tool that resolves packages through it.

What the article recommends, and how it maps here

Article recommendation Applies to managed-python?
npm config set min-release-age 1 No - there is no Node/npm in this repo. Out of scope.
pip config set global.uploaded-prior-to P1D Not directly - the bootstrapped venv contains no pip (verified: venv/bin has no pip). Adding pip.conf machinery nothing reads would be dead weight.
The underlying control: cooldown on package resolution Yes - via uv's exclude-newer, which is the single installer this repo provides.

Proposed change

Export UV_EXCLUDE_NEWER from the generated env files, defaulting to P1D:

  • setup.py gains --cooldown <duration> (default P1D; P0D disables).
  • env.sh, env.ps1 and env.bat all export UV_EXCLUDE_NEWER.
  • The chosen value is recorded in the [install] section of the installed distro.toml, matching the existing inspect/replay intent.
  • Docs updated: README.md, SECURITY.md (Supply Chain section), TESTING.md.

Verified behaviour against the pinned uv (0.10.12)

All of the below was run against a real bootstrap of the pinned uv_version = "0.10.12":

Check Result
UV_EXCLUDE_NEWER=P1D parses Yes - ISO 8601 and friendly durations (1 day) both accepted
Cooldown actually bites Yes - P365D resolved requests==2.32.4 vs 2.34.2 uncapped
uvx / uv tool install honour it Yes - ruff 0.12.8 under P365D vs 0.16.2 uncapped
Managed Python downloads affected No - uv python toolchain downloads are unaffected
UV_EXCLUDE_NEWER=false (the documented "off" value) Rejected as an env var - only valid in uv.toml. The escape hatch is P0D, which is what we will document
Lockfile installs Unaffected until --upgrade / --refresh, per uv docs. This mirrors the article's own npm ci / pinned-requirements caveat

Escape hatches for urgent patches

"$REDMATTER_UV" pip install --exclude-newer P0D <package>              # bypass entirely
"$REDMATTER_UV" pip install --exclude-newer-package <package>=P0D ...  # bypass for one package

Known trade-off, called out deliberately

UV_EXCLUDE_NEWER is uv's own env var and cannot be namespaced the way REDMATTER_UV is. Sourcing env.sh therefore changes the behaviour of any uv on PATH, including a pre-existing system uv - notably in the exact branch where _path_decision() currently declines to touch PATH out of respect for the user's own tooling.

The alternative - injecting the var inside the bin/uv wrapper so it only affects the managed uv - would turn a POSIX symlink into a shell script, which is a meaningful complication of a deliberately minimal design. Preference is to export it and document the effect plainly.

Reversibility classification

One-way door. This touches security posture and the generated env-file contract that downstream repos consume, so it goes through PR review rather than being self-merged.

Metadata

Metadata

Assignees

No one assigned

    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