Security & architecture
Containment you can take apart.
This audience reads the spec. So here it is — the six boundaries that hold an untrusted agent, each one enforced low enough that you can underwrite it. No hand-waving.
Kernel-enforced isolation
Each invocation runs in a fresh, unprivileged sandbox built per-run. No host filesystem, no ambient capabilities, a pinned syscall surface. The boundary is the kernel's, not a library's.
- bubblewrap user namespaces
- seccomp-BPF syscall filter
- cgroup v2: cpu / mem / pids / wall caps
- no-new-privileges, read-only system
One door, allowlisted
All outbound traffic is forced through a forward proxy. A request is permitted only if its host matches the tenant's allowlist; internal ranges, cloud metadata, loopback, and DNS-rebind are denied structurally — before any tenant check.
- per-tenant allowlist, hot-reloadable
- structural deny: RFC1918 · IMDS · loopback
- resolve-once, no rebind
- model providers are an explicit allowed class
Agents report. They never act.
Actuation is not a permission you can grant — it isn't on the path. A spec whose tool list contains an actuation primitive is rejected at validate time. Side-effecting actions stay with the host, always.
- actuation prefixes rejected at publish
- no host-side action surface for agents
- signals publish to one assigned topic only
No tenant sees another
Every read and write is tenant-scoped. Cross-tenant reach — filesystem, memory residue, assigned topics, context — isn't trusted to comments; it's asserted by a hardening drill that fails the build on regression.
- tenant-scoped repositories
- per-run mount + pid + net namespaces
- cross-tenant reach is a drill, not a doc
Nothing smuggles out
Resolved input values and secret-shaped strings are scrubbed from every reply and signal on the worker side, before the bytes cross the sandbox boundary. The control plane treats results as opaque, already-redacted.
- worker-side value-list + pattern redaction
- resolved inputs never persisted
- belt-and-braces secret-shape reject at insert
A receipt for everything
Every invoke, deploy, quota refusal, and cap trip writes an append-only audit row keyed for investigation — identifiers, outcomes, byte-lengths, never content. The log an auditor reads is the same one ops does.
- append-only audit_logs (trigger-enforced)
- lengths + identifiers, never values
- per-investigation query recipes documented
The threat model, per-invariant security review, and the full fifteen-shape hardening drill suite are part of the open repo.
Request access →