# 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](https://agentskills.io) 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](https://slowshield.org/skills/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](https://slowshield.org/skills/slowshield/SKILL.md), or the source in [plugins/slowshield](https://github.com/squirro/slowshield/tree/main/plugins/slowshield).

## Put SlowShield in front of a sandbox

1. **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:
   ```
   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
   ```
   Maven, Gradle and Cargo need a file each ([Java](https://slowshield.org/docs/java/), [Rust](https://slowshield.org/docs/rust/)); images the sandbox pulls need the runtime's setting ([Container images](https://slowshield.org/docs/containers/)).

2. **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`.

3. **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:
   ```
   docker 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/go
   ```
   Its dashboard at `http://localhost:8080/ui/` shows what was installed and what was held back.

## Reading this site

- [/llms.txt](https://slowshield.org/llms.txt): what SlowShield is, and the guide's pages.

- [/llms-full.txt](https://slowshield.org/llms-full.txt): the whole guide in one Markdown file.

- Every page of the guide as Markdown: add `index.md` to its address, such as [/docs/python/index.md](https://slowshield.org/docs/python/index.md).

---

This page as HTML: https://slowshield.org/docs/agents/. All of the guide in one file: https://slowshield.org/llms-full.txt
