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
requiredserver 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 inrwpaths. - The server runs in its own process group. Closing the session kills the group, and the server is killed if Aura dies.
httpservers cannot be confined locally;sandbox: trueon 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"}'