arizuko › research
research
How arizuko separates tenants, confines a turn and lets folders hand work to each other.
- Architecture — tenancy, turns, topics, routing
- Security — threat model, layers, egress
- Patterns — delegation and observation
- Skills — tools against skills
A folder is a tenant and routd checks every call
- Tenancy
- A folder is a tenant. Its path is a routing target and the home the guest sees. Authority comes from rows in the
acltable, androutdchecks them on every tool call. See grants. - Turn
routdmatches a route and posts/v1/runstoruned.runedboots one QEMU guest for the turn and powers it off after the reply. See a turn, end to end.- Group, topic, session
- A group is a persistent folder. A topic is a thread inside it with its own session. A session is one Claude Code context. See topics.
- Routing
- Routes are rows in the
routestable withseq,matchandtarget. The lowestseqthat matches wins, and an engaged chat overrides the target. See routing. - Observation
observe_group(source)subscribes a folder to the inbound messages of another folder.routdshows them as<observed>context, capped byOBSERVE_WINDOW_MESSAGESandOBSERVE_WINDOW_CHARS. See route modes.
Four layers confine a turn that is not trusted
Arizuko assumes three things:
- Agent output is untrusted
- A model can produce malicious output.
- Tool calls are the attack surface
- Every MCP tool call can try to gain authority.
- Network access is a risk
- An agent with open network access can send data out.
| Layer | Mechanism | Threat stopped |
|---|---|---|
| Guest | One KVM guest per turn, powered off after; the agent's kernel is not the host's | Process escape, host filesystem access |
| Network | One tap per guest, a static rule set that accepts only the proxy's port, and a proxy started for that turn | Data sent to a host outside the allowlist |
| MCP | One unix socket per folder at <data>/ipc/<folder>/gated.sock, with grants checked by routd |
Tool access in another tenant, privilege escalation |
| Secrets | AES-256-GCM at rest; routd resolves each capability credential on the host per tool call |
Secret theft from disk or from the guest |
The guest receives model credentials, the five keys of store.EnvProfileKeys [store/secrets.go], and any key that a shell:env:<KEY> grant names [runed/render.go]. See secrets.
The host bridge of a turn dials the socket of that turn's folder only. See ant.
The proxy is the only way out of the guest
The per-folder allowlist is enforced by a proxy that runed starts for each turn:
- No other route
- The only interface of the guest is its
/30tap. The rule set of that tap accepts only the proxy's port and drops the rest, so a raw socket to an IP address goes nowhere. [runed/vmnet.go] - Host matching
- The match is exact or by subdomain, ignores case, and reads the host from the request line. [egress/match/match.go]
- CONNECT tunnels
- The proxy passes HTTPS through. It has no CA, no key and no view of request bodies. [egress/proxy.go]
- One client
--clientpins the proxy to the address of that one guest, and the proxy refuses every other peer. [runed/vmnet.go, client]
An allowlist example: ["api.anthropic.com", "github.com", "pypi.org"].
See egress docs and
SECURITY.md.
Three tools move work between folders
delegate_group(group, prompt, chatJid)- Hands a prompt down to a child folder. The child runs on its own, and the parent does not wait. See a child folder runs in its own guest.
escalate_group(prompt, chatJid)- Hands a prompt up to the parent folder. The parent answers back through this child.
observe_group(source)- Reads the messages of another folder without taking over its routing.
fork_topic(parent, child) starts a new topic with a fresh session ID and a copy of the parent's Claude Code session file. See topics.
Tool definitions: [delegate_group] [escalate_group] [observe_group] [fork_topic].
A side effect needs a tool and knowledge needs a skill
| Aspect | MCP tool | Skill |
|---|---|---|
| What the agent holds | Tool name and description | Name and description; the agent reads the SKILL.md body when the task matches |
| Who enforces the limit | routd, through grants on each call |
Nobody; the text only instructs the agent |
A side effect such as a message, a new group or a token goes through an MCP tool, because routd checks a grant on each call.
A procedure or domain knowledge goes in a skill.
Claude Code reads skills from the folder. For codex and pi, ant/src/skills-scan.ts checks each skill and, for codex, renders a <skills> index into the prompt.
See skills.
Part of the arizuko docs ·
Comparable systems: how each differs from arizuko
Related: Agent frameworks ·
krons.fiu.wtf
Source: github.com/kronael/arizuko (MIT) ·
SECURITY.md ·
ROUTING.md