Zethro Core · supervisor for agents · one Debian package

Give an agent exactly this much, and a record of all of it.

Core runs each agent in a cell, with its own namespaces, a Landlock ruleset, a seccomp filter and a cgroup, built by a worker that drops every privilege before the agent starts. What the agent may touch is a set of capabilities handed down by whoever started it, and a cell can only ever hand down less. Everything that crosses the boundary goes into a signed ledger.

// build.zon: what this cell may do, and no more
.{
  .paths  = .{ .{ .path = "src",  .rights = .rw },
               .{ .path = "/usr", .rights = .ro } },
  .exec   = .{ "/usr/bin/make", "/usr/bin/zig" },
  .net    = .{},                        // no route out
  .model  = .{ .role = "coder", .tokens = 200_000 },
  .budget = .{ .cpu = 4, .memory = "4GiB", .wall = "20m", .pids = 256 },
  .spawn  = .{ .depth = 1, .count = 4 }, // sub-cells inherit a subset
}

Five mechanisms

CELL

A sandbox the kernel enforces

User, mount, pid, net, ipc and uts namespaces; a read-only view of the host; a private writable layer; Landlock on paths; seccomp on system calls; cgroup v2 on resources. The worker holds three file capabilities and drops them before exec. Thirty-three catalogued escape techniques are each a test that must fail inside.

CAPABILITY

Rights that narrow

Eight types, path, exec, net, secret, model, budget, spawn and ledger. A handle is bound to its cell and cannot be replayed. Derivation is a subset check per type; revocation follows the derivation tree. A widening is refused and recorded.

LEDGER

Written, synced, acknowledged

One hash chain per cell, sealed in segments with Ed25519 and ML-DSA-65, each seal recorded in a host-wide stream. Execs and denied calls are captured through seccomp notification. Exportable as JSON lines. Replay a ledger against a new model and diff the result.

SNAPSHOT

Capture, rollback, fork, merge

Captures freeze the cell, stage changed files, thaw, hash. Rollback keeps the cell identity; fork starts a sibling from the same point. zc merge applies an approved diff hash to the requester's tree, only under write capabilities, and ledgers the approval.

NETWORK

No route without a right

A cell without a net capability has no route out. With one, nftables in the cell's namespace redirects allowed connections to a relay that resolves names, checks the TLS server name, opens the connection itself and records denials. Secrets are inserted by the relay; the cell never sees them.

MODEL

A gateway on loopback

Roles map to local or remote models per host. Request fields are allow-listed; provider keys never enter a cell. Tokens and money are reserved before a call and settled after. Local servers run only if their binary hash matches.

A session, end to end

  1. DeclareWrite a cell.zon. The validator refuses a semantic fault with the line number before anything runs.
  2. Runzc run --profile cell.zon -- <command>. The daemon, which holds no capability itself, asks the worker to build the cell and places it under its cgroup and budgets.
  3. WorkThe agent sees its view and nothing else. Sub-cells it spawns inherit a subset. Every boundary crossing becomes a ledger entry.
  4. StopExit, or a budget reached. The ledger names the cause. The cell's writes sit in its overlay.
  5. Read, then mergezc diff, then zc merge with the hash you read, or zc drop. Nothing reaches your tree unseen.
  6. ReplayAny ledger replays against a new model or policy; the diff is your regression test for agents.

Compared

Sandboxes are necessary and several good ones exist. Core assumes the sandbox and adds the record, the narrowing and the way back.

Zethro CoreNVIDIA OpenShellNonoOpenSandboxsystemd-nspawnFirejail
Kernel-enforced sandboxyesyesyescontaineryesyes
Per-call scoped rightscapabilitiespolicyper tool callnonono
Delegation that only narrowsyes, per typenonononono
Signed, replayable ledgeryeslogsnononono
Snapshots, rollback, forkyesnonononono
Merge after diffyesnonononono
Budgets as rightscpu, mem, wall, net, tokens, moneynononocgroup onlyno
Secrets kept out of the sandboxrelaynoproxynonono
Installed asone Debian packagevendor stackbinaryDocker, KubernetesDebian packageDebian package

From each project's public documentation at the time of writing. Corrections welcome through the repository.

Engineering

Language
Zig 0.17; C libraries only from Debian (libseccomp, libnftables, libcurl, libssl)
Executables
zcored (no capability), zcore-worker (three file capabilities, dropped), zc, zmodel, libzcore.so.1 with a C header
Protocol
length-prefixed JSON frames, unknown fields rejected, daemon version M serves M and M-1
Kernel
Linux 6.12 or later, with Landlock, cgroup v2, user namespaces, seccomp notification and idmapped mounts
Verification
unit tests, an escape suite in detect and held modes, a container and VM matrix, a second-builder security review per increment
Licence
open source

Core is in active development toward 1.0. Chapters 01 to 11 of the specification are complete; the daemon, worker, capability model and per-cell socket are built and verified. Follow progress in the repository.