one thing from the litellm mess i keep thinking about
the git tag was clean. if you read the code on github before upgrading you saw nothing. one line got added to the build config right before the wheels were made, so only the package on pypi had the stealer
checking the repo doesn't protect you. so i looked at the upload times instead. the clean 1.106.2 went up at 10:44 utc, the bad 1.107.0 at 11:39, and pypi had pulled it by early afternoon
a one day cooldown on new versions and you never would have installed it
uv and pip both have this built in now, it's one line. add hash pinned lockfiles so an agent running pip install can't quietly pull something new, and docker images pinned by digest instead of latest
if your agents touch python projects, add the cooldown today. 1 day would have been enough here, 3 is safer. checklist in the reply
4
8
250
the checklist
1. cooldown (ignore versions newer than X)
uv, in pyproject.toml:
[tool.uv]
exclude-newer = "3 days"
pip 26.1+: pip install --uploaded-prior-to P3D -r requirements.txt
2. hash pinned installs
uv lock writes hashes, install with uv sync --locked
pip: uv pip compile requirements.in --generate-hashes -o requirements.txt
then pip install --require-hashes -r requirements.txt
3. docker by digest, never latest
docker buildx imagetools inspect ghcr.io/berriai/litellm:v1.1…
put the sha256 it prints after an @ on the image tag
4. why .pth matters: a .pth file in site-packages runs on every python start, even if you never import the package. look without starting python:
find ~ /usr/local /opt -name '*.pth' -path '*site-packages*' 2>/dev/null
some normal ones exist (setuptools has one), look for names you don't recognise
5. trusted publishing ties uploads to one repo and workflow. litellm had no pypi provenance on 1.106.2, so there was nothing to compare against
source: github.com/BerriAI/litellm/i…
Oct 22, 2026 · 9:02 PM UTC
1
3
100

