core-utils
    Preparing search index...

    Module @clipboard-health/clearance

    clearance

    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-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).

    ClearanceCheckInput
    ClearanceConfig
    ClearanceLogger
    CreateClearanceServerOptions
    EnsureClearanceInput
    EnsureClearanceResult
    ProcessKillInput
    ResolveAllowlistInput
    ResolveSafehouseCmuxIntegrationInput
    RestartClearanceInput
    SafehouseCmuxIntegration
    SpawnClearanceInput
    StartClearanceFromEnvInput
    StatusClearanceInput
    StatusClearanceResult
    StopClearanceInput
    StopClearanceResult
    ClearanceCommand
    ClearanceListenerCheck
    ClearanceSpawner
    DnsLookup
    ProcessKiller
    CLEARANCE_PACKAGE_NAME
    SAFEHOUSE_CMUX_CLAUDE_COMMAND_PRELUDE
    SAFEHOUSE_CMUX_ENV_PASS
    SAFEHOUSE_CMUX_WRAPPER_LOCAL_ENV_NAMES
    createClearanceServer
    ensureClearance
    isClearanceListening
    parseClearanceCommand
    resolveAllowlist
    resolveClearanceConfig
    resolveSafehouseCmuxIntegration
    restartClearance
    safehouseCmuxIntegrationWarningLines
    spawnClearance
    startClearanceFromEnv
    statusClearance
    stopClearance