Network controls are runtime policy managed through the admin UI/API, not
deployment config. By default, all network access for the agent is closed. The
host opens network access incrementally through PUT /v1/network/policy.
Network controls govern the agent and host service users, not root-owned host
bootstrap and maintenance work. At the host firewall, root (uid 0) has outbound
access for package installation, security updates, and ordinary root-owned
system traffic. The dedicated trustyclaw-proxy uid has outbound access only so
it can make policy-approved upstream connections on behalf of the agent. When
Cloudflare Access operator access is configured, the dedicated cloudflared uid
has outbound access only for DNS, TCP 443, and TCP/UDP 7844. The host does
not install or configure the AWS SSM agent, and snapd is stopped and masked
during bootstrap. Root, proxy, and optional cloudflared egress are still
bounded by the EC2 security group, which keeps TCP/UDP 7844 open only when a
cloudflare_access operator endpoint is configured. That 7844 rule is
outbound-only and nftables allows it only for the cloudflared uid, not for the
agent, admin API, or proxy users; it does not expose an inbound EC2 port. The
agent runs as a non-root user with no sudo, so it reaches root's broader path
only if it first escalates to root.
Normal HTTP requests are configured per domain in allowed_network_access.
allow_http_methods opens outbound HTTP over TCP port 80 and HTTPS over TCP
port 443 for the configured domain, subject to the listed methods and path
restrictions. The agent cannot resolve DNS names itself; a domain is resolved on
the host's controlled path only while an allowed request to it is being proxied.
{
"managed_ai_provider_network_access": {
"openai": true
},
"allowed_network_access": {}
}| Field | Required | Type | Behavior |
|---|---|---|---|
managed_ai_provider_network_access |
No | object | Managed AI provider network bundles. Set openai: true to enable Codex/OpenAI access and claude: true to enable Claude Code/Anthropic access. Missing keys or explicit false disable that provider; the related runtime starts and remains deactivated until policy enables it. |
allowed_network_access |
Yes | object | Map of domain rules. Keys are exact domains or wildcard suffix domains. Wildcards must start with *., such as *.example.com; * matches any non-empty hostname prefix ending at that dot. Embedded globs and regex keys are not supported. |
When managed_ai_provider_network_access.openai is true, Codex tasks can run
after Codex OAuth login. The host automatically adds these managed domain rules:
{
"api.openai.com": {
"allow_http_methods": ["POST"],
"openai_account_guard": true,
"openai_disable_live_web_search": true
},
"auth.openai.com": {
"allow_http_methods": ["GET", "POST"]
},
"chatgpt.com": {
"allow_http_methods": ["GET", "POST"],
"openai_account_guard": true,
"openai_disable_live_web_search": true
}
}Do not list openai.com, chatgpt.com, or their subdomains in
allowed_network_access; the parser rejects those rules because they are
managed by managed_ai_provider_network_access.openai. The OpenAI live web
search guard and account guard are always applied to the managed API/data-plane
domains. The host infers the OpenAI account id from Codex login status instead
of accepting it in config. OpenAI data-plane requests are denied until that
inferred account id is available; auth.openai.com stays available for login.
When managed_ai_provider_network_access.claude is true, Claude Code tasks
can run after Claude OAuth login. The host automatically adds these managed
domain rules:
{
"api.anthropic.com": {
"allow_http_methods": ["GET", "POST"],
"anthropic_account_guard": true
},
"platform.claude.com": {
"allow_http_methods": ["GET", "POST"],
"path_guards": ["^/v1/oauth(?:/.*)?$"]
}
}Do not list anthropic.com, claude.ai, claude.com, or their subdomains in
allowed_network_access; the parser rejects those rules because they are
provider-owned by Claude Code. The managed bundle currently opens only
platform.claude.com OAuth paths plus api.anthropic.com; claude.ai is not
opened unless a future Claude Code denial proves it is required. The host
verifies claude auth status, infers the Claude account metadata from the agent
user's Claude config, stores only account metadata plus a SHA-256 hash of the
OAuth access token, and denies api.anthropic.com data-plane requests until the
presented bearer token matches that stored hash. The unauthenticated
/api/hello readiness probe remains available for Claude Code startup.
Each value in allowed_network_access is a domain rule.
Domain keys must be exact DNS names such as api.example.com or wildcard DNS
names such as *.example.com. A wildcard must be the first character and must
be followed by ., then a concrete DNS suffix. It matches any non-empty prefix
before that suffix, including dots, so *.example.com matches
api.example.com and a.b.example.com, but not example.com. If both the apex
domain and its subdomains are needed, configure both example.com and
*.example.com.
Domain keys are normalized to lowercase. Wildcard domain rules must not
overlap: for example, *.example.com and *.api.example.com cannot both be
configured, because x.api.example.com would match both. Exact domain rules may
coexist with wildcards and override them for that exact hostname.
Prefer exact domains over wildcards. A wildcard lets the agent have the host
resolve any subdomain it chooses (for example <data>.example.com), which leaks
that label to the domain's DNS as a low-bandwidth side channel. Only use a
wildcard for a domain whose nameservers you trust not to be an exfiltration
sink.
{
"allow_http_methods": ["GET", "HEAD"],
"path_guards": ["^/dist(?:/.*)?$"]
}| Field | Required | Type | Behavior |
|---|---|---|---|
allow_http_methods |
Yes | enum array | HTTP methods allowed for proxied requests to this domain. Valid values are GET, HEAD, POST, PUT, PATCH, and DELETE. An empty array keeps HTTP/HTTPS closed for this domain. |
path_guards |
No | string array | Python re regular expressions for allowed request targets, evaluated with re.fullmatch against the path plus query string when present. If omitted, paths are not restricted beyond the domain and method rule. |
WebSockets use the same domain rule. A WebSocket connection starts with an HTTP
GET request that includes an upgrade header, so GET must be present in
allow_http_methods and the handshake path must pass path_guards when path
guards are configured. For wss:// URLs, proxy CONNECT handling is internal
to the host and is not listed in allow_http_methods. After the upgrade
succeeds, WebSocket frames continue on the approved connection; they are not
separate HTTP requests. On managed OpenAI domains with the live web search
guard, each client-to-upstream WebSocket message is additionally inspected with
the same live web search guard as HTTP request bodies; a violating message
closes the connection.
Path guards use Python re syntax and must match the full request target path.
For example, ^/dist(?:/.*)?$ allows /dist and /dist/index.js. If query
strings are allowed, include them in the regex, such as
^/simple(?:/.*)?(?:\\?.*)?$.
For Codex, the host also restricts the agent runtime to cached web search, so the OpenAI proxy guard is the second layer rather than the only one.