# How the Apache Maka Sandbox Boundary Controls File‑Write Operations for Tools

> Learn how Apache Maka's sandbox boundary controls tool file writes using explicit declarations, validation, and runtime path matching for secure filesystem access.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: internals
- Published: 2026-08-25

---

**Apache Maka isolates tool execution behind a permission‑profile sandbox boundary that requires explicit declarations for filesystem access, validates requests against hard constraints and explicit deny rules, and enforces write permissions at runtime through path‑matching checks.**

Apache Maka isolates the actions of tools—such as file‑writing utilities and web‑fetch agents—behind a strict **sandbox boundary** that governs all file‑write operations. This boundary ensures that tools can only access filesystem paths explicitly granted through an additive permission expansion. According to the Apache Maka source code in [`packages/core/src/sandbox-boundary.ts`](https://github.com/apache/maka/blob/main/packages/core/src/sandbox-boundary.ts), the boundary implementation spans validation, conflict detection, and runtime enforcement layers.

## Understanding the Sandbox Boundary Architecture

The sandbox boundary is implemented as a **permission profile** that describes which filesystem paths a tool may read or write and whether network access is permitted. Tools cannot write files by default; they must request a **sandbox boundary expansion** that lists additional filesystem entries (path, access level, and scope) required for their operation.

### The Permission Profile Foundation

At the core of the system is the `SandboxBoundaryExpansion` type defined in [`packages/core/src/sandbox-boundary.ts`](https://github.com/apache/maka/blob/main/packages/core/src/sandbox-boundary.ts) (lines 59‑66). This structure allows a tool to declare its need for additional filesystem entries and optional network enablement. Each expansion request must conform to strict validation rules before the system merges it into the existing `SandboxProfile`.

## Step‑by‑Step: How Tools Request File‑Write Access

The workflow for granting write access follows a deterministic, auditable pipeline that prevents privilege escalation.

### 1. Declaring a Sandbox Boundary Expansion

A tool initiates the process by constructing an expansion object that specifies the target path, access type (`read` or `write`), and scope (`exact` or `subtree`). For example, a tool wanting to write to [`/tmp/output.txt`](https://github.com/apache/maka/blob/main//tmp/output.txt) must include this path with `access: 'write'` in its expansion request.

### 2. Validating Expansion Constraints

Before processing, the system invokes `validateSandboxBoundaryExpansion` (lines 13‑52 of [`sandbox-boundary.ts`](https://github.com/apache/maka/blob/main/sandbox-boundary.ts)) to verify the payload is well‑formed. This validation enforces hard limits:

- **Maximum 32 entries** per expansion
- **Maximum 4 KB** per path length
- **Maximum 64 KB** total expansion size

Errors are reported through a typed `SandboxBoundaryExpansionValidationResult`, ensuring the system rejects malformed or oversized requests before they reach the permission profile.

### 3. Detecting Conflicts with Explicit Denies

The function `assessSandboxBoundaryExpansion` checks for policy violations by running `expansionConflictsWithExplicitDeny` (lines 33‑42 and 54‑61). This step ensures the expansion never weakens an existing **explicit deny** entry or violates a **protected‑metadata** policy (such as `.git` directories). If a conflict is detected, the expansion is rejected, preserving the principle that explicit denies always dominate.

### 4. Applying and Compacting Permissions

If validation passes and no conflicts exist, `applySandboxBoundaryExpansion` merges the new entries into the existing `SandboxProfile`. The merge process first compacts overlapping entries via `compactSandboxBoundaryFilesystemEntries` (lines 53‑67) to optimize the profile size and prevent redundant permission checks.

## Runtime Enforcement of Write Permissions

Once the expansion is applied, the runtime enforces the boundary during tool execution.

### Execution Boundaries and Display Modes

The resulting `ExecutionBoundary` (managed, bypass, or external) is stored with a revision number. The boundary is presented to the UI through `executionBoundaryDisplayMode` (lines 176‑226 of [`sandbox-boundary.ts`](https://github.com/apache/maka/blob/main/sandbox-boundary.ts)), which maps the internal profile to user‑facing modes such as **explore** (read‑only) or **ask** (writable). This abstraction allows users to understand tool permissions without parsing raw path lists.

### Path‑Level Access Control

When a tool attempts to write a file, the runtime checks the current execution boundary using `sandboxBoundaryExpansionAllowsPath` (lines 70‑81). The helper `canWritePath`—re‑exported from [`packages/core/src/permission-profile.ts`](https://github.com/apache/maka/blob/main/packages/core/src/permission-profile.ts)—returns `true` only when the target path is covered by a *write* entry whose scope matches (exact or subtree) and no explicit deny blocks it.

## Practical Code Example: Requesting Write Access

The following TypeScript implementation demonstrates the complete workflow from declaration to enforcement:

```typescript
import {
  createReadOnlyPermissionProfile,
  canWritePath,
  PermissionProfileManaged,
} from '../permission-profile.js';
import {
  validateSandboxBoundaryExpansion,
  assessSandboxBoundaryExpansion,
  applySandboxBoundaryExpansion,
} from '../sandbox-boundary.js';

// 1️⃣  A tool wants to write to /tmp/output.txt
const expansion = {
  filesystem: [{ path: '/tmp/output.txt', access: 'write', scope: 'exact' }],
};

// 2️⃣  Validate the shape
const validation = validateSandboxBoundaryExpansion(expansion);
if (!validation.ok) {
  throw new Error(`Bad expansion: ${validation.reason} – ${validation.message}`);
}

// 3️⃣  Assess against the current profile (read‑only sandbox)
const baseProfile: PermissionProfileManaged = createReadOnlyPermissionProfile();
const assessment = assessSandboxBoundaryExpansion(baseProfile, validation.expansion);
if (assessment.outcome === 'conflict') {
  throw new Error('Expansion conflicts with an explicit deny');
}

// 4️⃣  Apply the expansion (if needed)
const newProfile =
  assessment.outcome === 'apply'
    ? assessment.profile
    : baseProfile; // noop case

// 5️⃣  Enforce the write
console.log(
  canWritePath(newProfile, '/tmp/output.txt')
    ? 'Write allowed'
    : 'Write denied',
);

```

This pattern is validated in the unit test `distinguishes a new expansion, an approved no‑op, and an explicit‑deny conflict` (lines 58‑90 of [`packages/core/src/__tests__/sandbox-boundary.test.ts`](https://github.com/apache/maka/blob/main/packages/core/src/__tests__/sandbox-boundary.test.ts)).

## Summary

- **Additive permissions only**: The Apache Maka sandbox boundary only allows tools to add permissions through expansions; they cannot remove or weaken existing grants.
- **Explicit denies dominate**: Any deny entry in the permission profile blocks write access regardless of subsequent expansion requests.
- **Protected metadata safeguards**: Entries matching protected metadata (e.g., `.git` directories) cannot receive write access unless explicitly permitted by the base profile.
- **Hard validation limits**: Expansions are constrained to 32 entries, 4 KB path lengths, and 64 KB total size to prevent resource exhaustion.
- **Runtime enforcement**: The `canWritePath` function in [`permission-profile.ts`](https://github.com/apache/maka/blob/main/permission-profile.ts) performs the final authorization check using the merged `ExecutionBoundary` managed by the runtime in [`packages/runtime/src/tool-runtime.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/tool-runtime.ts).

## Frequently Asked Questions

### What happens if a tool tries to write to a path outside its sandbox boundary?

The write operation is blocked. The runtime invokes `sandboxBoundaryExpansionAllowsPath` (lines 70‑81 of [`sandbox-boundary.ts`](https://github.com/apache/maka/blob/main/sandbox-boundary.ts)) and `canWritePath` from [`permission-profile.ts`](https://github.com/apache/maka/blob/main/permission-profile.ts) to verify coverage. If the path is not included in a write‑enabled entry, the function returns `false` and the tool receives a permission denial.

### Can a tool request write access to system directories like `/etc` or `.git` folders?

No, unless explicitly permitted by the base profile. The `expansionConflictsWithExplicitDeny` check (lines 33‑42) prevents expansions from overriding protected‑metadata policies. Attempting to expand into protected directories results in a conflict outcome, rejecting the expansion before it modifies the profile.

### What are the size limits for a sandbox boundary expansion request?

Apache Maka enforces three hard limits during validation: a maximum of **32 filesystem entries**, a maximum **4 KB length** for any individual path, and a maximum **64 KB total size** for the entire expansion payload. These constraints prevent malformed tools from submitting oversized permission requests that could degrade performance or exhaust memory.

### How does the runtime know which permission profile to enforce for a tool?

The runtime loads the current `ExecutionBoundary` for the tool from [`packages/runtime/src/tool-runtime.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/tool-runtime.ts). This boundary includes a revision number and references the active `SandboxProfile`. Before performing file I/O, the runtime checks this boundary using `sandboxBoundaryExpansionAllowsPath` to determine if the requested operation is permitted.