Disco ParrotDisco Parrot Home
Docs
Request a Demo

Network boundary and customer-hosted compute

The governance view of running agent compute inside your own boundary. Pods in your cluster or containers on your engine, under your own controls; an operator that only ever dials out, so nothing reaches in; code and secrets that stay on your side; a short outbound list you can allowlist; and your own compute, which the platform does not meter.

Some teams can run agent work anywhere. Others have a hard line: the work has to happen on infrastructure the organization governs, inside its own network, under its own controls. This page is for the second kind. It is the governance view of customer-hosted compute, what you expose to run it, what crosses the boundary and what never does, and what you can put in front of a reviewer to show that "we run agents inside our boundary" is a set of facts rather than a hope.

The mechanics, the channel itself, the tokens that secure it, and how it recovers, live in network and connectivity. This page is the lens above that one: the boundary as a control you can attest, not a wire you have to trace.

Run the compute where you govern it

When you run a bring-your-own host, agent sandboxes execute as pods in a Kubernetes cluster you own or containers on a Docker engine you control, not on outside compute. That single placement decision pulls agent work under the controls you already trust: your node pools and your network policy, your admission controllers, your monitoring, your audit. The image, the runtime, and the change policy are the platform's; the place the work happens, and everything your infrastructure already enforces there, is yours.

Your boundaryKubernetes clustersandbox podsnon-root, capabilities droppedDocker enginesandbox containersyour disk, your engineyour node pools, network policy, admission control, monitoring, auditPlatformimage, runtime,change policyorchestration onlyno Service, no Ingress, no port, no VPN
A bring-your-own host runs the work inside your boundary, as pods in your cluster or containers on your engine, under the controls you already enforce there. The platform supplies the image, the runtime, and the change policy and reaches your host one way only, outbound, for orchestration. Nothing reaches in.

Nothing about how a sandbox is built changes when it runs inside your boundary. What changes is jurisdiction: the run that would have happened on managed compute now happens somewhere you can inspect, govern, and answer for.

Nothing reaches in

The first question a security team asks about any outside system is what it had to open. The answer here is nothing inbound. The operator you install does not listen for connections; it dials out to a managed messaging channel and holds that one connection open. The platform sends work over the channel the operator opened, and the operator answers on the same channel. There is no service to expose, no ingress to route, no port to forward, and no VPN or network peering to stand up.

This is a fact you can confirm rather than a posture you accept. The operator bundle you applied contains no Service, no Ingress, and no listening port, on Kubernetes or on Docker, so there is nothing to scan and nothing to firewall on the way in. A bring-your-own host behaves like every other outbound client your network already allows, the way a build runner or a backup agent does, and the only direction that ever carries traffic is out.

Your code and your secrets stay on your side

The channel carries small control messages, not your work. Two kinds of thing travel it: lifecycle commands (launch this sandbox, tear that one down, report health) and agent events (the stream of a run's progress so you can watch it live). Both are compact messages with a correlation id, not a pipe your source flows through.

What does not cross is the part that matters most for a review. A checkout, a build, a file an agent reads or writes, all of it stays on the compute inside your boundary and is never shipped to the platform and back. And a credential an agent needs for a real action is leased at the moment of use and handed straight to the process that uses it, never serialized into a message on the wire. The platform tells your host what to do and watches it happen; the work, and the sensitive material the work touches, stay with you.

What stays on your side also leaves on your terms. A sandbox's working directory is scratch space that lives and dies with the run on a managed or Kubernetes host, and persists only where you deliberately turn that on, on a Local Docker host whose disk is yours to begin with. What a run leaves behind, and when a container and its workspace are gone, is covered in sandboxed execution isolation.

A small, legible blast radius

Running something inside your boundary is only reassuring if you can see how far it reaches, so the footprint is deliberately small. On a Kubernetes host the operator is one deployment in one namespace, with RBAC that reaches no further: it may create, read, watch, and delete pods and get and create service accounts in that namespace, and nothing else. No secrets, no nodes, nothing cluster-wide. The operator deployment is itself resource-bounded, so the thing you install to launch sandboxes cannot crowd out your own workloads.

The sandbox pods it launches are hardened the way your own workloads should be: they run as a non-root user, drop every Linux capability, cannot escalate privileges, run under the default seccomp profile, and are held to set CPU and memory limits, and they carry a service account with no access to the Kubernetes API at all. So a sandbox does its work without being able to reach into your cluster, and a compromised one cannot escalate, reach a restricted syscall, or eat the node. The token each sandbox holds on the messaging channel is publish-only, too: a sandbox can speak for itself but cannot subscribe to another sandbox's traffic, so two runs on the same host cannot listen in on each other.

Blast radius: one namespaceThe operatorcreate, read, watch, delete: podsyesget, create: service accountsyessecrets, nodes, anything cluster-widenoEach sandbox podruns as a non-root useryesevery Linux capability droppedyesno privilege escalationyesseccomp set to RuntimeDefaultyesany access to the Kubernetes APIno
The blast radius made into a checklist. The operator reaches one namespace and only pods and service accounts, never secrets or nodes or anything cluster-wide. Each sandbox pod runs hardened and holds no Kubernetes API access. A reviewer reads this off the manifest and the cluster, not off a promise.

The connection itself runs on short-lived tokens rather than standing secrets. The operator trades a single-use install key, kept only as a hash and checked in constant time, for a connection token that lasts about an hour and renews itself; each sandbox's channel token is short and refreshed before it lapses; and the credentials an agent uses for real work are leased per operation and measured in minutes. Re-downloading the operator bundle mints a fresh key and retires the prior one, so there is no standing key that lingers across downloads. Nothing in the chain is a long-lived secret sitting on your host.

The outbound you allow

Because everything runs outward, you can allowlist exactly what a host needs. From inside your boundary the operator reaches a short, known list of destinations:

  • the platform endpoint where it exchanges its install key for a connection token,
  • the managed messaging channel it holds its connection open over,
  • the container registry it pulls the sandbox image from.

That is the operator's whole outbound story, and it is the same shape of rule you already write for a build agent. That short list is the operator's outbound, not a fence around the agent. What an agent reaches for its own work, your Git provider, a package registry, the cloud resource an identity grants it, is governed by what you connected it to, the credential it is leased for each action, and the container boundary it runs inside, every grant scoped and recorded. There is no inbound rule to write on any host kind, which is the rule that decides whether you can run this behind a firewall.

Your compute, and your cost

Customer-hosted compute is also a cost boundary. Agent runs on a bring-your-own host execute on your cluster or engine, on hardware you already pay for, and the platform does not meter that compute. Metered compute is the managed pool; the runs you place on your own Kubernetes or Docker host are yours to size and yours to account for. The platform's only window into a run on your host is the orchestration and health channel already described, so there is no separate metering agent reading your compute. Bringing the work inside your boundary keeps both the governance and the bill on your side of the line.

A dropped connection is a pause, not a loss

The piece that decides whether you can run this seriously is what happens to work already in flight when the connection blips, and the answer is that it keeps running. The sandboxes are on your compute, a pod in your cluster, a container on your engine, so a dropped operator connection does not kill them. The host shows the connection as dropped, and when the operator returns it reconciles with the sandboxes that were running, re-points each one at a fresh token, and carries on. A brief outage costs a brief wait, not the work in flight. The full recovery behavior is in network and connectivity.

What a reviewer can verify

The boundary is built so its guarantees are facts you can produce, not claims you have to defend:

  • No inbound exposure. The operator manifest has no Service and no Ingress; on a Kubernetes host, kubectl get svc,ingress in its namespace returns nothing, and on a Docker host the operator's Compose project publishes no ports.
  • Code and secrets stay home. The work runs in your compute and only control messages cross the channel; a credential for an action is leased to the process that uses it, never put on the wire.
  • A bounded operator. Its RBAC reaches one namespace and only pods and service accounts; the sandbox pods are non-root, drop all capabilities, and hold no Kubernetes API access.
  • A short outbound list. Three operator destinations you can allowlist, and no inbound rule anywhere.
  • Everything on the record. Issuing a host bundle and every credential an agent is leased move through the audit trail: the host.operator_bundle event carries a short fingerprint of the key rather than the key, and each credential lease is recorded as it is granted, consumed, denied, and expired, with its scope and expiry and the secret itself redacted in every row.

Keeping the work inside the network

The Insights team has a requirement that predates any agent: work that touches the production data set must not leave the company's network. When Marcus proposes letting agents help with that work, the security owner's first question is the obvious one, does this put our data on someone else's compute, and the boundary model answers it directly. The agent runs as a pod in the team's own cluster; the source and the data stay on that compute; only orchestration messages cross the channel, outbound, over a connection the cluster opened. There is no inbound door to the cluster, no peering to the platform, and no copy of the work shipped out to be processed and returned.

That turns a hard governance line into a configuration choice. The profiles that have to stay inside the network point at the cluster host; everything else can run managed; and the security owner can show, from the manifest and the audit trail, that the data-residency rule holds by construction rather than by policy. The decision becomes whether the team wants the capability, not whether it is allowed to.

Why the boundary works this way

The simple way to connect a customer's compute to a platform is to have the platform reach in: open a port, hold a tunnel, peer the networks. It is the obvious thing to reach for, and it is exactly what a security team cannot allow, because every inbound door is a door someone else might walk through. So the model inverts it. Your host reaches out, the way everything else in your network that talks to the outside world already does, and the platform never holds a connection into your boundary.

The rest follows from that one inversion. The channel carries orchestration rather than your code or your secrets, because the work belongs on your compute and the sensitive material belongs with the process that uses it. The footprint is small and namespace-scoped because a thing you run inside your boundary should be a thing you can fully read. The compute is yours, and so is its cost, because the whole point was to keep the work on infrastructure you govern. And all of it is auditable because, for the people who answer for the boundary, safe has to be provable. The aim is to make "we run agents inside our own network" a decision you can defend line by line, not a leap of faith.

For the person who owns security, this is the page you bring to the boundary review. No inbound exposure, code and secrets that never cross the wire, a namespace-scoped operator, a three-destination outbound list, and an audit trail for all of it. Every claim is one you can verify from your own cluster and the record.

For a platform engineer, the operator is a well-behaved outbound client: it connects out, reconnects on its own, survives a node blip without taking running work with it, and reaches a short, allowlistable set of destinations. It runs like the other agents already on your network.

For a lead, the boundary is what lets you say yes to agents on a regulated workload without a months-long argument. The hard questions, where does the data go, what did we expose, what can it reach, have concrete answers, so the decision is about whether you want the capability.

For a prospect evaluating the platform, customer-hosted compute is the answer to "can this run where our rules require." The work runs inside your network, on your compute, under your controls, with nothing reaching in and a record of everything that reaches out.