Skip to main content

Run claude code in an isolated container sandbox.

uvx trusted-agent

With no command, this runs claude --dangerously-skip-permissions — the sandbox is the permission boundary. Pass a command to run something else:

uvx trusted-agent claude "Do something"

Backends

The backend is auto-selected from the host OS. Override with --backend {auto,podman-gvisor,apple-container}.

  • podman-gvisor (Linux default) — rootless podman running images under gVisor's runsc. Two layers: container + user-space kernel. Requires podman and runsc on PATH.
  • apple-container (macOS default) — Apple's native container CLI. Each container runs in its own minimal Linux VM via Virtualization.framework, so the VM boundary is the sandbox. Requires Apple Silicon and macOS 15+ (macOS 26 recommended). If container is not installed, the tool prompts to install it via Homebrew (brew install --cask container); container system start is invoked automatically when the service is not running.

You need to be signed-in in claude-code on the host.

Security delta on macOS

The Linux backend applies several defense-in-depth knobs that have no equivalent under Apple Container and are skipped there:

  • --cap-drop=ALL, --userns=keep-id, --security-opt=no-new-privileges, --pids-limit, and the cgroup flags (--cgroup-manager=cgroupfs, --runtime-flag=ignore-cgroups).

Apple's container CLI does not expose any of these Linux-side knobs. On macOS the per-container Linux VM provides a hardware-backed isolation boundary that those flags were emulating in software.

Agents

The first token of the command picks which host configs are projected into the sandbox. Unknown commands (e.g. bash) get no projections.

  • claude (default) — ~/.claude.json, ~/.claude/.credentials.json, ~/.claude/settings.json, ~/.claude/plugins/.
  • opencode${XDG_DATA_HOME:-~/.local/share}/opencode/ (auth tokens) and ${XDG_CONFIG_HOME:-~/.config}/opencode/ (config, agents, skills).
  • crush${XDG_CONFIG_HOME:-~/.config}/crush/ and ${XDG_DATA_HOME:-~/.local/share}/crush/.

Each set is copied to a temp dir before mounting, so token refreshes and in-session writes never touch the host originals. The bundled variants only ship claude; install opencode or crush in a custom variant Dockerfile to use them.

Variants

Pick a pre-built image variant with --variant NAME (defaults to default):

  • default — node + python + common dev tools.
  • nodejs — adds pnpm and yarn.
  • rust — adds the Rust stable toolchain (with clippy and rustfmt).
  • android — adds JDK 17 and the Android SDK.
uvx trusted-agent --variant rust claude

Drop your own Dockerfile at ~/.config/trusted-agent/variants/<name>/Dockerfile to add a variant. User variants take precedence over bundled ones with the same name. To extend the lean base, start your file with FROM trusted-agent-default:latest.

Image caches are not shared between backends — each backend builds into its own store on first use.

Changelog

All notable changes to this project are documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.12.0

Changed

  • When no command is given, the default is now claude --dangerously-skip-permissions instead of plain claude. The sandbox is the permission boundary, so the agent runs unattended by default; pass claude explicitly to keep permission prompts.

0.11.0

Added

  • trusted-agent --version / -V prints the installed version and exits.
  • Project ~/.claude/skills (user-defined skills) into the sandbox, same throwaway-copy model as plugins.

Fixed

  • Plugin skills now load inside the sandbox: plugin metadata records absolute install paths under the host home, which are rewritten to the guest home when the plugins dir is projected.

0.10.0

Added

  • Project host configs for opencode and crush into the sandbox when those are the command being run. Claude Code remains the default and keeps its existing projections; running anything else (e.g. bash) projects nothing.
  • Apple backend forwards the host's DNS servers (--dns) to both container run and container build. Works around apple/container#402: the gateway DNS proxy silently fails to start whenever another host service (e.g. Mullvad's local resolver) holds port 53, leaving containers without DNS.

Fixed

  • Apple backend now detects whether the container CLI uses image or images as its image-management subcommand (renamed in 0.6.0). The old hardcoded images made image_exists always fail, so every run rebuilt the image from scratch.
  • On macOS, Claude Code stores its OAuth tokens in the login Keychain, not in ~/.claude/.credentials.json; the credentials projection now falls back to the Claude Code-credentials Keychain item, so the sandbox no longer starts logged out.
  • Homebrew install hint updated: container ships as a formula now, not a cask (brew install container).

0.7.2

Fixed

  • nodejs variant build no longer collides with the pnpm/yarn corepack shims that ship in node:22-slim (npm install -g now passes --force).

0.7.1

Fixed

  • trusted-agent --help / -h now prints local usage and exits instead of building the image and forwarding the flag to claude inside the sandbox.

0.7.0

Added

  • Image variants. The single Dockerfile is split into default (lean base with Python), nodejs (adds pnpm + yarn), rust, and android. Pick one with --variant NAME. Users can drop their own variant at ~/.config/trusted-agent/variants/<name>/Dockerfile; user variants take precedence over bundled ones.

Changed

  • Image is now tagged trusted-agent-<variant>:latest instead of trusted-agent:latest. The old image is no longer built and can be removed with podman image rm trusted-agent:latest.
  • default variant no longer bundles the Rust toolchain or the Android SDK; use --variant rust / --variant android to get them.

0.6.2

Added

  • Render the changelog on the PyPI project page alongside the README, via the hatch-fancy-pypi-readme build hook.

0.6.1

Added

  • Mirror the host's ~/.claude/plugins/ into the sandbox at container start so installed plugins are available without manual reinstall. Carries over enabledPlugins and extraKnownMarketplaces from the host's ~/.claude/settings.json into the projected user settings.

0.5.0

Added

  • Bind-mount the git common dir for linked worktrees so git commands resolve inside the sandbox.
  • Rust toolchain (stable, with clippy and rustfmt) and the Android SDK (cmdline-tools, platform-tools, API 34, build-tools 34.0.0) in the image.

0.3.0

Added

  • Install uv / uvx in the sandbox image.
  • README with basic usage.

0.2.0

Added

  • First working version: run Claude Code inside a podman + gVisor sandbox with a projected ~/.claude.json, projected credentials, and a /workspace bind-mount.

Release files for trusted-agent 0.12.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for trusted-agent 0.12.0
File Size Uploaded
trusted_agent-0.12.0.tar.gz 17.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for trusted-agent 0.12.0
File Interpreter ABI Platform
trusted_agent-0.12.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.4 kB

Release files / trusted_agent-0.12.0.tar.gz

Download URL trusted_agent-0.12.0.tar.gz
Size 17.3 kB
Tags Source
SHA-256 checksum
How to use checksums
041880a799cddb84326c40d74c068c6615f520e7fe27fadb320338b0b1c65856
BLAKE2b-256 checksum
How to use checksums
cf046a22aae59c2f5fca4e603fbfe008526825adcdfb0c99f0fd8c08d871fd0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release files / trusted_agent-0.12.0-py3-none-any.whl

Download URL trusted_agent-0.12.0-py3-none-any.whl
Size 17.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a5b5a0672fab14b4e9735d603481bfe664e7823162ccbfa143cc4cb5473f0e60
BLAKE2b-256 checksum
How to use checksums
c7068bc03671a2eac966442739709079d7fe3b3b6adfed93959031b36fc5be60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.12.0 This release

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.2.0

1 release file

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page