Route AI agent package installs through proxy cooldowns
How to make Codex, Claude Code, npm, and Python clients use Craftifact proxies with pull-policy cooldowns before new public package versions can install.
Quick path
- Create or select npm and Python proxy repositories for public package traffic.
- Attach a strict pull policy with a cooldown window.
- Commit project package-manager configuration that makes Craftifact the registry or package index.
- Add
AGENTS.mdguidance for Codex and import it fromCLAUDE.mdfor Claude Code. - Enforce the boundary with network or sandbox controls so the agent cannot bypass Craftifact.
What this protects against
A cooldown gate helps when a public package version is newly published, compromised, and then detected or removed before the cooldown expires. In strict mode, Craftifact keeps held versions out of npm package metadata and Python Simple API listings, and returns a policy hold for direct package-file pulls through the proxy. That means normal installs through those repositories cannot fetch the new version until the cooldown has passed or a trusted user fast-tracks it. The same pull policy can also hold or deny versions with known vulnerability findings when vulnerability rules are configured and analysis data is available.
This is not a malware guarantee. It does not help when the compromised version is already older than the cooldown, already cached and allowed, pinned in a lockfile before the policy was enabled, or fetched through a direct network path outside Craftifact. It also does not replace vulnerability triage, review of install scripts, dependency changes, and the agent’s proposed commands.
Configure the Craftifact gate
Use a strict pull policy for the npm and Python proxies used by AI coding agents. A 72-hour window is a practical starting point for public dependencies because many broad supply-chain incidents are discovered and remediated within hours, while the Fast-track workflow still lets you approve an urgent release deliberately.
pull_policies:
default: agent-package-cooldown
agent-package-cooldown:
enforcement_mode: strict
cooldown:
minimum_release_age: 72h
unknown_release_time: use_first_seen
vulnerabilities:
max_severity: high
unknown_analysis: allow
repositories:
- name: npm-public
type: npm_proxy
upstream_url: https://registry.npmjs.org
pull_policy:
policy: agent-package-cooldown
- name: python-public
type: python_proxy
upstream_url: https://pypi.org
pull_policy:
policy: agent-package-cooldown
Use unknown_release_time: hold instead when the repository should block packages with missing publish-time metadata until a human fast-tracks them.
Use vulnerabilities.unknown_analysis: hold only when you want packages without ready vulnerability analysis to wait for analysis or manual review.
Use the Fast-track action for a held package only after reviewing the package, release notes, maintainer context, and the reason the agent needs it.
Commit package-manager configuration
Commit the registry and package-index URLs, but keep tokens in environment variables or user-level package-manager config.
registry=https://packages.example.com/repository/npm/npm-public/
audit=false
fund=false
//packages.example.com/repository/npm/npm-public/:_authToken=${CRAFTIFACT_NPM_TOKEN}
For Python, commit the package index URL without credentials when that fits your workflow:
[global]
index-url = https://packages.example.com/repository/python/python-public/simple/
disable-pip-version-check = true
Then provide credentials through the agent or CI environment:
export PIP_INDEX_URL="https://__token__:${CRAFTIFACT_PYTHON_TOKEN}@packages.example.com/repository/python/python-public/simple/"
Do not put ${CRAFTIFACT_PYTHON_TOKEN} directly in pip.conf; pip treats it as literal text instead of expanding the environment variable.
For Poetry, use the same Python Simple API URL and store credentials separately:
poetry source add --priority=primary craftifact \
https://packages.example.com/repository/python/python-public/simple/
poetry config http-basic.craftifact __token__ "$CRAFTIFACT_PYTHON_TOKEN"
Use robot tokens with read access to the proxy repositories.
Regenerate lockfiles after switching the package source, or check that existing lockfiles do not pin direct public-registry URLs:
rg "registry\.npmjs\.org|npmjs\.com|pypi\.org|pythonhosted\.org" package-lock.json npm-shrinkwrap.json pnpm-lock.yaml yarn.lock requirements*.txt poetry.lock uv.lock Pipfile.lock
If this finds direct public registry or package-host URLs, regenerate the lockfile through Craftifact before relying on the cooldown gate.
Add shared agent instructions
Codex reads AGENTS.md.
Claude Code reads CLAUDE.md, so keep one source of truth by importing AGENTS.md.
These files guide the agent, but they are not a security boundary by themselves.
# AGENTS.md
## Dependency installs
- Use the committed package manager and lockfile.
- Use only this npm registry for installs: `https://packages.example.com/repository/npm/npm-public/`.
- Use only this Python package index for installs: `https://packages.example.com/repository/python/python-public/simple/`.
- Do not run npm, pnpm, Yarn, npx, pnpm dlx, yarn dlx, pip, pipx, Poetry, uv, or PDM commands that fetch packages from public registries directly.
- Do not change `.npmrc`, `pip.conf`, lockfile registry URLs, or package-manager source settings unless the user explicitly asks for that change.
- If Craftifact returns a policy hold, stop and report the package name, version, and `X-Craftifact-Policy-Reason`.
# CLAUDE.md
@AGENTS.md
Keep the registry and index URLs in the instruction file aligned with the committed package-manager configuration.
Enforce the boundary in Codex
For Codex Cloud environments, set agent internet access to an empty allowlist plus your Craftifact instance host.
For install-only tasks, allow only GET, HEAD, and OPTIONS.
Avoid the common-dependencies preset for this workflow because it includes public package registries.
Setup scripts still run with internet access, so make sure setup commands also use the committed .npmrc and do not install directly from public npm.
For Python setup commands, make sure pip, uv, Poetry, and related tools use the Craftifact Python Simple API URL.
For local Codex sessions, enforce the same boundary outside the agent with your workstation sandbox, container, firewall, or CI network policy.
Enforce the boundary in Claude Code
Claude Code can enforce outbound network domains for sandboxed shell commands. In a shared project setting, allow only the Craftifact instance host for agent sessions that should install npm or Python packages through the proxies.
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"network": {
"allowedDomains": ["packages.example.com"],
"deniedDomains": [
"registry.npmjs.org",
"*.npmjs.org",
"npmjs.com",
"*.npmjs.com",
"pypi.org",
"*.pypi.org",
"pythonhosted.org",
"*.pythonhosted.org"
]
}
}
}
If the agent also needs source-control, issue-tracker, or documentation network access, add those domains deliberately and keep public npm and Python package domains denied.
Verify the setup
Run these checks in the same environment the agent will use:
npm config get registry
npm view react version --registry https://packages.example.com/repository/npm/npm-public/
export PIP_INDEX_URL="https://__token__:${CRAFTIFACT_PYTHON_TOKEN}@packages.example.com/repository/python/python-public/simple/"
python -m pip index versions requests
Then ask the agent to explain which npm registry and Python package index it is allowed to use before it runs an install.
For Codex, also ask it to list the active AGENTS.md instructions.
For Claude Code, use its memory view to confirm the CLAUDE.md import loaded.
When a package is inside the cooldown window, a strict Craftifact policy returns a hold response with policy decision headers instead of silently falling back to public package registries. Treat that as the control working, not as an install failure to bypass.
Related pages
- For npm and Python client authentication, see Configure client tools for package formats.
- For policy fields and Fast-track behavior, see Instance configuration reference.
- For token issuance, see Create a robot account and use its token.
- For Codex instruction loading, see Custom instructions with AGENTS.md.
- For Codex environment network controls, see Agent internet access.
- For Claude Code project instructions and sandbox network settings, see Claude Code memory and Claude Code settings.