Quilzomanual

Run an AI agent's own code in a sandbox

When an agent's own program decides instead of a model, Quilzo runs it in a box and hands in only what the declaration allows.

In the adminAgents

A program is the other way an agent decides: a coding agent's command line, a script, or a runtime somebody built their agent in. Quilzo never runs it as itself. It runs it in a box with no capabilities, its own namespaces, Landlock for files and ports, and a system call filter. It hands in three things over the box's own loopback: the agent interface for this run, a model endpoint through the gateway, and a proxy to the declared hosts.

Check where programs can run

quilzo agent backends
native     available
  namespaces true, Landlock 7 (files true, ports true), system call filter true, no capabilities true
openshell  unavailable
  the openshell command is not installed here (https://docs.nvidia.com/openshell)

The native backend is built from the Linux kernel's own parts. It needs no root, no daemon and no container runtime: user, PID, network, IPC and UTS namespaces, Landlock for files and ports (port rules need Linux 6.7, Landlock ABI 4), seccomp, no capabilities, and resource limits. NVIDIA OpenShell is a second backend, with the same services handed in and the declaration compiled to its policy.

Give an agent a program, and run it

  1. Write the program

    Inside the box the program finds what it needs in its environment. This one lists its tools and reads a page:

    import json, os, urllib.request
    MCP = os.environ["QUILZO_MCP_URL"]
    TOKEN = os.environ["QUILZO_RUN_TOKEN"]
    def mcp(method, params, id=1):
        body = json.dumps({"jsonrpc": "2.0", "id": id, "method": method, "params": params}).encode()
        req = urllib.request.Request(MCP, data=body, headers={
            "Content-Type": "application/json", "Accept": "application/json",
            "Authorization": "Bearer " + TOKEN})
        return json.load(urllib.request.urlopen(req))
    tools = mcp("tools/list", {})["result"]["tools"]
    print("tools:", ", ".join(t["name"] for t in tools))
    page = mcp("tools/call", {"name": "quilzo_read",
               "arguments": {"operation": "read_page", "arguments": {"page": "returns"}}}, 2)
    print(page["result"]["content"][0]["text"][:200])
  2. Declare it as the agent's program

    Name the command by its absolute path, and every directory it needs to read with --read. Settings go in with --env K=V, never secrets.

    quilzo agent program help-desk --read /opt/agent -- /usr/bin/python3 /opt/agent/agent.py
  3. Run it

    quilzo agent run help-desk --program "What do the returns rules say?"
      deciding with program:python3; the manifest is still the only vocabulary
      its program ran on native for 164ms: namespaces true, Landlock 7, system call filter true, capabilities dropped true
    help-desk  retrieval
      its program chose each action, in its box; each one went through the manifest as a step
      it said: tools: quilzo_find, quilzo_read, quilzo_write, quilzo_check
    body: Thirty days, unused, and we pay the postage back. Ink is the exception: …
      did 1, refused 0, failed 0
      was decided by a program, so anything it produced needs a person

    The run is kept and traced like any other, and has a receipt.

What the program finds inside

VariableWhat it is
QUILZO_MCP_URLThe agent interface for this run only, as MCP. Every operation is one step of the run, through the same gate, budget, approvals, audit records and receipt as any other.
QUILZO_RUN_TOKENThe credential for this run's services. It is worth nothing outside the box or after the run.
OPENAI_BASE_URL, OPENAI_API_KEYAn OpenAI-compatible model endpoint through the model gateway. The run is charged, budgets hold, and no provider key is ever inside. Pictures and the tools a program offers pass through whole, and the tool the model chooses comes back. A picture goes only to a route allowed personal data, since it cannot be checked for any.
HTTPS_PROXY, HTTP_PROXYA proxy to the hosts the declaration names and nothing else. Each connection is recorded.
QUILZO_RUN, QUILZO_AGENT, QUILZO_GOALThe run, the agent and what it was asked to do.

Nothing else is reachable. The program has a working directory of its own, reads the system's libraries and the directories you named, and nothing of the store. Its /proc and /sys are its own: its own processes, and none of the machine's hardware. Because OPENAI_BASE_URL is the usual variable, most agent frameworks pick up the gateway without changes.

Limits a program cannot get round

  • Time is the declaration's duration. CPU time, memory, file size, open files and processes are capped too; --memory-mb sets the memory cap (2048 by default). It counts what the program writes, not the address space it reserves, so Node and a browser run in the box.
  • A connection to a host the declaration does not name is refused by the proxy, and the network namespace leaves no other way out.
  • Ask-first capabilities wait for a person, and the program waits on its call meanwhile. Answer on the run's page or with quilzo agent approve RUN STEP (or decline). If nobody answers before the run's time is up, the call is refused, with the reason.
  • The exfiltration breaker applies. Once the run holds something private and has read somebody else's words, a step that would send it out waits for a person in the same way, and a connection through the proxy is refused, with the reason.

Ask in advance with quilzo agent could --program NAME host:api.example.com.

Run it in NVIDIA OpenShell

With the openshell command installed, choose it per agent and name the image the sandbox is made from:

quilzo agent program help-desk --backend openshell --image IMAGE -- /usr/bin/python3 /opt/agent/agent.py

The same three services are handed in, and the declaration is compiled to OpenShell's policy. Take a program away with quilzo agent program help-desk --remove.

Next