Skip to navigation

Architecture

View as Markdown

OpenShell system architecture showing a trusted supervisor separated from a network-isolated sandbox workload. The workload can connect only to the supervisor.

OpenShell governs what agents can do in two ways: it instruments the kernel to enforce policy on every file access, system call, and network connection at runtime, and it uses formal verification to check what a policy change would allow before it is applied.

  • Kernel-level enforcement. Each agent runs in an isolated sandbox. Kernel controls confine which files it can access and which system calls it can make, and every network connection passes through a policy check before it leaves the sandbox. OpenShell supplies credential placeholders to agents and adds real credentials only to requests bound for approved endpoints.
  • Formally verified policy changes. Before a policy change is approved, OpenShell uses formal verification to flag risky new access it would grant, such as reaching a new host with credentials or calling a new API method, so those changes wait for human review.

The gateway is the control plane: it manages the lifecycle of sandboxes and provides connectivity and management of sandboxes to end users and operators. When you create a sandbox, its compute driver provisions a workload and a separate supervisor, establishes their protected channel, and builds the isolation boundary; the supervisor confirms that boundary before starting the agent and then connects back to the gateway for policy, credentials, logs, and interactive sessions.

What Each Piece Does

ComponentWhat it does
SandboxLives inside the boundary with the agent. It owns the agent’s processes, knows which program made each request, applies process controls, and forwards TCP and DNS traffic to the supervisor.
Outer network fenceDenies all network egress from the workload except its protected connection to the supervisor. Each runtime builds this with its own native tools.
SupervisorLives on the trusted side of the boundary. It checks requests against policy, supplies credentials, resolves DNS, opens approved connections, and keeps the link to the gateway alive. It works with every runtime through one isolation backend interface to confirm the boundary, start the agent, run commands, forward connections, and see network requests.
PoliciesDescribe what the agent can touch: files, processes, network destinations, API calls, and where provider credentials can go.
ProvidersConnect a service name to a stored credential. The supervisor hands that credential out only where policy allows it.
Policy proverRuns in the gateway and uses formal verification to check agent-proposed network rules. It flags changes such as new credentialed reach, new HTTP methods, or access to cloud metadata endpoints; any finding blocks auto-approval. It also ships as the standalone openshell-prover command for checking a policy against a boundary in CI.
GatewayChecks who you are and remembers everything about your sandboxes. It delivers policy and settings, attaches providers, decides who can do what, and coordinates connections into sandboxes.
Compute runtimeCreates the sandbox, starts the supervisor and the workload, sets up the private channel between them, and builds the network fence. It reports status back and cleans up when the sandbox goes away.

Inside the Sandbox Boundary

The supervisor and sandbox sit on opposite sides of the boundary. The supervisor is trusted and makes the decisions. The sandbox shares the boundary with the untrusted agent, so it never makes policy decisions. It reports what the agent is trying to do and lets the supervisor decide.

The sandbox launches the agent as an owned child and provides exec, terminal streams, signals, process status, and loopback forwarding. In the current Linux backend, the workload uses one non-root identity and no Linux capabilities. Landlock limits filesystem access; seccomp user notification stages network operations. The sandbox identifies the calling executable from trusted process observations.

OpenShell sandbox enforcement flow showing the network-isolated sandbox and trusted supervisor as separate boundaries. The supervisor channel is the workload's only allowed egress path.

Mediated Channel

The supervisor and sandbox talk over the OpenShell Sandbox Protocol: one HTTP/2 connection authenticated with TLS and a sandbox JWT that carries many independent streams. The compute driver picks the transport: a Unix socket for Docker and Podman, TCP for Kubernetes, or vsock for MicroVM. Authentication and protocol behavior are the same on all of them. The supervisor presents a sandbox-specific credential, as described in How Components Authenticate.

OpenShell Sandbox Protocol showing the trusted supervisor and the network-isolated sandbox connected by one authenticated connection with separate control, DNS, and per-connection TCP streams. The agent reaches the supervisor only through the sandbox.

Each TCP connection gets its own stream with its own backpressure, so a slow download can’t block DNS, exec, or process control.

GuaranteeHow the sandbox provides itWhat the supervisor gets
Process ownershipRuns the agent as an owned child and keeps its process and terminal state.Handles to wait on, attach to, signal, exec in, and stop the agent.
Program identityIdentifies the calling program from trusted /proc data.The real program behind each request, not a path the agent claims.
Network mediationIntercepts TCP opens and DNS queries with seccomp and hands them over.Requests that wait for a policy decision before going anywhere.
Fail closedHolds launch until the supervisor confirms, and freezes the agent if the connection drops.A short window to reconnect, or a stopped workload.

Together these mean the agent can’t run before its controls are confirmed, signals and exec reach only this sandbox’s processes, and the agent can’t get around TCP or DNS mediation.

How a network request travels

  1. The agent opens a TCP connection or makes a DNS lookup.
  2. The sandbox identifies the calling program.
  3. The request travels over the Sandbox Protocol to the supervisor.
  4. The supervisor checks it against policy and adds any credentials policy allows.
  5. If allowed, the supervisor opens the real connection and relays traffic.

The mediated channel to the supervisor is the workload’s only allowed egress path. The outer fence denies everything else, so the agent can’t reach a service, the gateway, DNS, or another private address directly.

Agent traces

When an operator enables the agent trace relay, the sandbox points the agent’s OpenTelemetry SDK at the reserved address 192.0.0.8:4318. Connections to it take the same mediated channel, but the supervisor answers them itself instead of opening an upstream connection. It tags each trace batch with the sandbox ID and forwards it to the operator’s collector. The agent never learns the collector’s address and needs no egress rule to reach it.

How Each Runtime Builds the Boundary

Every runtime follows the same contract, but each one uses the tools it already has to place the supervisor, connect it to the sandbox, and fence off the network.

RuntimeWhere the supervisor runsHow it talks to the sandboxHow direct egress is blocked
DockerIts own containerAuthenticated Unix socket on a driver-owned volumeWorkload container has networking turned off
PodmanIts own containerAuthenticated Unix socket on a driver-owned volumeWorkload container has networking turned off
KubernetesIts own podPrivate service with server-authenticated TLS and a sandbox JWTNetworkPolicy allows only the supervisor service
VMA process on the hostAuthenticated vsockGuest has no network device

The runtime’s job is to build the boundary and prove it’s in place. It never decides whether a request is allowed. That decision always belongs to the shared supervisor and policy engine, which is why the same policy behaves the same way everywhere.

Runtimes can differ in how they report readiness and which features they support. Each one advertises its capabilities so the gateway knows what it can do.

How Components Authenticate

Three connections tie a sandbox session together. The gateway signs the session’s gateway and sandbox JWTs, each bound to that sandbox and generation.

OpenShell sandbox authentication showing the gateway preissuing session JWTs, delivery to dedicated supervisors through the compute driver or to shared supervisors through a host-JWT-authenticated assignment stream, and the supervisor presenting the sandbox JWT over server-authenticated TLS to the sandbox.

ConnectionWho connectsHow it’s protected
Supervisor to gatewayThe supervisor dials out to the gateway.A gateway JWT, over TLS when the gateway has TLS enabled.
Supervisor to sandboxThe supervisor acts as the TLS and gRPC client over the driver’s private channel. The runtime can initiate the underlying transport connection.TLS authenticates the sandbox server; the sandbox JWT authenticates the supervisor. No TLS client certificate is used.
Agent to supervisorThe agent never connects directly. The sandbox relays its traffic over the connection above.Covered by the supervisor-to-sandbox channel.

The supervisor verifies the gateway’s TLS certificate with its CA. User client certificates and private keys stay outside both the supervisor and workload; the gateway JWT authenticates supervisor RPCs.

Getting the first credential

The gateway prepares session credentials for each sandbox generation and delivers them through trusted launch provisioning:

  • Docker, Podman, and MicroVM. The driver supplies the dedicated supervisor with private credential files.
  • Kubernetes, dedicated supervisor. The driver mounts the preissued credential bundle from a Secret into the supervisor pod.
  • Kubernetes, shared supervisor. Each sandbox’s credential bundle arrives in its assignment over the authenticated supervisor-host stream.

A separate IssueSandboxToken exchange accepts a compute-driver bootstrap identity. On Kubernetes, the driver validates a projected ServiceAccount token and its pod and owner identity. The gateway compares the driver and runtime identity with its stored sandbox record before returning a gateway JWT. This exchange is not required for supervisors provisioned with a credential bundle.

Gateway and Sandbox JWTs

The gateway issues a pair of JWTs for each run of a sandbox:

  • Gateway JWT. Authenticates the supervisor’s sandbox-specific calls to the gateway. It allows only the calls a supervisor needs, such as fetching policy, pushing logs, and relaying sessions. It is not a user credential and can’t manage other sandboxes.
  • Sandbox JWT. Authenticates boundary opening and the supervisor’s control and mediation streams to the sandbox. The sandbox holds only the gateway’s public key, so it can verify the token but can never create one.

Each token works only on its own connection. Both are bound to one sandbox and one run of that sandbox, called a generation. Restarting a sandbox starts a new generation with fresh tokens and fresh TLS certificates, and the old ones stop working.

Shared Kubernetes supervisors also use a separate, gateway-scoped supervisor-host JWT to receive assignments. The pool’s replicas share this token, which authorizes only the host assignment stream. The gateway checks assignment ownership separately, and each assigned sandbox still uses its own session JWTs. See Multi-tenant Supervisor.

Renewing and revoking

The supervisor keeps its session tokens in memory and renews both together before they expire. Renewal works only while the sandbox still exists, so deleting a sandbox ends that sandbox’s session.

Shared deployments, such as Kubernetes, should set gateway_jwt.ttl_secs so tokens expire. Local single-user gateways can leave it unset, which issues tokens that last for the life of the sandbox run.

What the agent can see

The agent shares its side of the boundary with the sandbox, so the sandbox holds nothing worth stealing: no gateway signing key, no gateway JWT, and no provider credentials. It can verify that it’s talking to the right supervisor, but it can’t impersonate one.

If the supervisor disconnects, the sandbox freezes the agent. The same supervisor process can reconnect and resume it within the recovery window. In a shared Kubernetes supervisor pool, the gateway can authorize a replacement supervisor with a signed takeover grant for that sandbox generation and a higher ownership epoch. When the replacement confirms the boundary, a runtime that supports takeover revokes the previous owner’s access and resumes the agent. Valid session credentials alone do not authorize takeover. If recovery does not complete before the deadline, the runtime terminates the workload.

Working With Your Existing Infrastructure

OpenShell plugs into the tools you already use, including container runtimes, schedulers, secret stores, identity providers, image pipelines, storage, and device plugins. The gateway and supervisor define how OpenShell behaves. Drivers translate that behavior into whatever your platform understands and report back what happened. This keeps platform-specific details out of the core control plane and the policy model.