Mantle

Security model

What a session can reach.

The agent and its tools run inside a Substrate sandbox on the worker. This page lists what that sandbox enforces in 0.3.1, where credentials go, what is recorded, and what is outside the model.

01 / Trust

Trust the worker’s administrator.

The worker host is trusted. Host administration, including mantle worker ssh, runs outside every sandbox and can read every workspace and the Claude token file. The sandbox protects the host and other sessions from the agent; it is not a boundary against whoever administers the worker.

02 / Sandbox

Required before an agent starts.

Substrate reports facts about what it can enforce. mantle start refuses with FAILED_CAPABILITY and the missing names unless the worker reports all of these:

Inside, /workspace is writable; /opt/mantle and the host’s /usr, /bin, /lib and /lib64 are read-only. The sandbox refuses Unix-domain sockets. CPU is not bandwidth-limited: Substrate 0.16.1 bounds cumulative CPU time only, and resources.cpu only sets CARGO_BUILD_JOBS. A storage quota applies only when the worker serves workspace quotas. Substrate’s full isolation floor is documented in the Substrate documentation.

03 / Network

Ten destinations, all port 443.

The only way out of the sandbox is the egress aperture to mantle-egress, a CONNECT proxy on the worker’s loopback at 127.0.0.1:3128, outside the sandbox. The service runs it with its built-in allowlist, shared by every session on the worker:

Gateway allowlist
ForDestinations
Claude Codeapi.anthropic.com:443, platform.claude.com:443
Codexauth.openai.com:443, chatgpt.com:443
GitHubgithub.com:443, codeload.github.com:443, objects.githubusercontent.com:443
crates.iocrates.io:443, index.crates.io:443, static.crates.io:443

The gateway’s refusals and address filtering are covered by native scenarios with controlled DNS, and were observed on a live worker for 0.1.2 (an unlisted host and direct egress refused).

04 / Credentials

Where the agent’s credential lives.

Claude Code
On the laptop, claude.token_command or claude.token_file supplies the token; error messages name the source, never the value. worker up and start write it to /var/lib/mantle/secrets/claude on the worker. Substrate passes it to the agent execution through the claude secret slot on an inherited descriptor; the launcher puts it in the agent’s environment. Tools the agent starts can inherit it. The worker token file remains after stop.
Codex
Device login in the agent terminal. The auth file and conversation files live in /workspace/.mantle/home/.codex, readable by the agent’s tools. stop keeps them; destroy deletes them.
Command sessions
No agent credential: no claude secret slot, no CLAUDE_CODE_OAUTH_TOKEN, no Codex home and no Claude or Codex variables. A manifest with agent.auth and kind: command is refused.
mantle exec
Gets no agent credential, but shares the workspace, including the Codex home.
Git
No Git credential broker. Repositories are cloned over HTTPS without credentials.

05 / Recording

Terminal output may be recorded.

Claude Code, Codex and command sessions use the same Substrate terminal transport, which may record terminal output. There is no end-to-end non-recording mode. Mantle’s own launcher keeps its replay buffer in memory, and Codex’s SQLite and text diagnostics are written to a tmpfs the launcher verifies. mantle status --json and the acceptance runner never fetch terminal output.

06 / Laptop state

Private by default.

Each state directory (default ~/.local/state/mantle, mode 0700) holds the SQLite records, the worker’s SSH key and its pinned host key. Ordinary commands accept the worker’s host key on first use and refuse a changed key afterwards (StrictHostKeyChecking=accept-new). doctor, JSON status and worker upgrade --check accept only an already pinned key. Your configuration file holds cloud identifiers and stays outside every repository.

07 / Outside the model

Not protected, not provided.