A local HTTP/HTTPS forward proxy that gates network egress against a hostname allowlist. Built for deny-by-default sandboxes — coding agents, CI workers, isolated build steps — where you want one choke point the sandbox can permit, with every other route to the network closed.
The proxy ships with zero compiled-in opinions about which hosts to allow. Bring your own list — either inline via env or by pointing at one or more plain-text files. Teams typically check those files into their repo so everyone shares the same baseline.
npm install -g @clipboard-health/clearance
This installs two binaries: clearance (the proxy) and clearance-ensure
(idempotent daemon launcher).
CLEARANCE_ALLOW_HOSTS=api.example.com clearance
Then point tools at http://127.0.0.1:19999 with HTTP_PROXY and
HTTPS_PROXY.
By default the proxy listens on 127.0.0.1:19999, allows destination port
443, and blocks private, loopback, link-local, multicast, documentation,
and other non-public IP ranges after DNS resolution.
If neither CLEARANCE_ALLOW_HOSTS nor CLEARANCE_ALLOW_HOSTS_FILES is
set, the proxy refuses to start.
A file is a plain-text list of hosts, one per line. Blank lines are ignored,
# introduces a comment to end-of-line, and trailing dots / wildcard
prefixes (*.example.com) are normalized.
# AI agents
api.openai.com
api.anthropic.com
# Source code
github.com
api.github.com
*.githubusercontent.com
Point at one or more files via CLEARANCE_ALLOW_HOSTS_FILES using your
platform's PATH delimiter — : on macOS/Linux, ; on Windows. The values
from CLEARANCE_ALLOW_HOSTS, all referenced files, and any duplicates
are concatenated and deduped.
CLEARANCE_ALLOW_HOSTS_FILES="$REPO/clearance-allow-hosts:$HOME/.config/clearance/personal-hosts" \
clearance
This is how teams share a baseline: check a team-allow-hosts file into
your repo, and let individuals layer a personal file on top via the same
env var.
| Variable | Default | Notes |
|---|---|---|
CLEARANCE_ALLOW_HOSTS |
(unset) | Comma- or whitespace-separated exact hosts and wildcard suffixes. |
CLEARANCE_ALLOW_HOSTS_FILES |
(unset) | PATH-delimited paths (: macOS/Linux, ; Windows) to plain-text host files (# comments, blank lines). |
CLEARANCE_ALLOW_PORTS |
443 |
Comma- or whitespace-separated TCP ports. |
CLEARANCE_LISTEN_HOST |
127.0.0.1 |
Bind host. |
CLEARANCE_PORT |
19999 |
Bind port. |
CLEARANCE_DNS_TTL_MS |
60000 |
In-process DNS cache TTL. |
CLEARANCE_IDLE_TIMEOUT_MS |
120000 |
Socket idle timeout. |
CLEARANCE_MAX_SOCKETS |
1024 |
Inbound connection cap and outbound HTTP agent cap. |
CLEARANCE_ALLOW_PRIVATE_IPS |
(unset) | Set to 1 to disable private/non-public IP blocking for local testing. |
clearance-ensureclearance-ensure checks 127.0.0.1:19999; if no proxy is listening it
spawns one detached using the same env vars and waits for it to bind. Logs
live at ${XDG_CACHE_HOME:-$HOME/.cache}/clearance/clearance.log,
pid at …/clearance.pid.
CLEARANCE_ALLOW_HOSTS_FILES="$REPO/clearance-allow-hosts" clearance-ensure
clearance-ensure accepts an optional subcommand. With none, it defaults to
start (the idempotent launch above). All subcommands discover the running
proxy through the pidfile.
| Command | Behavior |
|---|---|
clearance-ensure |
Default start: launch the proxy if nothing is already listening. |
clearance-ensure start |
Same as the bare invocation. |
clearance-ensure stop |
Signal the pidfile process to terminate, wait for the port to close, and remove the pidfile. |
clearance-ensure restart |
stop the existing proxy (if any), then start a fresh one. Use this to pick up edited host files. |
clearance-ensure status |
Report whether the proxy is listening and its pid. Exits non-zero when it is not running. |
To pick up edited allow-host files, restart in one step:
CLEARANCE_ALLOW_HOSTS_FILES="$REPO/clearance-allow-hosts" clearance-ensure restart
Safehouse uses macOS sandbox profiles, so
this section is for macOS hosts only. Safehouse allows network access by
default for agent compatibility.
To force a wrapped agent through this proxy, run the proxy outside
Safehouse, then append a Safehouse profile that denies direct remote
egress while leaving localhost open for http://127.0.0.1:19999.
The package ships a safehouse-clearance wrapper plus the matching
clearance.env and clearance-only.sb profile. After a global install,
the wrapper lives at $(npm root -g)/@clipboard-health/clearance/safehouse/safehouse-clearance.
It ensures the proxy is running, then execs safehouse with the env file and
sandbox profile alongside it. It does not parse or rewrite your
arguments — anything you pass is forwarded verbatim, so put any safehouse
flags before the agent command:
SAFEHOUSE_CLEARANCE="$(npm root -g)/@clipboard-health/clearance/safehouse/safehouse-clearance"
"$SAFEHOUSE_CLEARANCE" \
--enable=cloud-credentials --env-pass=AWS_PROFILE,AWS_REGION \
-- codex --dangerously-bypass-approvals-and-sandbox
For day-to-day agent use, configure your allow-host files and add shell aliases:
SAFEHOUSE="$(npm root -g)/@clipboard-health/clearance/safehouse"
export CLEARANCE_ALLOW_HOSTS_FILES="$HOME/code/<your-repo>/clearance-allow-hosts:$HOME/.config/clearance/personal-allow-hosts"
alias codex-proxy="$SAFEHOUSE/safehouse-clearance codex --dangerously-bypass-approvals-and-sandbox"
alias claude-proxy="$SAFEHOUSE/safehouse-claude-proxy"
safehouse-claude-proxy runs Claude through Safehouse with
--permission-mode auto. When launched from a cmux terminal, it preserves
cmux's Claude shim by forwarding the cmux session environment and granting
read-only access to the cmux app/socket state and generated Codex hooks. The
integration also grants cmux's existing Sentry cache write access so diagnostics
cannot corrupt hook JSON output. It points the shim at the real Claude binary so
the shim does not recurse through itself.
The cmux environment pass-through is an explicit reviewed allowlist. If a cmux
update adds new CMUX_* variables to its Claude wrapper contract,
safehouse-claude-proxy prints a warning naming the unreviewed variables
instead of automatically passing every CMUX_* value through the sandbox.
For AWS SSO work, log in on the host first, then layer the safehouse cloud credentials flag through the wrapper:
aws sso login --profile <profile>
AWS_PROFILE=<profile> "$SAFEHOUSE/safehouse-clearance" \
--enable=cloud-credentials --env-pass=AWS_PROFILE,AWS_REGION,AWS_SDK_LOAD_CONFIG,AWS_CONFIG_FILE,AWS_SHARED_CREDENTIALS_FILE,AWS_CA_BUNDLE \
-- codex --dangerously-bypass-approvals-and-sandbox
Make sure your allow-host file includes the AWS endpoints you need
(typically *.amazonaws.com, *.api.aws, *.awsapps.com, *.ecr.aws).
If you'd rather not depend on the bundled assets, you can build the same setup by hand.
mkdir -p ~/.config/agent-safehouse
cat > ~/.config/agent-safehouse/clearance-only.sb <<'SB'
;; Force remote network egress through the local clearance while keeping
;; localhost available for local-only agent workflows.
(deny network-outbound
(remote ip "*:*")
(remote tcp "*:*")
(remote udp "*:*"))
(allow network-outbound
(remote ip "localhost:*")
(remote tcp "localhost:*")
(remote udp "localhost:*"))
SB
cat > ~/.config/agent-safehouse/clearance.env <<'ENV'
HTTP_PROXY="http://127.0.0.1:19999"
HTTPS_PROXY="http://127.0.0.1:19999"
ALL_PROXY="http://127.0.0.1:19999"
NO_PROXY="localhost,127.0.0.1,::1"
http_proxy="${HTTP_PROXY}"
https_proxy="${HTTPS_PROXY}"
all_proxy="${ALL_PROXY}"
no_proxy="${NO_PROXY}"
ENV
Then run the wrapped command with Safehouse:
safehouse \
--env="$HOME/.config/agent-safehouse/clearance.env" \
--append-profile="$HOME/.config/agent-safehouse/clearance-only.sb" \
-- <agent-command>
Do not pass API-key environment variables just for proxying. The env file only supplies proxy settings; agents should continue to use their normal auth/config stores.
Quick checks:
# Should use the proxy and usually return 401 without auth.
safehouse --env="$HOME/.config/agent-safehouse/clearance.env" \
--append-profile="$HOME/.config/agent-safehouse/clearance-only.sb" \
-- curl -I https://api.openai.com/v1/models
# Should fail because this bypasses the proxy and tries direct egress.
safehouse --env="$HOME/.config/agent-safehouse/clearance.env" \
--append-profile="$HOME/.config/agent-safehouse/clearance-only.sb" \
-- curl --noproxy '*' -I https://api.openai.com/v1/models
# Should be denied by the proxy unless example.com is in your allow-host list.
safehouse --env="$HOME/.config/agent-safehouse/clearance.env" \
--append-profile="$HOME/.config/agent-safehouse/clearance-only.sb" \
-- curl -I https://example.com
For developers working on the package itself, the source lives in ClipboardHealth/core-utils. After npm install in the repo, the bin scripts dispatch through a runCli helper that detects no compiled JS and re-execs node with --conditions @clipboard-health/source, so the proxy runs straight from TypeScript source — no build step:
cd ~/dev/c/core-utils
CLEARANCE_ALLOW_HOSTS=api.example.com node ./packages/clearance/bin/run.js
Requires Node ≥ 24.3 (native .ts type stripping enabled by default).