- Built-in defaults — model APIs and agent keys, so a fresh install works.
~/.airlock/policy.toml— your global policy, applied to every repo..airlock.toml— per-repo overrides, read from the current directory.
network.allow,
env.passthrough, mounts.readonly, and mcp.enable. Only image.sandbox and
image.proxy replace the previous value.
Because lists only append, a policy file cannot remove a built-in default.
Which is why the defaults are kept minimal. Claude Code telemetry
(
statsig.anthropic.com) is not a default: the shipped allowlist is
dark, and telemetry is an explicit opt-in (see below).airlock init:
.airlock.toml
Airlock never touches your repo’s
.gitignore.
No credentials are stored in it; those live in ~/.airlock/secrets.toml.[network]
string
default:"allowlist"
allowlist — only listed hosts are reachable. blocklist — everything is
reachable except listed hosts.string[]
Hostnames the sandbox may reach, in
allowlist mode.string[]
Hostnames refused in
blocklist mode.openrouter.ai matches
api.openrouter.ai. Matching is case-insensitive, and a refusal is a 403
in either mode.
Choosing a mode
Both modes log identically: every request, allowed or refused, with host, path, byte counts, and duration. The mode changes what is refused, never what is recorded. Observability does not depend on being strict..airlock.toml
allowlist for repos touching sensitive systems, credentials, or
customer data — an unknown host is refused before it can matter.
Pick blocklist for ordinary development, where the cost of a blocked
package registry exceeds the risk of the request. Mode is per-repo policy, so
one team can run open while another runs strict.
blocklist mode does not weaken the boundary that makes egress
observable at all: the sandbox still has no route out except the proxy, so
every request is still attributed and logged. It widens what the proxy
permits, not what it sees.Allowlist mode
Allowed by default:
Enabled MCP connectors add their own domains on top of this.
Telemetry is opt-in. Claude Code’s telemetry host is deliberately absent
from the defaults, so nothing leaves the sandbox that you did not allow. To opt
in, add it yourself:
~/.airlock/policy.toml
[env]
string[]
Host environment variables copied into the sandbox, if set on the host.
ANTHROPIC_API_KEY, OPENAI_API_KEY,
OPENROUTER_API_KEY, XAI_API_KEY.
A variable that is not set on the host is silently skipped.
Airlock itself sets
AIRLOCK_REPO, AIRLOCK_USER_ID, and
AIRLOCK_USER_EMAIL in the sandbox and proxy containers — ids only, used
for event attribution. Tokens never enter a container.[mounts]
string[]
Extra read-only mounts, in
hostpath:containerpath form.:ro appended, so the agent can read them but not write them.
[image]
string
default:"airlock/base:latest"
Image used for the sandbox container.
string
default:"airlock/proxy:latest"
Image used for the egress proxy container.
[mcp]
string[]
MCP connectors enabled for this repo, by name.
airlock setup mcp. Enabling a connector widens the
egress allowlist with its domains and injects its credentials from
~/.airlock/secrets.toml. An unknown name here is a hard error at startup.
Secrets
Credentials never live in a repo or in a policy file. Identity is kept apart from connector credentials, because they are different trust domains:~/.airlock/secrets.toml(mode0600) — connector credentials, keyed by section, written byairlock setup mcp:
~/.airlock/secrets.toml
~/.airlock/auth.json(mode0600) — your identity, written byairlock login: the backend URL and an ingest-scoped API token.

