Concept
Containment model
Enclave assumes the workload is hostile. Containment is the baseline for every session — not a set of toggles — and it states plainly what it does and does not yet enforce.
Threat model#
The code is untrusted: it may try to exfiltrate data, read host credentials, exhaust resources, or escape the container. Enclave's job is to make each of those either impossible or observable, and to ensure the blast radius of one bad run is exactly one ephemeral session.
Enforcement#
| Field | Type | Description |
|---|---|---|
| Kernel | gVisor (runsc) | Workloads run under a userspace kernel that intercepts syscalls — not directly on the host kernel. |
| API access | no SA token | automountServiceAccountToken=false — the pod has no Kubernetes identity to abuse. |
| Privilege | least | runAsNonRoot, all capabilities dropped, readOnlyRootFilesystem, no privilege escalation, no host mounts. |
| Egress | default-deny | Per-session NetworkPolicy with empty egress, which also blocks the 169.254.169.254 metadata IP. Allowlist mode permits explicit CIDRs only. |
| Resources | quotas | CPU + memory limits, Job activeDeadlineSeconds, podPidsLimit. Over-budget workloads are killed with a precise reason. |
| Secrets | boundary-injected | Service-binding secrets are held by the egress proxy and injected at the network boundary; a private-repo git token stays on the clone init-container. No secret is placed in the workload sandbox or returned by the API. |
| Audit | immutable | Every egress decision, binding invocation, quota kill, result, and teardown is recorded per session. |
The four invariants#
These are the boundaries the codebase commits to never break:
- Secret withholding. No brokered secret enters the workload sandbox or comes back to the caller: service-binding secrets are injected at the egress proxy, a private-repo git token stays on the clone init-container, and the public
Sessionhas no token field. - Backend parity. Orchestration, audit, streaming, and auth/tenancy logic are backend-agnostic, so simulator, Docker, and Kubernetes paths behave identically.
- Simulator honesty. The simulator models behaviour; it does not execute code and never pretends to compute.
- Secure defaults. Egress is default-deny; pods are non-root, no SA token, caps dropped, read-only rootfs, no host mounts. These don't get relaxed.
Honest caveats#
Not yet enforced
Enclave documents its boundaries rather than papering over them:
- gVisor egress enforcement is proven on the home k3s cluster; k3d validates the orchestration mechanics, not runsc itself.
pids_exceeded(fork-bomb) is reported as a kill reason by the Docker and simulator backends; on Kubernetes the node's--pod-max-pidscontains a fork bomb, but a PodSpec has no pids field, so the precisepids_exceededreason is not derivable.- The Docker backend runs on the host kernel (no gVisor) and can't enforce allowlist egress — it is a dev convenience, not a boundary.