Brewlet keeps container-grade isolation (runc) while adopting a Wasm-grade developer experience. This page covers the isolation model, defaults, supply-chain verification, and the one genuinely sharp edge: privileged node provisioning.
See also SPECIFICATION §11.
Execution is runc-backed, so a Brewlet workload gets the same isolation primitives as any ordinary pod:
- namespaces (pid/net/mount/ipc/uts) and cgroup v2 resource control;
- seccomp / AppArmor profiles;
- CNI networking (a real, isolated pod netns and pod IP).
The JAR is treated as untrusted code and runs inside that sandbox — nothing about "it's just a JAR" weakens the boundary relative to a container image.
The JVM runs as an unprivileged uid; root is squashed unless explicitly
requested. Set the identity via the artifact's user (uid/gid) or the pod
securityContext:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
runtimeClassName: brewlet
containers:
- name: app
image: registry.example.com/team/app:1.4.2
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true # the JDK root is RO already
capabilities: { drop: ["ALL"] }The JDK runtime root is mounted read-only and shared; only a small per-container upper/scratch layer is writable.
Because the JAR is a first-class OCI artifact, standard supply-chain controls apply:
- Digest-pin artifact references (
repo@sha256:…). The admission webhook stampsbrewlet.sh/artifact-digest, and the shim resolves the JAR straight from containerd's content store by digest. See Building & publishing. - cosign signatures / SLSA provenance (roadmap, Phase 4): the shim/operator can require a valid signature and/or provenance on the artifact before launch, via admission policy. Verification failure → admission denied with a clear reason. See the supply-chain verification research note for the design (policy-engine vs. a fail-closed Brewlet webhook, and turnkey signing).
The single biggest security win: the JVM lives on the node, shared across workloads. Patching the node JDK patches every workload at once — no rebuilding and re-pushing hundreds of images to ship a JVM CVE fix. See JDK management.
Node provisioning is privileged and mutates the host. The
brewlet-node-provisioner DaemonSet:
- runs privileged with
hostPID; - writes the shim to the host
PATHand JDK/launcher roots under/opt/brewlet; - edits
/etc/containerd/config.tomland reloads containerd.
Mitigations and guardrails:
| Guardrail | How |
|---|---|
| Provisioning is scoped, but broad by default | The chart's default NodeProfile provisions every node (§5.6). To limit the blast radius, disable it (defaultProfile.enabled=false) and define named NodeProfiles scoped to platform-owned pools. The legacy standalone DaemonSet instead touches only nodes carrying the brewlet.sh/provision=true label. |
| Scope to platform-owned pools | Use named NodeProfile pools (or the brewlet.sh/provision label for the standalone path) to restrict provisioning to nodes your platform team controls. Do not provision shared/hostile multi-tenant nodes. |
| The operator is unprivileged | The operator only talks to the API server; only the DaemonSet it manages is privileged. |
| Stronger isolation for untrusted JARs | Use gVisor or Kata as the underlying OCI runtime on shared nodes (roadmap option). |
| Webhook can't block workloads | admission.failurePolicy: Ignore (default) means a webhook outage never wedges deployments. |
⚠️ Treat enabling Brewlet on a node the same way you'd treat any privileged node-bootstrap DaemonSet (this is the KWasm model). Document the blast radius.
- Trusted tenants / your own services: runc isolation is equivalent to ordinary containers — appropriate as-is.
- Untrusted or hostile JARs: layer gVisor/Kata under the sandbox and keep
provisioning off shared nodes. runc alone is the same trust boundary as a normal
container — no more, no less. See the
sandbox runtimes research note for how the isolation
tiers would be built (gVisor as a
runscswap; Kata's tradeoffs).
- Provision only platform-owned node pools; scope
brewlet.sh/provision. - Pin component images and OCI artifacts to digests.
- Run workloads
runAsNonRoot, drop capabilities,readOnlyRootFilesystem. - Use cert-manager for the admission webhook serving cert in production (not the Helm self-signed cert). See Configuration.
- Plan JDK patch cadence — it's now a single centralized lever.
- For untrusted workloads, evaluate gVisor/Kata.