gVisor, not plain Docker
The handler runs under gVisor (runsc), a user-space kernel that intercepts syscalls, on an operator-provisioned host. Plain Docker (runc) shares the host kernel and is not a security boundary for untrusted code.
The hardened run-spec
Both backends enforce the same invariants on every untrusted container. None of them is optional.No privilege, no host access
No privilege, no host access
Never privileged. Never host networking. No added capabilities,
capDrop ALL, and no-new-privileges. The container cannot escalate.No secrets in the environment
No secrets in the environment
The platform environment is empty. No secrets, no keys. The only thing injected is a short-lived, scoped data-proxy token, and only per request. See the egress proxy.
No network of its own
No network of its own
Network
none. The container has no egress path except the data proxy, which is attached host-side. It cannot open a socket to the internet on its own.Read-only and noexec filesystem
Read-only and noexec filesystem
Read-only root filesystem.
tmpfs mounted noexec and nosuid, so the handler cannot drop an executable and run it, or gain privilege through a setuid binary.Hard resource limits
Hard resource limits
Positive
pids, memory, and cpu limits, plus a runner-enforced timeout and an optional disk quota. Live example caps: 256 pids, 256 MiB memory, 0.5 cpu. A handler cannot fork-bomb, exhaust memory, or run forever.Size caps
Request and response bodies are each capped at 1 MiB.
An oversize request is rejected before the handler is ever invoked, so a large payload cannot be used to run compute the buyer did not pay for. An oversize response fails closed with a
502.
Two containers per endpoint
A deployed endpoint is not one process. It is two, with a trust boundary between them.1
The untrusted handler
Runs the generated code. It has no facilitator URL and no token, and it can talk only on its per-slug internal network. It cannot reach the money path even if it wanted to.
2
The trusted sidecar / gate
Sits in front. It owns the escrow response gate: it reads the 402, verifies the payment, invokes the handler, classifies the response, and settles. It holds the facilitator token.
3
Traefik routes the public host
Traefik routes the public host to the sidecar, never directly to the handler. Every call reaches the money path first.
Splitting the endpoint in two means the untrusted code never holds a credential that could move money, and never sees the facilitator. Even a fully compromised handler can only return a response, which the sidecar will then classify and, if it is bad, refuse to charge for.
Related
The static gate and egress proxy
What runs before the build and how the handler reaches an upstream.
The escrow response gate
The money path the trusted sidecar owns.
Provisioning
Standing up the gVisor host and the wildcard TLS domain.
The deploy pipeline
Where the sandbox sits in build and deploy.