# Permission System for Bash Command Approval and Sandboxing in Reasonix

> Explore Reasonix's permission system for Bash command approval and sandboxing. Learn how it uses deny ask allow fallback sequence and OS-level sandboxing to secure shell execution.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: internals
- Published: 2026-08-13

---

**Reasonix enforces a layered permission hierarchy that evaluates Bash commands through a deny → ask → allow → fallback sequence, combining regex-based access control lists with OS-level sandboxing via Seatbelt or bubblewrap to isolate shell execution from the host filesystem.**

The permission system for bash command approval and sandboxing in Reasonix provides fine-grained governance over shell commands executed by the AI agent. According to the esengine/DeepSeek-Reasonix source code, the platform implements a fail-closed security model where write-capable tools default to explicit user approval unless explicitly configured otherwise. This architecture ensures that potentially destructive operations require human verification while maintaining developer productivity through configurable automation.

## Permission Hierarchy and Evaluation Order

Every tool invocation in Reasonix traverses a strict evaluation sequence defined in `site/src/pages/docs.astro`. The system processes permissions in the following order: **deny → ask → allow → fallback**.

Read-only tools typically pass automatically, but write-capable tools—including Bash—respect the configured `[permissions]` mode. The default posture is `ask`, which triggers an interactive prompt before executing any Bash command that modifies the system.

When evaluating a command, Reasonix checks explicit deny lists first, followed by allow lists. If neither list matches, the system falls back to the global mode setting. This hierarchy ensures that dangerous patterns like `rm -rf` are blocked immediately, regardless of broader permission settings.

## Explicit Deny and Allow Lists

The [`opencode.json`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/opencode.json) file at the repository root defines global permission defaults and per-tool regex patterns. Administrators can specify wildcard denials (`"*": "deny"`) alongside granular Bash-specific rules.

The configuration uses regex patterns to match command strings. For example, the following rules demonstrate typical security boundaries:

```toml

# ~/.reasonix/config.toml

[permissions]
mode = "ask"
deny = ["Bash(rm -rf*)", "Bash(git push*)"]
allow = ["Bash(go test:*)"]

```

Entries like `Bash(rm -rf*)` prevent recursive deletion operations, while `Bash(go test:*)` permits testing workflows without manual approval. These patterns are evaluated against the raw command string before execution, providing deterministic control over shell access.

## Dynamic Bash Opt-In for Indirect Execution

By default, Bash commands executed indirectly—such as those spawned by other tools—follow the standard permission flow. Setting `allow_dynamic_bash = true` in the `[permissions]` section modifies this behavior to permit indirect Bash execution when the global mode is set to `allow`.

As documented in `site/src/pages/docs.astro`, this opt-in prevents accidental shell escapes through tool chains while enabling sophisticated automation workflows. Without this flag, even indirect Bash invocations respect the deny/ask/allow hierarchy, ensuring that write operations cannot bypass user consent through intermediary tools.

## Sandboxing Architecture and Filesystem Restrictions

### Workspace Isolation and Path Resolution

All file-writing tools, including Bash when spawning subshells, must operate within the configured `[sandbox] workspace_root`. By default, this resolves to the current working directory. The sandbox implementation resolves symlinks and normalizes `..` path segments to prevent directory traversal attacks.

The configuration supports explicit read and write restrictions:

```toml
[sandbox]
workspace_root = ""                  # Empty string defaults to current directory

allow_write = ["/tmp"]               # Writable paths inside the sandbox

forbid_read = ["${HOME}/.ssh"]       # Paths blocked from read access

```

### OS-Level Sandbox Enforcement

Reasonix supports mandatory OS-level isolation through the `bash` configuration option, which accepts `"enforce"` or `"off"`. When set to `"enforce"` and a compatible backend is present—Seatbelt on macOS or bubblewrap on Linux—Bash commands execute within a restricted environment isolated from the host filesystem.

If enforcement is enabled but no sandbox backend is available, Reasonix rejects the Bash command rather than executing it unconfined. This fail-closed behavior, described in `site/src/pages/docs.astro`, prevents accidental exposure of sensitive system resources when security dependencies are missing.

## Headless Execution Safety Controls

The `reasonix run` command defaults to the *Ask* posture for all write-capable operations. In headless or CI environments, Bash commands will fail closed unless explicitly authorized via command-line flags.

To enable automated execution, supply one of the following options:

```bash

# Auto-approve safe commands in headless mode

reasonix run -y "go test ./..."

# Or use the explicit permission mode flag

reasonix run --permission-mode auto "build_script.sh"

```

Without these flags, any Bash invocation requiring write access terminates with a permission error rather than hanging indefinitely for user input. This design ensures that unattended runs cannot invoke destructive shell commands without explicit configuration.

## Summary

- **Hierarchical evaluation**: Reasonix processes permissions as deny → ask → allow → fallback, with Bash defaulting to the `ask` mode unless explicitly configured.
- **Regex-based ACLs**: The [`opencode.json`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/opencode.json) and [`config.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/config.toml) files support pattern-based deny and allow lists for precise command filtering.
- **Indirect execution control**: The `allow_dynamic_bash` setting governs whether indirect Bash calls (from other tools) respect the `allow` mode or require explicit approval.
- **Filesystem sandboxing**: The `workspace_root` parameter confines all write operations, with symlink resolution and path normalization preventing directory escape.
- **OS-level isolation**: Setting `bash = "enforce"` requires Seatbelt (macOS) or bubblewrap (Linux); commands fail rather than run unconfined if backends are unavailable.
- **Headless safety**: `reasonix run` defaults to interactive approval; automated workflows require `-y`, `--auto`, or `--permission-mode auto` to proceed.

## Frequently Asked Questions

### How does Reasonix determine whether to prompt for Bash command approval?

Reasonix evaluates every Bash command against the permission hierarchy defined in `site/src/pages/docs.astro`. First, it checks explicit deny lists (blocking matches immediately), then allow lists (auto-approving matches). If no pattern matches, it falls back to the global `mode` setting—defaulting to `ask`, which triggers an interactive prompt before execution.

### What configuration files control Bash permissions and sandboxing?

Permissions are defined in [`opencode.json`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/opencode.json) at the repository level for global defaults, and in `~/.reasonix/config.toml` or project-local [`reasonix.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/reasonix.toml) for runtime settings. The `[permissions]` section controls approval modes and regex patterns, while the `[sandbox]` section defines `workspace_root` and path restrictions. OS-level enforcement is toggled via the `[tools] bash` setting.

### Can Reasonix block Bash commands executed indirectly by other tools?

Yes. Without `allow_dynamic_bash = true` in the `[permissions]` section, Bash commands spawned indirectly (e.g., by another tool invoking a shell) still traverse the deny/ask/allow hierarchy. Enabling this setting allows the `allow` mode to cover indirect execution, while `deny` rules remain enforced regardless of this flag.

### What happens if the OS-level sandbox backend is unavailable?

When `bash = "enforce"` is configured but Reasonix cannot detect Seatbelt (macOS) or bubblewrap (Linux), the system rejects the Bash command entirely rather than executing it without sandboxing. This fail-closed behavior ensures that security policies are never silently degraded due to missing dependencies.