Agents
Coding agents install packages on their own: pip install, npm install,
npx, uvx, go get, docker pull, often in a fresh sandbox without a
lockfile, and nobody reads the output. This page is for the people who run agents, and for the agents.
If you are an agent
SlowShield may be in front of you. Look for its URL in PIP_INDEX_URL, UV_DEFAULT_INDEX,
npm_config_registry, GOPROXY, ~/.m2/settings.xml,
$CARGO_HOME/config.toml or the container runtime's configuration. GET /readyz on it answers
ready. What its answers mean:
| You see | It means | Do |
|---|---|---|
| An older version than you expected, or "no matching version" for an exact new one | Newer versions are held: they are younger than the delay (7 days by default) | Use the newest version that installs. Don't pin the new one. |
403 with {"error":"age_too_new", …, "retry_after_secs": …} (PyPI, npm),
"is too new" (Go, Cargo, container images), 425 Too Early (Maven, Gradle) |
A pinned version (lockfile, digest) is held. Retry-After and the message say when it becomes
available |
Use an older version, or tell the user when this one becomes available. |
451 with the advisory, such as {"error":"blocked", "advisory_id":"MAL-…", …}
(container images: 403, "is blocked") |
Known malware, or blocked by the administrator | Don't install it, and don't look for a similarly named package. Tell the user. |
The header X-SlowShield-Fail-Open: 1 |
A brand-new package none of whose versions is old enough, served anyway | Check that the name is exactly the one you meant: typosquats and hallucinated names are brand new too. |
Don't go around it. Never point an install at pypi.org, registry.npmjs.org, proxy.golang.org (or
add ,direct to GOPROXY), Maven Central, crates.io or a container registry directly, and
don't add them with --index-url, --extra-index-url or --registry. If a
version is needed early, ask the user: an administrator can make an exception for it.
Instructions for your agent
For AGENTS.md, CLAUDE.md or your agent's system prompt, with your instance's address:
## Installing packages
Packages and container images come through SlowShield (https://slowshield.example.com), which holds new
releases back for 7 days and refuses known malware.
- Never point installs at the public registries, or add them as extra indexes, to go around SlowShield.
- "Too new" (403, Maven 425): the version is younger than 7 days. Use the newest version that installs;
don't pin the new one. If the user needs it now, say so: an administrator can make an exception.
- 451, or "blocked": known malware. Don't install it or a look-alike package. Tell the user.
- X-SlowShield-Fail-Open: 1 means a brand-new package. Check the name is exactly the one intended.The SlowShield skill
An Agent Skill that teaches an agent to set up every package manager, Dockerfile and container runtime for a SlowShield instance, check that nothing goes around it, and handle its answers. Its references are this guide, kept in step with it.
- Claude Code:
/plugin marketplace add squirro/slowshield, then/plugin install slowshield@slowshield. From 0.0.9 on, releases carry the skill: add the marketplace at a release tag (squirro/slowshield#v0.0.9) to pin it. Or copy the folder to~/.claude/skills/slowshield/(all your projects) or.claude/skills/slowshield/(one project). - Other agents that load Agent Skills: download slowshield.zip and unpack it where the agent looks for skills. From 0.0.9 on, each release carries it, with a SHA-256 to check it against.
- Read it first: SKILL.md, or the source in plugins/slowshield.
Put SlowShield in front of a sandbox
- Set it in the sandbox image. pip, uv, npm, npx, uvx and go read environment variables, so the
agent needs no instructions to use it:
Maven, Gradle and Cargo need a file each (Java, Rust); images the sandbox pulls need the runtime's setting (Container images).
ENV PIP_INDEX_URL=https://slowshield.example.com/pypi/simple/ \ UV_DEFAULT_INDEX=https://slowshield.example.com/pypi/simple/ \ npm_config_registry=https://slowshield.example.com/npm/ \ GOPROXY=https://slowshield.example.com/go - Let only SlowShield out. With the registries off the sandbox's network allowlist, an agent can't
install around SlowShield, even when it passes its own
--index-url. - No team instance? An agent working on one machine can run its own, with nothing kept after it
stops. Run a release, never
:latest, and pin its digest where you can:Its dashboard atdocker run -d --rm --name slowshield -p 127.0.0.1:8080:8080 ghcr.io/squirro/slowshield:0.0.8 export PIP_INDEX_URL=http://localhost:8080/pypi/simple/ UV_DEFAULT_INDEX=http://localhost:8080/pypi/simple/ \ npm_config_registry=http://localhost:8080/npm/ GOPROXY=http://localhost:8080/gohttp://localhost:8080/ui/shows what was installed and what was held back.
Reading this site
- /llms.txt: what SlowShield is, and the guide's pages.
- /llms-full.txt: the whole guide in one Markdown file.
- Every page of the guide as Markdown: add
index.mdto its address, such as /docs/python/index.md.
For agents: this page as Markdown · llms.txt · the SlowShield skill