ReferenceAsk
Remy Reference/Architecture/Boundaries & Execution/Execution Islands
05Boundaries & Execution

Execution Islands

The sandbox app code runs in, the three islands it becomes, and the contract that keeps the arrangement swappable.

App code runs in a Kata microVM with its own guest kernel, scheduled by Kubernetes onto EC2 nodes with nested virtualization, on a cluster in a VPC that cannot reach the platform. This chapter covers the sandbox primitive, the three islands it becomes, the hardening on every pod, and the provider contract that makes the arrangement swappable.


#The Primitive

A sandbox is a pod whose runtime class is Kata Containers. Instead of sharing the node's kernel the way an ordinary container does, each pod boots a lightweight virtual machine with its own kernel, and the container runs inside it. The boundary between app code and the node is a hypervisor, and the boundary between two apps is two hypervisors.

The nodes are EC2 instances with nested virtualization enabled, in dedicated node groups on the untrusted cluster. A node-group module owns the launch template that turns on nested virtualization, sets the instance metadata hop limit, applies the Kata taint and labels, and carries the tags the cluster autoscaler needs to model a node that does not exist yet. The same module is instantiated three times, once per island.

Kata's node configuration is asserted twice. A privileged DaemonSet keeps the node-level defaults correct, and every pod also carries runtime-scope annotations that pin the two settings that matter: the seccomp profile is applied inside the guest, and the sandbox's cgroup is anchored so the VM survives systemd's reclaim. A sandbox asserts its own hardening and does not depend on landing on a freshly configured node.


#Three Islands

The platform runs untrusted code in three places: separate node groups, separate resource profiles, separate lifetimes, and one shared construction path.

Release sandboxesJob runnersDev boxes
Node groupkata_appskata_jobskata_dev
What runsA deployed app's compiled methodsA build: method compile, web build, diagnosticsA person's development environment
LifetimeAssigned to a release, exits on idleSeconds to minutes, exit 0Hours, on a lease
ImageThe worker imageRunner images derived from the workerThe dev-box image
ReachabilityThe worker port, from the platformNoneThe dev-box port, from the sandbox proxy
ScalingA warm pool sized to demandOn demand, from zeroWarm-ish, few
ChapterRelease SandboxesJob RunnersDev Boxes

The rule is: share code, never share runtime. One module builds the pod manifest, applies the hardening, stamps the labels, and reaps terminated pods, so a hardening fix lands once. Three provider instances apply it with three configurations. A janitor on one island never sees another island's pods, because every pod carries an island label and every selector is rooted in it.


#What Every Pod Carries

The manifest builder produces one shape for every sandbox, and the release worker's container is byte-for-byte what the warm pool boots.

SettingValueWhy
runtimeClassNameThe Kata runtime classA VM per pod
seccompProfileRuntimeDefault, asserted in the guest by annotationThe syscall filter applies inside the VM
capabilitiesDrop allThe worker binds an unprivileged port and needs none
allowPrivilegeEscalationfalseNothing in the pod escalates
automountServiceAccountTokenfalseNo credential to present to the cluster
dnsPolicyNone, public resolversCluster-internal names do not resolve at all
restartPolicyNeverA dead sandbox is replaced, never resurrected in place
activeDeadlineSecondsPer islandKubernetes hard-kills a wedged pod regardless of what it is doing
imagePullPolicyAlwaysImages are moving aliases; every start re-checks the digest
Resource limitsPer islandBounded CPU and memory per sandbox
Labelsapp, island, pool, tier, release, app id, roleWhat the egress policy and the janitors select on

Files a runner needs before it starts arrive as a ConfigMap named after the pod, mounted into the image's working directory, and owned by the pod so Kubernetes garbage-collects it. Nothing is ever written into a running sandbox from outside.

The sandbox NetworkPolicy from The Trust Boundary selects on the app label every sandbox carries, so the value is defined once and the policy follows it.


#The Provider Contract

The orchestrator talks to sandboxes through one interface. A sandbox is a self-starting OCI image, booted from a spec. The contract is declarative: no exec into a running sandbox, no file writes after boot, no snapshots. Everything a workload needs is in the spec at create time.

The spec. An image, a command and arguments, environment, a working directory, files to place before start, labels to stamp at birth, and three hints: one to return as soon as the pod exists, one to fail fast when a node cannot be found, and one to report boot milestones to whoever is waiting on it. Every field is optional, and absent means exactly the provider's default, which is the release worker on its configured image.

Six operations. Create a sandbox, fetch one, find the sandboxes for a release, stop an app's sandboxes, relabel a sandbox, and reap terminated pods. A running sandbox reports its address on a port, and stops on request.

A required warm pool. The release path provisions only from the pool and has no cold-boot path, so a provider that cannot boot ahead of demand cannot serve a release. The pool is global across every orchestrator replica: which warm sandbox a caller receives is decided by an atomic pop in a Redis registry, and the pool label on the pod is the durable record of the claim.

Optional capabilities. A fleet view for the admin console, showing per-pod health, labels, resource usage, and boot timing broken into schedule, image and VM, and worker start; and log streaming for a pod's output. A consumer checks a capability once and calls it.

The Kubernetes provider implements the contract today. The same shape lets a Docker Engine provider, or a remote sandbox service, implement the same operations and pool, and slot in beneath the release manager unchanged.

What This Gives an App
Its code runs behind a hypervisor, not a shared kernel.
Its sandbox is built from one hardened manifest that every other sandbox also gets.
Its island's failures, bursts, and node group are its own; a build storm never touches a serving pod.
The platform can move it onto a different provider without the app knowing.
DiagramFIG. 05 — EXECUTION ISLANDS
EC2 NODE · NESTED VIRTKATA microVM · GUEST KERNELCONTAINERruntimeClass: Kataseccomp: RuntimeDefaultcaps: drop allno priv-escno SA tokendnsPolicy: NonerestartPolicy: NeveractiveDeadline · per islandimagePull: Alwayslimits: cpu / memManifest builderKubernetes provider · one module → three configs · harden, label, reapRelease sandboxeskata_appsruns · compiled methodslife · idle-exitreach · worker portscale · warm poolJob runnerskata_jobsruns · builds & diagnosticslife · seconds, exit 0reach · nonescale · from zeroDev boxeskata_devruns · a dev environmentlife · hours, on leasereach · dev-box portscale · warm-ishSandbox orch.the only callerSandbox provider contractdeclarative · no exec, no writes after boot, no snapshotssix ops · create · fetch · find · stop · relabel · reaprequired · a warm pool · atomic pop in a Redis registryTHE PRIMITIVETHREE ISLANDSshare code · never share runtimesandbox namespacededicated node group · metadata hop 1app codeworker · runner · dev boxseccomp RuntimeDefault applies in-guestcode ↔ node= 1 hypervisorapp ↔ app= 2 hypervisorsWHAT EVERY POD CARRIES · one hardened manifestlabels · app · island · pool · tier · release · appId · role↳ the egress NetworkPolicy and the janitors select on theseTHE PROVIDER CONTRACT · one interface, any implementationOther providersDocker Engine · remote sandbox serviceimplement the same contract, slot in unchanged
sandbox pod · node ⊃ VM ⊃ containercomponent / nodepod hardening settinggrouping · alternativebuilds · provisions · calls
One hardened primitive, three islands, one construction path. A sandbox is a pod whose runtime class is Kata: an EC2 node with nested virtualization holds a microVM with its own guest kernel, and the container runs inside that. The boundary between app code and the node is one hypervisor; between two apps, two. A single manifest builder stamps that shape with the hardening and labels every pod carries. Three provider configs deploy it as three islands, each with its own node group, lifetime, and reachability, but one code path, so a hardening fix lands once. The orchestrator drives all of it through a single provider contract: the Kubernetes provider implements it today, and a Docker Engine or remote provider could implement the same six operations and warm pool, and slot in unchanged.

Figure 05, "Execution Islands": a three-tier plate. One hardened primitive, three islands, one construction path. Top left, the primitive as a nested-containment box: an EC2 node (nested virtualization) contains a Kata microVM (its own guest kernel), which contains the container (app code: a worker, a runner, or a dev box). The isolation claim below it: code to node is one hypervisor; app to app is two. Top right, a Manifest builder bar (the Kubernetes provider, one module to three configs) fans down into a dashed "sandbox namespace" zone holding three island columns, each a pool of pods. The columns compare across the row: Release sandboxes (kata_apps: compiled methods, idle-exit, worker port, warm pool), Job runners (kata_jobs: builds and diagnostics, seconds then exit 0, no reachability, from zero), and Dev boxes (kata_dev: a dev environment, hours on a lease, dev-box port, warm-ish). The middle band, "what every pod carries", is a strip of hardening chips: runtimeClass Kata, seccomp RuntimeDefault, drop all capabilities, no privilege escalation, no ServiceAccount token, dnsPolicy None, restartPolicy Never, a per-island active deadline, imagePull Always, and CPU and memory limits; plus the labels (app, island, pool, tier, release, appId, role) the egress NetworkPolicy and the janitors select on. The bottom band, "the provider contract", is the swappable point: the sandbox orchestrator (the only caller) drives one declarative contract (no exec, no writes after boot, no snapshots; six operations; a required warm pool claimed by an atomic pop in a Redis registry), and a dashed "other providers" box (Docker Engine, a remote sandbox service) implements the same contract and slots in unchanged. No trust boundary in this figure, so no crimson.