Self-hosted environments are in public beta on Team and Enterprise plans; Availability and limitations covers the enablement path. This page covers running the fleet in production; see the quickstart for your first runner and session.
Harden your deployment
A self-hosted runner executes arbitrary, model-directed code on your infrastructure on behalf of any member of your Anthropic organization. Work through each item before you connect an environment to production systems:-
Ephemeral, per-session containers: run each runner process in a fresh container or VM that’s destroyed when the process exits, with
--capacity 1and the default--drain-grace-sec 0so each container serves exactly one session. At a higher capacity, or with a positive drain grace, one container serves multiple sessions from the same locked account; see Runner lifecycle. Don’t reuse a filesystem between runner restarts, except in the deliberate pre-warmed checkout setup, and never across accounts. -
No broad credentials in the image: don’t include long-lived SSH keys, cloud-provider credentials, or personal access tokens that grant more than a session needs. Mint credentials used during a session, such as push or API tokens, per session from your wrapper script. For the initial clone, which happens before the wrapper runs, use a
checkoutlifecycle hook or--use-anthropic-git-proxy; see Configure git. - Keep the environment secret off session-running hosts: the environment secret can register runners and pick up any org member’s queued sessions. On a fixed fleet it lives on every runner host, where any session’s code can read the secret file. Prefer on-demand runners, where the secret stays on the orchestrator host, which never runs user code, and each runner receives a single-use work order that registers exactly one runner. On a fixed fleet, treat the environment-secret file as readable by every session and rotate the secret after any suspected session compromise.
- Default-deny network egress: restrict runner and session container outbound traffic at your own network boundary on every environment; Default-deny egress covers what to allow and why.
- Least-privilege host IAM: the compute identity attached to the runner host, such as an instance profile or node service account, should grant only what the runner itself needs. Sessions should obtain their own credentials through your wrapper script rather than inheriting the host’s.
-
Block the cloud metadata endpoint from sessions: keeping sessions off the host identity requires blocking their access to the cloud metadata endpoint, and subnet-level egress policies don’t intercept link-local metadata traffic, so block it in the container itself:
- IMDSv2 with a hop limit of one
- GKE Workload Identity with metadata concealment
- An explicit deny for
169.254.169.254in the session container’s network namespace
-
Per-runner filesystem isolation: each runner process gets its own working directory that no other process on the host can read or write. Make
--hooks-dir, the wrapper script, and the host’s~/.claude/read-only to the session, either built into the image or mounted read-only. -
Dispatch is organization-wide: any member of your Anthropic organization can dispatch a session to any of its environments, and there’s no per-environment access control on dispatch. Treat every runner host as reachable for code execution by every org member, and place data or credentials on a runner host only if every org member is allowed to read them.
--lock-to-accountbounds which account’s sessions a given host executes, but dispatch into the environment itself stays organization-wide. To make self-hosted environments the only picker option, an Owner or admin can hide Anthropic-hosted environments for the whole organization from the Cloud environments page. -
Enforce the repo-settings guard: choose the guard mode with
--confine-repo-settings. The defaultwarnlogs a violation and still spawns the session,enforcerefuses the session, andoffdisables the scan. The runner scans each repository’s committed settings for:- A grant that resolves outside that session’s own workspace: an
additionalDirectoriesentry, anEdit,Write, orNotebookEditrule inpermissions.allow, or asandbox.filesystem.allowWriteorallowReadentry - A non-empty
envblock - An operator-posture override such as
sandbox.enabled: false
--trust-workspace, and doesn’t cover repository hooks,.mcp.json, or Bash rules; see Permissions and tool approval for where those grants belong. - A grant that resolves outside that session’s own workspace: an
Your organization’s IP allowlist doesn’t cover self-hosted runner traffic by default. Don’t rely on it as a network control for runner or session traffic; apply default-deny egress at your own network boundary instead, and contact your Anthropic account team if you want IP-allowlist enforcement for your organization.
Network requirements
The runner and the session children it spawns make outbound connections to the hosts below. Restrict session-container egress to these hosts and the specific internal services sessions need to reach; Default-deny egress covers how and why. These hosts are always required:
Whether these hosts are needed depends on your configuration:
The runner doesn’t reach
statsig.anthropic.com, *.sentry.io, claude.ai, or platform.claude.com. These hosts appear in some older enterprise network checklists, but you don’t need to allowlist them for runner or session traffic: feature-flag fetches go to api.anthropic.com, and the runner authenticates with the environment secret rather than interactive OAuth. Two host-side flows do reach claude.ai, so run them from a host whose egress allows it rather than widening session-container egress: the one-line installer fetches install.sh from claude.ai at install time, and interactive claude auth login, which the guided setup, doctor’s signed-in mode, and CI dispatch use, signs in through claude.ai, claude.com, and platform.claude.com. mcp-proxy.anthropic.com isn’t required either: self-hosted sessions don’t use it, and delivery of your organization’s claude.ai connectors to sessions, when enabled for your organization, routes through api.anthropic.com. See MCP servers.
Default-deny egress
Deploy runner and session containers in a network segment or namespace whose outbound traffic is limited to the hosts in the network requirements table, your git host, and the specific internal services sessions need to reach. The product can’t verify or enforce this, so apply it at your own network boundary on every environment. Session code is model-directed and can attempt connections to arbitrary hosts; default-deny egress at the network layer bounds where those attempts can land. This applies regardless of permission mode: the default pre-approved tool set already includesBash, so shell egress runs without a prompt even without auto mode.
For details on which telemetry each session emits and how to turn it off, see Telemetry.
Configure git
The runner manages repository checkouts but doesn’t configure git identity or credentials by default. You control the runner’s image and process environment, so you control the git config. Choose one of two approaches:- Let the runner configure git: start the runner with
--configure-gitto have it write the same identity and commit-signing config that Anthropic-hosted sessions use - Ship git config in your image: set identity and push credentials yourself, for example to commit under your own bot identity
--configure-git SSH commit signing requires Git 2.34 or newer, --use-anthropic-git-proxy requires 2.32 or newer, and resuming sessions from branches pushed by --push-outcome-on-release requires 2.29 or newer. Git 2.24 is sufficient if you omit all three and manage git identity yourself.
Let the runner configure git
Start the runner with--configure-git, or set SELF_HOSTED_RUNNER_CONFIGURE_GIT=1, to have it write global git config at startup:
user.name = Claudeanduser.email = noreply@anthropic.com, matching Anthropic-hosted sessions- SSH-format commit and tag signing, routed through a runner-managed shim that signs each commit via Anthropic’s signing service using the session’s own credentials. Signatures are verifiable on GitHub against Anthropic’s published SSH signing key.