Your agent’s CodeBuild sandbox just ran npm install lodash from the public registry, pulled a typosquat, and “fixed” a bug by executing a postinstall script that exfiltrated the task role credentials. Separately, every cold sandbox burns 90 seconds resolving the same dependency graph from the internet. AWS CodeArtifact is the unfair advantage: private npm/PyPI/Maven/Go mirrors with controlled upstreams, domain policies, and IAM so agent sandboxes never talk to the raw public internet for packages. Pair with CodeBuild sandboxes and ECR Lambda containers — this post is the package supply-chain layer.
⚡ TL;DR: Create a CodeArtifact domain + repos with upstreams to public registries. Grant sandboxes
codeartifact:GetAuthorizationToken+ read-only package permissions. Point npm/pip/go at the mirror; block direct egress to registry.npmjs.org / pypi.org where possible. Related: CodeBuild sandboxes, Verified Permissions, IAM condition keys.
Why public fetches fail agent sandboxes
Agent sandboxes (CodeBuild, Fargate tasks, Lambda custom runtimes) repeatedly:
- Clone a repo
- Install language dependencies
- Run tests / formatters / linters
Public registries create three failures:
| Failure | Symptom | CodeArtifact fix |
|---|---|---|
| Latency | 30–120s installs per sandbox | Cache hits inside your VPC/region |
| Supply chain | Typosquat / compromised maintainer | Upstream + optional package origin control / allowlists |
| Flaky egress | NAT timeouts, rate limits | Stable private endpoint + token |
# ❌ Agent buildspec talking to the public internet
phases:
install:
commands:
- npm install # hits registry.npmjs.org
- pip install -r requirements.txt # hits pypi.org
# ✅ Same sandbox via CodeArtifact
phases:
pre_build:
commands:
- export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \
--domain cheatcoders --domain-owner $ACCOUNT --query authorizationToken --output text)
- aws codeartifact login --tool npm --domain cheatcoders --repository agents-npm
- aws codeartifact login --tool pip --domain cheatcoders --repository agents-pypi
install:
commands:
- npm ci
- pip install -r requirements.txt
Domain, repos, and upstreams
One domain per org (or per prod vs sandbox). Repos per ecosystem; attach external upstreams so first fetch populates the private cache.
// ✅ CDK-ish: domain + npm repo with public upstream
import * as codeartifact from "aws-cdk-lib/aws-codeartifact";
const domain = new codeartifact.CfnDomain(this, "Domain", {
domainName: "cheatcoders",
});
const npmRepo = new codeartifact.CfnRepository(this, "NpmAgents", {
domainName: domain.domainName,
repositoryName: "agents-npm",
externalConnections: ["public:npmjs"], // ✅ upstream
});
const pypiRepo = new codeartifact.CfnRepository(this, "PypiAgents", {
domainName: domain.domainName,
repositoryName: "agents-pypi",
externalConnections: ["public:pypi"],
});
For stricter agents, publish an internal-only repo with no external connection and only packages your security team approved — slower onboarding, stronger guarantee.
# ✅ boto3: create repo without external connection (allowlist-only)
ca = boto3.client("codeartifact")
ca.create_repository(
domain="cheatcoders",
repository="agents-npm-locked",
description="No public upstream — publish approved packages only",
)
# ❌ create_repository(..., externalConnections=["public:npmjs"]) when you need a lock
IAM for CodeBuild / Fargate / Lambda sandboxes
Sandboxes need tokens and read access — not domain admin.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CodeArtifactAuth",
"Effect": "Allow",
"Action": ["codeartifact:GetAuthorizationToken", "sts:GetServiceBearerToken"],
"Resource": "*"
},
{
"Sid": "ReadPackages",
"Effect": "Allow",
"Action": [
"codeartifact:ReadFromRepository",
"codeartifact:GetRepositoryEndpoint",
"codeartifact:ListPackages",
"codeartifact:GetPackageVersion*"
],
"Resource": [
"arn:aws:codeartifact:REGION:ACCOUNT:repository/cheatcoders/agents-npm",
"arn:aws:codeartifact:REGION:ACCOUNT:repository/cheatcoders/agents-pypi",
"arn:aws:codeartifact:REGION:ACCOUNT:package/cheatcoders/agents-npm/*",
"arn:aws:codeartifact:REGION:ACCOUNT:package/cheatcoders/agents-pypi/*"
]
}
]
}
Tag agent roles and constrain with IAM condition keys. Deny codeartifact:PublishPackageVersion on sandbox roles — agents should consume, not publish, unless you have a deliberate “agent-built library” pipeline.
// ❌ Sandbox role with codeartifact:* — agent can delete repos / publish malware
Action: ["codeartifact:*"]
Wiring npm, pip, and go
# npm — after aws codeartifact login OR manual
registry=https://cheatcoders-ACCOUNT.d.codeartifact.REGION.amazonaws.com/npm/agents-npm/
//cheatcoders-ACCOUNT.d.codeartifact.REGION.amazonaws.com/npm/agents-npm/:_authToken=${CODEARTIFACT_AUTH_TOKEN}
# pip
pip config set global.index-url \
"https://aws:${CODEARTIFACT_AUTH_TOKEN}@cheatcoders-ACCOUNT.d.codeartifact.REGION.amazonaws.com/pypi/agents-pypi/simple/"
# Go modules via CodeArtifact (GOPROXY)
export GOPROXY="https://aws:${CODEARTIFACT_AUTH_TOKEN}@cheatcoders-ACCOUNT.d.codeartifact.REGION.amazonaws.com/go/agents-go/"
In CodeBuild sandboxes, put login in pre_build and refresh tokens (valid ~12 hours) at the start of each ephemeral project.
For Lambda container tools that vendor deps at image build time, run CodeArtifact login in the Dockerfile build stage on CodeBuild — not at Invoke — so SnapStart/cold paths never hit the registry.
Domain policies and debugging install failures
Attach a domain resource policy so only expected accounts/roles can read. When agents fail installs:
- Check token expiry (
GetAuthorizationToken) - Confirm repo endpoint matches tool config
- Check whether the package exists upstream vs blocked
- Inspect CodeArtifact CloudTrail for
ReadFromRepositorydenies
# ✅ Debug: list package versions the sandbox should see
ca = boto3.client("codeartifact")
print(ca.list_packages(domain="cheatcoders", repository="agents-npm", maxResults=20))
# ❌ Debugging by curling registry.npmjs.org from the sandbox — defeats the mirror
Combine with network controls: VPC endpoints for CodeArtifact, deny egress to public registry hosts in the sandbox security group / NAT firewall. Authorize the install_deps tool via Cedar / Verified Permissions so only approved sandboxes can mutate lockfiles.
Caching, retention, and agent CI performance
CodeArtifact caches upstream packages after the first pull. Cold sandboxes still pay once per unique version; warm orgs amortize. Set lifecycle policies so unused versions do not grow forever — but do not expire versions still pinned in production lockfiles your agents re-install hourly.
// ✅ Measure install time with and without mirror (emit EMF)
console.log(
JSON.stringify({
_aws: { Timestamp: Date.now(), CloudWatchMetrics: [{
Namespace: "CheatCoders/AgentSandbox",
Dimensions: [["tenant"]],
Metrics: [{ Name: "NpmInstallMs", Unit: "Milliseconds" }],
}]},
tenant: tenantId,
NpmInstallMs: elapsedMs,
mirror: "codeartifact",
})
);
Practical targets for coding-agent CI:
- Vendor or layer common toolchains in the CodeBuild image (
node_modulesfor formatters) so agents only resolve project deps. - Use
npm ci/ lockfiles — agents that rewritepackage.jsonfrom the model should still commit lockfile updates through a reviewed tool. - Prefer internal packages for company SDKs; publish once from a non-agent pipeline, consume from sandboxes.
- On security incidents, delete or block a package version in CodeArtifact and force agents to fail closed rather than falling back to public npm.
# ✅ Block a bad version after incident (ops, not agent)
aws codeartifact dispose-package-versions \
--domain cheatcoders --repository agents-npm \
--format npm --package evil-typosquat --versions 1.0.0
# ❌ Agent role allowed to dispose packages — ransomware-by-tool
When debugging “works on my laptop, fails in sandbox,” compare registry endpoints first. Ninety percent of agent install flakes are expired tokens or $LATEST build images without aws codeartifact login in pre_build.
Checklist
- [ ] Domain + per-ecosystem repos with intentional upstreams (or locked allowlist repos)
- [ ] Sandbox IAM: token + read only; no publish/delete
- [ ] CodeBuild/Fargate
pre_buildlogin; Lambda images bake deps at build time - [ ] Block or monitor direct public registry egress from agent sandboxes
- [ ] Tag-based IAM + Verified Permissions on install tools
- [ ] Alert on publish attempts from sandbox roles (should be zero)
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Distributed Locks Reality Check: When Redis Redlock Is the Wrong Tool
- Ai Differential Testing: AI Oracles Validated Against Shadow Traffic
- Spec-First AI Development: OpenAPI Remains the Only Source of Truth
- REST API Design Best Practices: The Patterns That Make APIs a Joy to Use
Newly added
- AWS Organizations SCPs: Hard Caps on What Coding-Agent Accounts Can Call
- Amazon Bedrock Prompt Management: Versioned System Prompts for Coding Agents
- AWS CodeArtifact: Private Package Mirrors Inside Coding-Agent Sandboxes
- Amazon MemoryDB: Durable Sub-Millisecond Session State for Multi-Turn Coding Agents
- AWS Lambda SnapStart: Cut Coding-Agent Cold Starts Without Always-On Waste
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.