agent-locker 0.1.0-alpha.1

A sandbox for running coding agents with restricted filesystem access.
agent-locker-0.1.0-alpha.1 is not a library.

Agent Locker

A sandbox for running coding agents (and arbitrary commands) with restricted filesystem access. The whole filesystem is made read-only via Landlock; only a small, explicit set of paths is writable.

Requires Linux 5.13+ with Landlock enabled, and currently x86_64 only.

Usage

agent-locker [-C DIR] <command> [args...]
agent-locker [-C DIR] <preset> [args...]
  • -C, --context-dir DIR — the main writable project directory (defaults to the current directory).
  • The first positional selects a built-in preset (claude, codex, opencode); anything else is run as a generic command.
agent-locker -- cargo test        # generic command in the current directory
agent-locker -C ./project claude  # claude preset scoped to ./project

What's writable

Every invocation grants write access to:

  • the context directory (and its real git directory, if it's a worktree),
  • /tmp,
  • /dev/null and /dev/tty — the only device nodes any agent needs to write (verified via strace). Reads elsewhere (e.g. /dev/urandom) still work because the rest of the filesystem remains readable.

Everything else — including the home directory, /dev, and /run/user — is read-only unless listed below.

Preset-specific writable paths

Presets additionally allow their own config/cache directories:

Preset Program Extra writable paths
claude claude ~/.claude, ~/.claude.json
codex codex ~/.codex
opencode opencode ~/.opencode, ~/.local/share/opencode, ~/.cache/opencode

Generic commands get no extra paths beyond the common set above.

Presets run in their default mode — agent-locker does not force flags like --dangerously-skip-permissions. Use the config file to opt in.

Configuration

Optional config file at $XDG_CONFIG_HOME/agent-locker/config.toml, falling back to ~/.config/agent-locker/config.toml when XDG_CONFIG_HOME is unset.

Each preset section may supply args, which are prepended to the preset's command line, before any arguments you pass on the command line. A missing config file is fine; a malformed one — including unknown sections or keys — is an error.

Exhaustive example

# Arguments are prepended to the preset's command line, before any arguments
# passed on the command line. Each section is optional; omit a section to run
# that preset with no extra arguments.

[claude]
# Skip claude's interactive permission prompts.
args = ["--dangerously-skip-permissions"]

[codex]
# Bypass codex's own approval/sandbox prompts.
args = ["--dangerously-bypass-approvals-and-sandbox"]

[opencode]
# opencode takes no special arguments by default; add your own here.
args = []