Self-Hosted Claude Code Environments: Runners in Your Network
Claude Code cloud sessions normally run on Anthropic-managed VMs. A self-hosted environment keeps the same developer experience (start a session from claude.ai, the desktop or mobile app, claude --cloud, or a routine) but runs the session on runners, processes you operate inside your own network, much like self-hosted CI runners. Sessions can then reach internal services, databases, and registries, use your pre-built toolchain, and keep checkouts and build artifacts on your machines.
It is in public beta on Team and Enterprise plans and off by default. This guide follows Anthropic's self-hosted documentation: how environments, runners, and sessions fit together, what stays on your infrastructure and what does not, a first runner, the runner lifecycle that production deployments must design around, and the limitations. It is not a way to run Claude Code fully on-premises: the control plane, the conversation, and by default model inference stay with Anthropic. For local sessions on developer machines, nothing here applies. See also Claude Code Cloud Sessions.
Environments, runners, and sessions
Three parts:
- Environment: a named destination created on the Cloud environments admin page in claude.ai. It groups a set of runners and appears in the environment picker next to Anthropic-hosted environments.
- Runner: the long-lived process you deploy on Linux or macOS hosts or containers. It is part of the standard
claudebinary (claude self-hosted-runner, v2.1.224 or later). It authenticates with the environment's secret, registers, and polls for work. - Session: one Claude Code task. When a developer picks your environment, Anthropic's control plane queues the session; a runner with free capacity claims it, clones the repository, and starts a child Claude Code process that streams events back over HTTPS.
Every connection is outbound from your network: queue polling, the event stream, and model inference go to api.anthropic.com, and the runner reaches your git host with credentials you configure. Anthropic never connects in. Corporate egress proxies are supported through the usual HTTPS_PROXY and NO_PROXY variables, but because session streaming uses server-sent events, a proxy in the path must not buffer responses.
You can keep runners running yourself, or deploy Anthropic's autoscaling orchestrator, which starts runners as sessions queue.
Quick reference
- Sessions check out repositories from GitHub, including GitHub Enterprise Server for Team and Enterprise; each developer needs their own GitHub connection.
- Self-hosted sessions consume the organisation's Claude Code usage the same way Anthropic-hosted sessions do.
- In API fields and metrics the environment appears as
pool, with apool_id.
Remember this
You run the execution; Anthropic runs the queue and the conversation, and every connection starts from your side.
What stays on your infrastructure, and what does not
This is the part to get exactly right in a compliance review. Per the docs:
- Stays on your machines: repository checkouts, build artifacts, secrets, and any files a session creates or modifies.
- Goes to Anthropic: the conversation itself (prompts, responses, and tool results) goes to
api.anthropic.com, and Anthropic stores the session transcript so the session can be resumed from other surfaces. Session orchestration, queueing, and the claude.ai interface remain Anthropic-hosted.
Model inference uses the Anthropic API by default. You can configure a runner to send model requests to Amazon Bedrock or Google Cloud's Agent Platform instead, but session content still goes to Anthropic in the session's event stream either way, and on such a runner server-managed settings and organisation policies from claude.ai do not reach sessions.
So self-hosting is about execution locality (network reach, tooling, where code and artifacts live), not about keeping prompts or tool output off Anthropic's systems. Organisations with Zero Data Retention or the HIPAA configuration cannot use self-hosted environments at all.
Quick reference
- Tool results include file contents Claude reads and command output, so code Claude opens is part of what is sent, even though the checkout stays local.
- If the requirement is that no code ever leaves your network, self-hosted environments do not meet it; that needs a different deployment model.
- Secrets on the runner are reachable by session commands; scope runner credentials as tightly as CI credentials.
Remember this
Checkouts and artifacts stay local; the conversation, including tool output, still goes to Anthropic.
Stand up a first runner
Prerequisites: an Owner turns on Allow self-hosted environments on the Cloud environments admin page (which requires cloud sessions to be enabled), the GitHub connector is on, the host has outbound HTTPS to api.anthropic.com and your git host, Git 2.24 or newer, and a clock synchronised with NTP (authentication fails if it is more than five minutes off). Windows is not supported as a runner host.
Check the binary first:
1claude self-hosted-runner --helpThen either run the guided setup, claude self-hosted-runner setup, as an Owner, or do it manually:
1. On the Cloud environments page, select New, name the environment, and copy the environment key. It is shown once and expires 365 days after creation. 2. Save it to a file readable only by the runner's user, without putting it in shell history:
1mkdir -p /etc/claude2(umask 077 && cat > /etc/claude/environment-secret)3. Start the runner with a dedicated working directory:
1claude self-hosted-runner \2 --environment-secret-file /etc/claude/environment-secret \3 --base-dir /srv/claude-runnerThe runner logs Registered: runner_id=... and the environment's status changes to Healthy. Start a session at claude.ai/code, pick your environment and a repository the host can clone over HTTPS, and the runner logs Picked up session ....
Quick reference
- Use a base directory dedicated to the runner. It treats whatever it finds at
<base-dir>/<owner>/<repo>as its own clone and may reset or overwrite it. - A clone that fails with
could not read Username formeans the runner had no HTTPS credentials for the git host; configure git credentials or rewrite URLs to SSH. - Rotate the secret from the environment's Configuration tab: create a new one, roll it out, then revoke the old; runners with a revoked secret log
poll auth failedand exit.
Remember this
One command and a secret file register a runner; give it a dedicated directory and HTTPS git credentials.
The runner lifecycle production must design around
Three behaviours shape how you deploy runners.
One owner at a time. The first session a runner picks up locks it to that session's owner (the user, or the Claude Tag agent for channel sessions). It then runs sessions only for that owner, up to --capacity. This keeps checked-out code from mixing between people. It also means your minimum fleet size is the number of owners active at once.
Leases by polling. A runner holds a lease on each session, refreshed by every poll, which doubles as its heartbeat. If polling stops, the lease lapses after about 60 seconds and the session can be requeued to another runner, which can take several minutes.
Exit by design. At the default --drain-grace-sec 0, a runner exits as soon as its sessions finish, so an orchestrator such as Kubernetes can restart it with a fresh disk, ready for any owner. Run runners under something that restarts them and backs off when a runner exits immediately after start. If your infrastructure kills hosts at a known time without a usable SIGTERM, such as spot reclamation or sandbox lifetime caps, pass --retire-at <epoch-seconds> a few minutes earlier: the runner stops taking work, releases sessions so they resume on a fresh runner at the user's next message, and exits cleanly.
Quick reference
- Without
--retire-at, a signal-less host kill looks like a crash: the control plane records a lost worker and the session requeues. - A turn that outlives the kill is lost; size the retire margin to your longest normal turn.
- The autoscaling orchestrator starts runners as sessions queue, which fits the one-owner model better than a fixed pool.
Remember this
Size the fleet by concurrent owners, run runners under a restarting orchestrator, and use --retire-at when hosts die on a schedule.
Availability and limitations
The docs are clear that most teams are better served by Anthropic-hosted environments, which need no infrastructure. Self-hosting makes sense when your network, tooling, or compliance requirements call for execution on infrastructure you control, and you accept the operational ownership: building and maintaining the runner image, operating the fleet, and controlling its network.
Before production, Anthropic's deploy guide covers security hardening, egress control, git credential options (including per-session minted credentials and an Anthropic git proxy for github.com), and Kubernetes and Compose recipes. Treat the runner like CI infrastructure: it executes code chosen by whoever starts a session.
| Area | Status |
|---|---|
| Plans | Team and Enterprise, off by default; an Owner enables it |
| ZDR or HIPAA organisations | Not available |
| Surfaces | claude.ai/code, desktop and mobile apps, routines, claude --cloud; Claude Tag with limits |
| Code Review and Claude Security sessions | Do not route to self-hosted environments yet |
| Repositories | GitHub, including GitHub Enterprise Server |
| Model inference | Anthropic API by default; Bedrock or Google Cloud optional, content still sent to Anthropic |
| Runner hosts | Linux or macOS; not Windows (use a Linux container) |
Quick reference
- The beta label means flags and behaviour change between releases; pin the runner version your fleet uses.
- Sessions running inside your network can reach whatever the runner can reach; segment runners as you would CI runners.
- A CI smoke test that dispatches a session with
--environmentand reads the reply is documented for validating new runner images.
Remember this
Choose self-hosting only for network, tooling, or compliance needs, and budget for running it like CI.
Hands-on: one runner, one session
In a test Team or Enterprise organisation where you are an Owner:
1. Enable Allow self-hosted environments, create an environment, and save its key to a file with umask 077.
2. On a Linux VM, install Claude Code, check claude self-hosted-runner --help, and start the runner with a dedicated --base-dir.
3. Confirm Registered: runner_id=... and the Healthy status.
4. Start a session at claude.ai/code on a public repository, picking your environment, and watch for Picked up session ....
5. From another machine, send a follow-up: claude -p "list the files you changed" --cloud <session-id>.
6. Archive the session and observe the runner exit with account workload drained.
Pass criterion: the session ran on your VM, you can show from the VM which repository was checked out, and you can explain which parts of that session were still sent to Anthropic.
Quick reference
- If the session sits queued, check the runner's log for registration and the host clock.
- If the clone fails, the runner needs HTTPS credentials for your git host.
- Delete the test environment and revoke its key afterwards.
Remember this
One runner on one VM, one session, and a clear statement of what left your network.
Key takeaway
Self-hosted environments run Claude Code cloud sessions on runners inside your network: developers pick the environment as usual, Anthropic's control plane queues the session, and a runner you operate polls for it, clones the repository, and runs a child Claude Code process, with every connection outbound. Checkouts, build artifacts, and secrets stay on your hosts; the conversation, including tool results, and the stored transcript still go to Anthropic, even if inference is routed to Bedrock or Google Cloud.
It is a public beta for Team and Enterprise, unavailable with ZDR or HIPAA, and it comes with CI-style operational work: one owner per runner, leases kept alive by polling, runners that exit by design under a restarting orchestrator, and --retire-at for scheduled host kills. For the alternative of steering a session on your own machine, see Claude Code on Mobile; for the security review around it, see Claude Code Security and Compliance.
Practice (45 min): complete the six steps above on a test VM.
References
- Claude Code docs: Self-hosted environments — checked Oct 17, 2026
- Claude Code docs: Self-hosted environments quickstart — checked Oct 17, 2026
- Claude Code docs: Deploy self-hosted environments to production — checked Oct 17, 2026
Shoaib Hossain
Lead Author & Systems ArchitectSoftware engineer and distributed systems architect specializing in backend scalability, cloud-native infrastructure, databases, and AI engineering workflows. Author and maintainer of Core Concept Learning.
Related Articles
Explore this topic