# How Permission Profiles Define Access Controls in Apache Maka

> Learn how Apache Maka's PermissionProfile defines filesystem, network, and environment access controls. Understand how it creates runtime sandbox policies.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: deep-dive
- Published: 2026-09-05

---

**PermissionProfile is the central TypeScript abstraction in Apache Maka that declaratively specifies filesystem, network, and environment access rights for tools, which are then compiled into platform-specific sandbox policies and enforced at runtime.**

Apache Maka uses **PermissionProfile** as its core mechanism for implementing least-privilege security. This article explains how profiles are defined, compiled, and enforced across Windows, macOS, and Linux based on the source code in `apache/maka`.

## What PermissionProfile Controls

A PermissionProfile governs three dimensions of access:

- **Filesystem access** — `read` and `write` glob patterns that specify which paths are accessible
- **Network access** — `network` flag set to `allow` or `deny` for outbound connections
- **Environment access** — `env` flag controlling visibility of environment variables (`full`, `read-only`, or `none`)

## Defining Permission Profiles in TypeScript

The `PermissionProfile` type is exported from [`permission-profile.ts`](https://github.com/apache/maka/blob/main/permission-profile.ts). The repository provides factory helpers for common use cases.

### Built-in Profile Factories

| Helper Function | Purpose |
|-----------------|---------|
| `createReadOnlyPermissionProfile()` | Read filesystem, no writes, no network |
| `createWorkspaceWritePermissionProfile()` | Read workspace, write to workspace, no network |
| `fullAccessProfile` | Unrestricted access (used sparingly) |

```typescript
import {
  createWorkspaceWritePermissionProfile,
  createReadOnlyPermissionProfile,
} from '@maka/core/permission-profile';

// Allow reading entire workspace, writing only to out/ directory
const writeProfile = {
  ...createWorkspaceWritePermissionProfile(),
  write: ['out/**'],
};

// Strict read-only: no writes, no network, minimal environment
const readOnlyProfile = createReadOnlyPermissionProfile();

```

## Compiling Profiles into Sandbox Policies

The [`permission-profile-compiler.ts`](https://github.com/apache/maka/blob/main/permission-profile-compiler.ts) module transforms declarative profiles into enforceable policies. According to the Maka source, this compilation performs three operations:

1. **Validation** — checks for duplicate entries and canonical paths
2. **Normalization** — resolves paths relative to the current working directory
3. **Platform compilation** — generates OS-specific policy formats

```typescript
import { compilePermissionProfile } from '@maka/core/permission-profile-compiler';

const compiled = compilePermissionProfile({
  mode: 'ask',
  cwd: '/workspace',
  profile: readOnlyProfile,
});

// Platform-specific policies
console.log(compiled.linuxSeccompPolicy);   // seccomp JSON string
console.log(compiled.macosSeatbeltProfile); // Seatbelt configuration
console.log(compiled.windowsSandboxPolicy); // Windows Sandbox XML

```

## Platform-Specific Enforcement Implementations

Maka implements sandbox enforcement differently per operating system:

- [`windows-profile.ts`](https://github.com/apache/maka/blob/main/windows-profile.ts) — Windows Sandbox policy generation
- [`macos-seatbelt.ts`](https://github.com/apache/maka/blob/main/macos-seatbelt.ts) — macOS Seatbelt sandbox profiles
- [`linux-sandbox.ts`](https://github.com/apache/maka/blob/main/linux-sandbox.ts) — Linux seccomp-bpf and namespaces

The [`sandbox-manager.ts`](https://github.com/apache/maka/blob/main/sandbox-manager.ts) module contains `profileRequiresSandbox()`, which determines whether a given profile can run in the host environment or needs isolation.

## Runtime Permission Checking

During tool execution, the filesystem worker in [`filesystem-worker/client.ts`](https://github.com/apache/maka/blob/main/filesystem-worker/client.ts) validates every operation against the active profile:

```typescript
// Pseudocode representing runtime checks in filesystem-worker/client.ts
if (!canReadPath(activeProfile, requestedPath)) {
  throw new PermissionDeniedError(`Read blocked: ${requestedPath}`);
}

if (!canWritePath(activeProfile, requestedPath)) {
  throw new PermissionDeniedError(`Write blocked: ${requestedPath}`);
}

```

Network calls are wrapped by `networkRestricted()`, which blocks outbound sockets when `profile.network === 'deny'`.

## Computing Effective Permission Profiles

In [`builtin-tools.ts`](https://github.com/apache/maka/blob/main/builtin-tools.ts), the `effectivePermissionProfile()` function merges explicit caller-supplied profiles with the global **permission-mode** (`ask`, `allow`, or `deny`). This produces the final profile used for compilation and enforcement.

```typescript
// Using a profile when spawning a tool
import { runTool } from '@maka/runtime';

await runTool({
  command: ['python', 'script.py'],
  cwd: '/workspace',
  permissionProfile: writeProfile,  // enforces declared constraints
});

```

## Summary

- **PermissionProfile** in [`permission-profile.ts`](https://github.com/apache/maka/blob/main/permission-profile.ts) declaratively specifies filesystem, network, and environment access controls
- Factory helpers like `createWorkspaceWritePermissionProfile()` provide sensible defaults for common security postures
- The **permission-profile-compiler** validates, normalizes, and compiles profiles into platform-specific policies
- Runtime enforcement occurs through [`filesystem-worker/client.ts`](https://github.com/apache/maka/blob/main/filesystem-worker/client.ts) checks and `networkRestricted()` wrappers
- Platform implementations in [`windows-profile.ts`](https://github.com/apache/maka/blob/main/windows-profile.ts), [`macos-seatbelt.ts`](https://github.com/apache/maka/blob/main/macos-seatbelt.ts), and [`linux-sandbox.ts`](https://github.com/apache/maka/blob/main/linux-sandbox.ts) translate profiles into OS-level sandbox constraints

## Frequently Asked Questions

### What happens if a tool requests access outside its PermissionProfile?

The filesystem worker in [`filesystem-worker/client.ts`](https://github.com/apache/maka/blob/main/filesystem-worker/client.ts) calls `canReadPath()` or `canWritePath()` before each operation. If the path doesn't match the profile's glob patterns, a `PermissionDeniedError` is thrown, blocking the operation.

### How does Maka choose between host execution and sandbox isolation?

The `profileRequiresSandbox()` function in [`sandbox-manager.ts`](https://github.com/apache/maka/blob/main/sandbox-manager.ts) analyzes the compiled profile. Profiles with `PermissionProfile.External` or minimal constraints may run on the host; stricter profiles trigger platform-specific sandbox instantiation.

### Can PermissionProfile settings override the global permission-mode?

No. Per [`builtin-tools.ts`](https://github.com/apache/maka/blob/main/builtin-tools.ts), `effectivePermissionProfile()` **merges** the explicit profile with the global mode (`ask`, `allow`, `deny`). The mode acts as a ceiling—if global mode is `deny`, even `allow` network settings in the profile are blocked.

### What's the difference between env: 'full' and env: 'read-only'?

`env: 'full'` grants read and write access to environment variables. `env: 'read-only'` allows inspection but prevents modification. `env: 'none'` provides an empty or scrubbed environment, used for untrusted external tools.