7 Steps: Securing AI Agents After npm Supply Chain Attacks
A practical checklist for founders/CTOs of SMEs following npm supply chain attacks. 7 steps: sandbox (Windows/Docker), egress, SBOM, dependency scanning, pinned + provenance, tool call allowlisting, Vercel AI Gateway, and telemetry. Includes short JSON/YAML snippets.

Key takeaways
- Isolate agents in a sandbox (Windows/Docker) and block egress by default.
- Generate SBOM and scan dependencies in CI; fail the build on high risks.
- Use pinned dependencies and provenance in npm; install via npm ci.
- Implement tool call allowlisting and parameter validation.
- Route LLM traffic through Vercel AI Gateway and rotate keys per agent.
- Collect agent event telemetry and alert on anomalies.
In light of recent npm supply chain incidents (e.g., TanStack) and fake repositories on Hugging Face, the default configuration of AI agents in Next.js/Node/Windows can be an easy attack vector. Here are 7 steps: sandbox and egress, SBOM + scanning, pinned versions with provenance, tool call allowlisting, key management via Vercel AI Gateway, and telemetry — with short snippets for implementation within a week.
Is Your AI Agent in Next.js/Node at Risk?
An AI agent is an autonomous component executing tasks based on prompts and access to tools. A prompt is a set of input instructions (from a user, system, or another agent) that defines the goal, context, and constraints of the action, e.g., "fix bug X in repo Y, using only searchDocs and createIssue." A tool call is a specific invocation of a tool available to the agent (e.g., documentation search, creating a PR). Each of these can open an attack surface.
Recently, we have seen notable supply chain incidents (e.g., TanStack) and fake repositories on Hugging Face. Adoption of agents in SMEs (Next.js/TypeScript/Windows) is on the rise, and so is the risk. Attackers target: npm dependencies, postinstall scripts, excessive permissions in tool calls, unrestricted egress, and key leaks.
Conclusion: assume an incident will occur. Mitigate the impact with the 7 steps below.
- npm dependencies and compromised maintainer accounts
- install/postinstall scripts running in CI/production
- tool calls executing code or accessing resources without limits
- unrestricted egress (data/key exfiltration)
- API keys in logs and lack of rotation
Step 1-2: Sandbox (Windows/Docker) and Default Egress Blocking
Step 1. Isolate coding agents in a sandbox. On Windows, use Windows Sandbox for code generation/execution tasks. On Linux/hosting, use Docker with restrictions. Example configuration for Windows Sandbox (.wsb) – disables network and GPU, mounts only the working directory in read-only mode, and starts the agent without a user profile; thus minimizing egress, permissions, and the persistence of any potential attack:
<Configuration> <VGpu>Disable</VGpu> <Networking>Disable</Networking> <MappedFolders> <MappedFolder> <HostFolder>C:\agents\work</HostFolder> <ReadOnly>true</ReadOnly> </MappedFolder> </MappedFolders> <LogonCommand> <Command>powershell -NoProfile -ExecutionPolicy Bypass npm ci; node agent.js</Command> </LogonCommand> </Configuration>
Example Docker Compose (isolation, no network by default):
version: "3.8" services: agent: image: node:20-alpine user: "1000:1000" read_only: true cap_drop: ["ALL"] security_opt: - no-new-privileges:true network_mode: none tmpfs: - /tmp:rw,noexec,nosuid,nodev command: ["node","agent.js"] environment: - NODE_ENV=production
- Sandbox for tasks involving code execution; everything else in a standard environment.
- Clean and destroy the environment after the task (ephemeral).
- Do not mount credentials/secrets to the sandbox unless necessary.
Step 3-4: Node.js SBOM and Dependency Scanning in CI
Step 3. Generate an SBOM (Software Bill of Materials) with every build. Minimum start:
npx @cyclonedx/cyclonedx-npm@latest --output-file sbom.json
Alternatively, use Syft (CycloneDX): syft dir:. -o cyclonedx-json=sbom.json
Step 4. Scan dependencies and block the build on high risks. Combine npm audit and image/library scanners (e.g., Grype). Minimum GitHub Actions workflow:
- name: sbom-and-scan on: [push] jobs: ci: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 20 } - run: npm ci --ignore-scrip
Step 5-6: Pinned Dependencies and Provenance in npm
Step 5. Pinned dependencies and strict installation rules. Enforce exact versions and no scripts in CI/production. Example .npmrc:
save-exact=true audit=true engine-strict=true fund=false ignore-scripts=true
Installation in CI/PROD: npm ci --ignore-scripts --omit=dev
For transitive dependencies, use overrides in package.json: { "overrides": { "axios": "1.6.8" } }, and perform updates in batches and controlled (e.g., once a week). Step 6. Provenance for your own packages: publish with signature/attestation (npm publish --provenance) using GitHub OIDC. For external packages, maintain a whitelist of publishers/orgs and sources (check repository.url and maintainers).
- Use npm ci instead of npm install in CI and production.
- Block postinstall; enable only for packages that require it, in an isolated step.
- Update dependencies in a controlled manner (renovate/pnpm update – not ad hoc).
- Publish your own packages with provenance; consume external ones from the allowlist.
Step 7: Allowlist Tool Calls, Vercel AI Gateway, and Telemetry/Alerts
Step 7a. Tool call allowlisting and parameter validation. Define only necessary tools and validate input. Example (TypeScript + zod):
const ALLOWED_TOOLS = ["searchDocs","createIssue"] as const; const searchDocs = { name: "searchDocs", parameters: z.object({ query: z.string().max(200) }), execute: async ({ query }) => {/* ... */} }; function guardToolCall(name:string){ if(!(ALLOWED_TOOLS as readonly string[]).includes(name)) throw new Error("blocked_tool:"+name);}
Step 7b. Key and traffic control through Vercel AI Gateway. Use separate keys per agent/environment, tag requests, and set limits/redirect models in the Gateway. Minimum call with usage tag:
const resp = await fetch(process.env.AI_GATEWAY_URL!,{ method:"POST", headers:{ "Authorization":"Bearer "+process.env.AI_GATEWAY_KEY, "x-usage-tag":"agent:codebot:prod" }, body: JSON.stringify({ model:"openai:gpt-4.1-mini", input }) }); // rotate AI_GATEWAY_KEY every 30 days; keep in Server-only env
- Keys per agent and environment; automatic rotation.
- Enable request limits and logging in the Gateway; filter by x-usage-tag.
- If possible, block direct provider calls (only through Gateway).
These 7 steps significantly reduce the impact of npm supply chain attacks and AI agent abuses. Start with sandboxing and egress, then enable SBOM/scanning, pin dependencies, and secure tool calls and keys. If you'd like, we can review your repo and environment in a 90-minute consultation and create an implementation plan for the week.
Frequently asked questions
Does Next.js on Vercel allow egress blocking?
On Vercel (Serverless/Edge), you cannot configure a platform-level egress firewall. Implement a host allowlist in your code (e.g., a custom wrapper for fetch) and route LLM traffic exclusively through Vercel AI Gateway. In your own infrastructure, use Docker/k8s with NetworkPolicy or an egress proxy.
Is Windows Sandbox sufficient for production?
No. Windows Sandbox is not a production-grade environment and does not offer the required guarantees for management, networking, and observability. Treat it only for short, isolated tasks without secrets. In production, use containers or VMs with egress control/allowlist, signed images, minimal permissions, monitoring, and auditing.
Are pinned dependencies enough if a package is compromised?
No. Pinned dependencies limit version drift, but if the pinned version itself is compromised, you will install malicious code. Lockfiles and integrity hashes protect against artifact substitution, not against malicious publication. You need: SBOM + scanning in CI, --ignore-scripts in the build, publisher/org allowlists and provenance, code review diffs, isolated executions, and quick rollback.
How quickly can I implement SBOM in a Node/pnpm monorepo?
Generate SBOM at the workspace and per package level. The simplest way: run Syft in the repo directory (CycloneDX JSON) or per package (pnpm -r exec syft dir:. -o cyclonedx-json=sbom.json). In CI, add a step after pnpm install --frozen-lockfile. Archive artifacts and scan them with Grype; interrupt builds on high/critical.