Landlock Sandboxing

Aura uses Linux Landlock LSM to restrict filesystem access during tool execution.

How It Works

When sandboxing is enabled, Aura re-executes itself with Landlock filesystem restrictions applied. Only tools that declare Sandboxable() true are affected — other tools (todos, vision, transcribe, speak, query) run without restrictions.

The parent process pipes runtime context (sdk.Context) to the child as JSON via exec.Cmd.Stdin. This delivers agent name, model info, token state, stats, and workdir to the sandboxed process — the same context that in-process tools receive directly. Tool arguments remain CLI arguments (small, bounded); context bypasses execve() entirely via the kernel pipe (no ARG_MAX limit).

Configuration

File: .aura/config/sandbox/sandbox.yaml

sandbox:
  enabled: true

  restrictions:
    # Read-only paths
    ro:
      - /bin
      - /etc
      - /home
      - /lib
      - /lib64
      - /opt
      - /run
      - /sbin
      - /tmp
      - /usr
      - /var

    # Read-write paths
    rw:
      - /tmp
      - $HOME/.cache
      - $HOME/go
      - /dev/null

Paths support environment variable expansion ($HOME, etc.).

Writable directories permit moves and hard links between directories within the writable paths. Moving or linking a file across a read-only boundary remains blocked. These operations require Landlock ABI 2 or newer; when Landlock is available but too old, applying a sandbox with writable directories returns an error rather than dropping filesystem enforcement.

Mode and Agent Overrides

Modes and agents can extend or override sandbox restrictions via their features: frontmatter. Sandbox config follows the same override semantics as all other features.

Use extra to add paths on top of whatever the base restrictions resolved to:

features:
  sandbox:
    extra:
      rw:
        - .

Use restrictions to replace the base paths entirely:

features:
  sandbox:
    restrictions:
      rw: [/tmp, /var/log]

Other sandbox fields can also be overridden:

features:
  sandbox:
    enabled: false # explicitly disable sandbox for this mode/agent

Feature merge order: Global → Agent → Mode → Task = Effective Features. All layers use the same override merge — non-nil replaces, nil inherits.

Requested vs Enabled

Sandbox state is split into two independent flags:

State Meaning
Requested The user wants sandboxing (set via config enabled: true, /sandbox, or Ctrl+S). Independent of kernel support.
Enabled Landlock is actually enforcing restrictions. True only when both requested AND the kernel supports Landlock.

Landlock requires Linux 6.2+. On older kernels or non-Linux systems, sandboxing is requested but not enforced — tools run without filesystem restrictions.

A user on a system without Landlock support can still request sandbox — the UI shows the distinction (lock vs unlock emoji), and templates can branch on either flag. /info and /sandbox display both values.

Both states are available in prompt templates as {{ .Sandbox.Requested }} and {{ .Sandbox.Enabled }}. The {{ .Sandbox.Display }} field provides a pre-rendered restriction summary for prompt injection.

Controls

Method Description
/sandbox or /landlock Show or toggle sandbox
Ctrl+S Toggle sandbox on/off
Status bar Shows lock emoji (enabled) or unlock emoji (disabled)

MCP Servers

MCP tools run inside their server process, so the tool sandbox does not apply to them. A stdio server configured with sandbox: true is confined itself:

crossroads:
  command: uv
  args: [run, --script, /opt/trusted/authoring_mcp.py, --workspace, .]
  sandbox: true
  required: true

Aura starts the server through a private entrypoint of its own binary, which applies the same Landlock implementation with the session’s effective restrictions (ro and rw above, resolved against the working directory) and then executes the server. The confinement applies whether or not tool sandboxing is currently enabled, and is inherited by everything the server starts. Writes outside the rw paths — including through symlinks — fail with permission denied.

  • The server never starts unconfined: if Landlock is unavailable or cannot be applied, the connection fails (and a required server fails startup).
  • Keep the server’s code outside its writable paths (for example in a separate trusted checkout), so the model cannot change code that runs with the server’s privileges.
  • Temporary and cache paths the server needs (e.g. TMPDIR, UV_CACHE_DIR) must lie in rw paths.
  • The server runs in its own process group. Closing the session kills the group, and the server is killed if Aura dies.
  • http servers cannot be confined locally; sandbox: true on them is a configuration error.

CLI Sandboxing

The aura tools command supports sandboxed tool execution:

# Run with read-only sandbox
aura tools --ro Read '{"path": "file.txt"}'

# Add custom paths (repeat the flag for multiple paths)
aura tools --ro-paths /extra/path --ro-paths /another --rw-paths /tmp/work Read '{"path": "file.txt"}'

Back to top

Copyright © 2026 idelchi. Distributed under the MIT License.