CLAUDE LABJP
OPUS5 — Claude Code v2.1.219 makes Claude Opus 5 the default Opus model, with a 1M context window and fast-mode pricing of $10/$50 per million input/output tokensSONNET5 — Claude Sonnet 5 is now the default model for Free and Pro worldwide, with introductory pricing of $2/$10 per million input/output tokens through August 31SANDBOX — Claude Code adds sandbox.network.strictAllowlist, letting you deny any host that isn't on the allowlist for sandboxed commandsSTREAM — stream-json output now supports nested subagent forwarding, so you can trace inner exchanges across multi-layer agent setupsSKILL — The open-source Claude API skill, bundled with Claude Code, gives up-to-date Messages API and Managed Agents references across eight languagesVOICE — Voice mode now runs on Opus, Sonnet, and Haiku, reaches connected tools like Gmail and Slack, and speaks many more languagesOPUS5 — Claude Code v2.1.219 makes Claude Opus 5 the default Opus model, with a 1M context window and fast-mode pricing of $10/$50 per million input/output tokensSONNET5 — Claude Sonnet 5 is now the default model for Free and Pro worldwide, with introductory pricing of $2/$10 per million input/output tokens through August 31SANDBOX — Claude Code adds sandbox.network.strictAllowlist, letting you deny any host that isn't on the allowlist for sandboxed commandsSTREAM — stream-json output now supports nested subagent forwarding, so you can trace inner exchanges across multi-layer agent setupsSKILL — The open-source Claude API skill, bundled with Claude Code, gives up-to-date Messages API and Managed Agents references across eight languagesVOICE — Voice mode now runs on Opus, Sonnet, and Haiku, reaches connected tools like Gmail and Slack, and speaks many more languages
Articles/Claude Code
Claude Code/2026-07-25Advanced

Locking down Claude Code sandbox egress with strictAllowlist

Using sandbox.network.strictAllowlist in Claude Code v2.1.219 to tighten an automation pipeline's outbound traffic to a minimal allowlist, with a runnable script to discover real destinations and the pitfalls I hit.

Claude Code202SandboxSecurity10Automation40Networking

Premium Article

Late one night, my automated publishing pipeline stopped partway through without saying why.

The logs showed something that looked like a connection timeout. I blamed the network, re-ran it, and sometimes it went through. Classic "flaky network" behavior. Except the network was fine. A single host I had forgotten to add to the allowlist was being quietly refused.

This happened right after I turned on sandbox.network.strictAllowlist, added in Claude Code v2.1.219 (2026-07-24). As an indie developer running this pipeline solo, I want to share the field notes from folding that setting into my automation. I will spend less time on how to enable it and more on what broke afterward and how I tracked it down.

A "deny" wears the mask of an outage

The idea behind strictAllowlist is simple. For commands run inside the sandbox, refuse any outbound connection to a host that is not on the allowlist. It is a sensible way to run automation with a safe default.

But running it taught me that the deny itself is less troublesome than how the deny appears.

A connection to a host missing from the allowlist looks, from the application's point of view, like an ordinary connection failure. Most tools interpret that as "the network is unhealthy" and surface a retry or timeout message. In other words, an intentional policy block shows up wearing the face of a random network outage. That was the first pitfall. To work around this trap, observe the facts before you guess at the cause.

So the first thing I did was not to write an allowlist. It was to observe, once and completely, which hosts the pipeline actually reaches out to.

Discover the hosts you really touch

The "it probably connects to this host" in your head is not reliable. Trace connect(2) and collect destinations as facts. The script below wraps any command and prints the hostnames it connects to.

#!/usr/bin/env bash
# egress-recon.sh — discover which hosts a command actually connects to
# usage: ./egress-recon.sh <command to run...>
#   e.g. ./egress-recon.sh bash deploy-pipeline.sh
set -euo pipefail
 
TRACE="$(mktemp)"
trap 'rm -f "$TRACE"' EXIT
 
# follow only connect(2), recording destination addresses
# -f: follow child processes (git and npm spawn many)
strace -f -qq -e trace=connect -o "$TRACE" "$@" || true
 
# extract IPv4 destinations: sin_addr=inet_addr("x.x.x.x")
grep -oE 'inet_addr\("[0-9.]+"\)' "$TRACE" \
  | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' \
  | sort -u > "$TRACE.ip"
 
echo "# destination hosts (reverse-resolved, deduped)"
while read -r ip; do
  # skip local / link-local
  case "$ip" in 127.*|0.0.0.0|169.254.*) continue;; esac
  host="$(getent hosts "$ip" | awk '{print $2}')"
  printf '%-24s %s\n' "${host:-"(no PTR)"}" "$ip"
done < "$TRACE.ip" | sort -u

The key flag is -f. Both git push and npm install hand the real work to child processes. Watch only the parent and you miss the connections that matter. For any IP that has no reverse record, keep the raw IP and reconcile its purpose against the log described later.

Running this once in my environment, the destinations came to eleven hosts. I had expected four. Roughly 2.7x what I anticipated.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A runnable script that traces connect(2) to reveal every host your pipeline actually contacts
Why allowing a single hostname per service is not enough, with the exact failure I hit
An observability pattern that separates a policy block from a real network outage
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Claude Code2026-07-17
The String I Approved Wasn't the String I Read — Testing a Relayed Permission Prompt with Deceptive Characters
I pushed bidi overrides and zero-width characters through my own approval relay. NFKC normalization caught 0%. Here is why, and the implementation that catches 100% with zero false positives.
Claude Code2026-07-05
Rolling Out Trusted Devices for a Small Team: Enrollment, Preflight, and Rotation
How to introduce Team/Enterprise Trusted Devices for a 2-5 person team: device enrollment, an unattended-run preflight gate, and closing the gaps that appear during device rotation and offboarding.
Claude Code2026-06-29
Borrowing the Trusted Devices Idea for a Solo Setup: Pinning Automated Runs to Devices You Approved
The Trusted Devices feature that landed in Claude Code on June 28, 2026 is for Team and Enterprise. You can't use the feature on a solo plan, but you can borrow the idea. Here is how to identify a device in a way that doesn't break, and stop any automated run that starts from a device you never approved — with working code and the traps to avoid.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →