Docs
How to point your package managers and container runtimes at SlowShield, what changes for your builds,
and how to check that nothing goes around it. Every page shows the settings for
https://slowshield.example.com; your instance's Setup page (/ui/setup) shows the same
settings with its own address filled in.
- PythonPyPI: pip, uv, Poetry, PDM, Pipenv
- JavaScriptnpm: npm, pnpm, Yarn, Bun
- GoGo modules, as your
GOPROXY - JavaMaven Central, Google Maven, Gradle plugins: Maven, Gradle, sbt, Coursier
- Rustcrates.io: Cargo
- Container imagesDocker Hub, GHCR, Quay, registry.k8s.io and more: containerd, Kubernetes, Docker, Podman
- Building imagesBase images and every dependency of a Docker or Podman build through SlowShield
What SlowShield does
- New releases wait. A version becomes installable a number of days after it was published, 7 by default. Until then it is left out of the version lists your package manager reads, so it resolves to the newest version that is old enough. Asking for it directly, from a lockfile or a pinned digest, gets a refusal with the time it becomes available.
- Known malware is refused, for good, as soon as the OpenSSF/OSV or GitHub advisory feeds report
it: HTTP
451with the advisory (403for container images). Administrators can block packages, versions and images themselves too. - Every download is verified against the registry's own digest and against the fingerprint SlowShield recorded the first time it served the file. A file that changes is cut off mid-transfer.
- Everything is cached. Each file comes from the registry once and from SlowShield after that.
Setting it up
- Run SlowShield on one host your team and CI can reach: Docker Compose, rootless Podman or the
Helm chart (Get started). Use a real host name with HTTPS; the examples here use
slowshield.example.com. - Point every tool at it. Four lines in a shell profile cover pip, uv, npm and go. Other tools need a setting each, on the pages above.
- Close the way around it. Block the public registries at the firewall for machines that should only use SlowShield, so a forgotten setting fails loudly instead of quietly going around it.
For your shell profile (bash on Linux; the Setup page also has bash on macOS, zsh and fish):
cat >> ~/.bashrc <<'EOF'
export PIP_INDEX_URL=https://slowshield.example.com/pypi/simple/
export UV_DEFAULT_INDEX=https://slowshield.example.com/pypi/simple/
export npm_config_registry=https://slowshield.example.com/npm/
export GOPROXY=https://slowshield.example.com/go
export PIP_UPLOADED_PRIOR_TO=P3D
export npm_config_min_release_age=3
EOF
source ~/.bashrcTwo layers
Most package managers can now refuse brand-new releases themselves. Turn that on as well, a little shorter than SlowShield: 7 days in SlowShield, 3 in the package manager. On a normal day only SlowShield holds anything back. When something gets past it, a laptop without the setup or a brand-new package SlowShield serves because no version is old enough yet, the package manager still waits. Each tool's section shows its setting and the version it needs.
What you see when something is held
- Normal installs just get an older version. Indexes carry
X-SlowShield-Held-Versions, the number of versions left out. - A pin that is too new (lockfile,
==pin, image digest) gets403withRetry-Afterand a message saying when it becomes available (Maven and Gradle:425 Too Early, the only status they report clearly). - A brand-new package none of whose versions is old enough is served and recorded as fail-open on PyPI, npm and Go, and refused on Maven and Cargo, where brand-new packages are the usual attack (typosquats, impersonations). Container images only fail open during an instance's first week.
- Exceptions. An administrator can release one version early, or hold a package longer, in
config.toml(configuration).
More
- Configuration reference and config.example.toml
- Release-age policy, integrity checks, threat feeds
- Operations and observability
For agents: this page as Markdown · llms.txt · the SlowShield skill