# How the OS-Level Sandbox Works in Claude Code Telegram: sandbox_enabled and sandbox_excluded_commands Explained

> Explore the OS-level sandbox in Claude Code Telegram. Understand how sandbox_enabled and sandbox_excluded_commands control command execution and system access for enhanced security.

- Repository: [Richard A/claude-code-telegram](https://github.com/richardatct/claude-code-telegram)
- Tags: internals
- Published: 2026-02-20

---

**The OS-level sandbox confines Bash commands to the `APPROVED_DIRECTORY` using the `sandbox_enabled` setting, while `sandbox_excluded_commands` designates specific tools like `git` and `npm` to run directly on the host OS with full system access.**

The `claude-code-telegram` bot implements a defense-in-depth security model that isolates file-system operations through OS-level sandboxing. This mechanism is controlled by two configuration fields in [`src/config/settings.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/settings.py) that determine whether Bash tools run in a restricted environment or with unrestricted host access. Understanding the interaction between `sandbox_enabled` and `sandbox_excluded_commands` is essential for securing deployments while accommodating tools that require system-wide visibility.

## Where Sandbox Settings Are Defined

The security configuration resides in [`src/config/settings.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/settings.py), where Pydantic fields declare the sandbox behavior:

```python
sandbox_enabled: bool = Field(
    True,
    description="Enable OS-level bash sandboxing for approved dir",
)
sandbox_excluded_commands: Optional[List[str]] = Field(
    default=["git", "npm", "pip", "poetry", "make", "docker"],
    description="Commands that run outside the sandbox (need system access)",
)

```

*Source:* lines 114-120 [[settings.py]](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/settings.py#L114-L120)

When **sandbox_enabled** is `True`, the system activates OS-level isolation for all Bash commands. The **sandbox_excluded_commands** list identifies command names that bypass these restrictions, defaulting to common development utilities that require access to global configuration files and system-wide package repositories.

## How the Sandbox Is Applied to Claude SDK Requests

The configuration propagates from settings into the Claude runtime via [`src/claude/sdk_integration.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/sdk_integration.py). The `ClaudeSDKManager` constructs a `ClaudeAgentOptions` object that embeds the sandbox dictionary:

```python
options = ClaudeAgentOptions(
    ...,
    sandbox={
        "enabled": self.config.sandbox_enabled,
        "autoAllowBashIfSandboxed": True,
        "excludedCommands": self.config.sandbox_excluded_commands or [],
    },
    ...
)

```

*Source:* lines 176-182 [[sdk_integration.py]](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/sdk_integration.py#L176-L182)

This dictionary instructs the Claude Code runtime to wrap Bash tools in a restricted environment when `enabled` is `True`. The `excludedCommands` array ensures listed tools execute directly on the host OS without directory boundary checks. Even when `sandbox_enabled` is `False`, the SDK receives the sandbox configuration with `"enabled": False`, effectively disabling isolation.

Unit tests in [`tests/unit/test_claude/test_sdk_integration.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/tests/unit/test_claude/test_sdk_integration.py) verify this propagation, ensuring the `ClaudeAgentOptions.sandbox` dict receives the correct flags and excluded commands (lines 271-307).

## Runtime Enforcement and Directory Boundary Checks

Beyond the SDK-level sandbox, [`src/claude/monitor.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/monitor.py) implements secondary validation through the `check_bash_directory_boundary` function. This Python-based defense parses Bash commands and validates file-system operations remain within the `approved_directory`:

1. **Parse** the command with `shlex.split`
2. **Identify** the base command (`mkdir`, `rm`, etc.)
3. **Skip** read-only commands that do not modify the file system
4. **For filesystem-modifying commands**, resolve each path against the current working directory
5. **Reject** any path that resolves outside the absolute `approved_directory` using `Path.relative_to`

*Source:* `check_bash_directory_boundary` lines 70-130 [[monitor.py]](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/monitor.py#L70-L130)

The monitor validates Bash tool calls when the bot operates in **classic (non-agentic) mode**:

```python
if tool_name in ["bash", "shell", "Bash"] and not self.agentic_mode:
    valid, error = check_bash_directory_boundary(
        command, working_directory, self.config.approved_directory
    )

```

*Source:* lines 240-292 [[monitor.py]](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/monitor.py#L240-L292)

In **agentic mode** (`AGENTIC_MODE=true`), the monitor skips these checks because Claude Code's native OS sandbox handles enforcement at the system level. The test suite in [`tests/unit/test_claude/test_monitor.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/tests/unit/test_claude/test_monitor.py) validates this behavior, including handling of malformed quoting and dangerous patterns (line 113).

## Implications of sandbox_enabled versus sandbox_excluded_commands

Understanding the distinction between these two settings is critical for secure deployment:

**sandbox_enabled**
- Controls the global OS-level sandbox state for all Bash tools
- When `True`: Commands run in a restricted environment confined to `APPROVED_DIRECTORY`
- When `False`: Commands execute with full host access, bypassing both SDK sandboxing and monitor directory checks (dangerous for production)

**sandbox_excluded_commands**
- Specifies command names that execute outside the sandbox even when `sandbox_enabled` is `True`
- Default entries include `git`, `npm`, `pip`, `poetry`, `make`, and `docker`
- Commands in this list bypass `check_bash_directory_boundary` but remain subject to tool name validation unless `DISABLE_TOOL_VALIDATION` is set

If a command appears in `sandbox_excluded_commands`, it receives direct host execution without directory isolation. However, the monitor still validates the command name against allow-lists unless tool validation is explicitly disabled via environment variables.

## Practical Configuration Example

To configure a secure environment that allows version control but restricts file modifications:

```python

# src/config/settings.py

sandbox_enabled: bool = Field(
    True,  # Maintain OS-level isolation

    description="Enable OS-level bash sandboxing for approved dir",
)
sandbox_excluded_commands: Optional[List[str]] = Field(
    default=["git", "npm"],  # Allow system-wide operations

    description="Commands that run outside the sandbox",
)

```

When executing through `ClaudeSDKManager`:

```python
from src.config.settings import Settings
from src.claude.sdk_integration import ClaudeSDKManager
from pathlib import Path

cfg = Settings()  # sandbox_enabled=True, excluded=["git", "npm"]

sdk = ClaudeSDKManager(config=cfg)

# git runs unsandboxed; mkdir runs sandboxed

response = await sdk.execute_command(
    prompt="git status && mkdir new_folder",
    working_directory=Path("/app/projects"),
)

```

In this execution, `git status` operates with full system access while `mkdir` is confined to the approved directory. Setting `sandbox_enabled = False` would remove all protections, exposing the host file system to arbitrary modifications.

## Summary

- The **OS-level sandbox** is configured in [`src/config/settings.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/config/settings.py) through `sandbox_enabled` and `sandbox_excluded_commands`
- **sandbox_enabled** activates SDK-level isolation for Bash commands, restricting file access to `APPROVED_DIRECTORY`
- **sandbox_excluded_commands** allows specific tools to bypass sandbox restrictions and run directly on the host OS
- The Claude SDK receives these settings via `ClaudeAgentOptions` in [`src/claude/sdk_integration.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/sdk_integration.py)
- Secondary validation occurs in [`src/claude/monitor.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/monitor.py) through `check_bash_directory_boundary` for non-agentic mode
- Excluded commands bypass directory boundary checks but remain subject to tool validation unless disabled

## Frequently Asked Questions

### What happens if I set sandbox_enabled to False?

Setting `sandbox_enabled` to `False` disables the OS-level sandbox entirely. The `ClaudeAgentOptions` still transmits the configuration with `"enabled": False`, but no isolation occurs. Bash commands execute with full host file system access, bypassing both the SDK sandbox wrapping and the directory boundary checks in [`monitor.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/monitor.py). This configuration is not recommended for production deployments as it removes the primary security boundary protecting the host from unintended file modifications.

### Why are git and npm excluded from the sandbox by default?

These commands require system-wide access to function properly. Git accesses global configuration files and multiple repository locations, while package managers like `npm` and `pip` install dependencies across the system. Confining these tools to `APPROVED_DIRECTORY` would prevent normal operation. The `sandbox_excluded_commands` list ensures these trusted utilities can access the entire file system while maintaining restrictions on potentially dangerous commands like `rm` or `curl`.

### Does monitor.py validation apply to excluded commands?

No. Commands listed in `sandbox_excluded_commands` bypass the `check_bash_directory_boundary` validation in [`src/claude/monitor.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/claude/monitor.py). However, they remain subject to tool name validation against allow-lists and disallowed patterns unless you set `DISABLE_TOOL_VALIDATION` in the environment. This means excluded commands receive direct host execution without directory boundary checks but still undergo basic command validation.

### How does agentic mode affect sandbox behavior?

When running in agentic mode (`AGENTIC_MODE=true`), the bot skips the [`monitor.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/monitor.py) directory boundary checks because Claude Code's native OS sandbox handles enforcement at the system level. The SDK still respects the `sandbox_enabled` and `sandbox_excluded_commands` settings passed via `ClaudeAgentOptions`, but the secondary Python-based validation in [`monitor.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/monitor.py) is not invoked. This delegation relies on Claude Code's built-in sandbox to catch malicious commands that might escape directory boundaries.