# Permission Modes in Craft Agents: Safe, Ask, and Allow-All Explained

> Discover Craft Agents permission modes: Safe, Ask, and Allow-All. Learn how the PermissionManager enforces granular control over tool execution for enhanced agent security.

- Repository: [Craft Ai Agents/craft-agents-oss](https://github.com/craft-ai-agents/craft-agents-oss)
- Tags: deep-dive
- Published: 2026-07-06

---

**Craft Agents provide three permission modes—Safe (Explore), Ask (Ask to Edit), and Allow-All (Execute)—that enforce granular control over tool execution through the `PermissionManager` class in [`packages/shared/src/agent/core/permission-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/core/permission-manager.ts).**

The `craft-ai-agents/craft-agents-oss` repository implements a robust permission system that governs how AI agents interact with bash commands, file systems, and APIs. Understanding these **permission modes** is essential for deploying agents securely across exploratory, interactive, and automated workflows.

## The Three Permission Modes: Safe, Ask, and Allow-All

Craft Agents map internal keys to user-facing canonical names in [`packages/shared/src/agent/mode-types.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/mode-types.ts). Each mode determines whether the agent can write to the filesystem, execute arbitrary commands, or access external APIs without supervision.

### Safe Mode (Explore)

**Safe mode** operates as a read-only sandbox where all write-type tools are blocked. When running in `safe` (internally keyed as `'safe'`, displayed as **Explore**), the agent cannot modify files, execute destructive bash commands, or push to git repositories. The system evaluates tool calls against a whitelist defined in the permissions JSON, rejecting any operation that could alter system state.

### Ask Mode (Ask to Edit)

**Ask mode** enables full tool functionality while requiring user confirmation for high-risk operations. Internally keyed as `'ask'` and displayed as **Ask to Edit**, this mode allows the agent to propose dangerous actions—such as `rm`, `sudo`, or `git push`—but surfaces these requests to the user for explicit approval before execution. The `PermissionManager` identifies dangerous commands using a hard-coded `DANGEROUS_COMMANDS` set in [`permission-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/permission-manager.ts).

### Allow-All Mode (Execute)

**Allow-all mode** grants unrestricted autonomous execution for fully automated workflows. Internally keyed as `'allow-all'` and displayed as **Execute**, this mode bypasses all permission checks and dangerous-command detection. When `allow-all` is active, `shouldAllowToolInMode` returns `allowed: true` immediately, enabling the agent to run without prompts or whitelisting constraints.

## How Permission Enforcement Works in Craft Agents

Permission enforcement follows a centralized evaluation pipeline that checks the current session mode before allowing tool execution.

### Mode Evaluation and Policy Logic

The enforcement entry point is `PermissionManager.evaluateToolCall(toolName, toolInput)` in [`packages/shared/src/agent/core/permission-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/core/permission-manager.ts). This method retrieves the active mode via `getPermissionMode(sessionId)` and delegates the policy decision to `shouldAllowToolInMode(toolName, toolInput, mode, ...)` located in [`packages/shared/src/agent/mode-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/mode-manager.ts).

According to the source code in [`mode-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/mode-manager.ts), the policy logic behaves as follows:

- **In `allow-all` mode**: All tools return `allowed: true` immediately.
- **In `ask` mode**: Tools return `allowed: true` but may set `requiresPermission: true` for commands matching the dangerous-command list.
- **In `safe` mode**: Tools are blocked unless they match a read-only whitelist defined in `PermissionsConfigCache`.

### Dangerous Command Detection

The system maintains a hard-coded `DANGEROUS_COMMANDS` set in [`packages/shared/src/agent/core/permission-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/core/permission-manager.ts) that guarantees high-risk bash commands always require explicit user approval in `ask` mode. When `PermissionManager.checkBashCommand()` detects a dangerous pattern, it uses `getBashRejectionReason` and `formatBashRejectionMessage` to produce detailed error messages explaining why the command was blocked or requires confirmation.

### Session-Scoped Whitelisting

Users can permanently approve specific commands or network domains for the duration of a session. The `PermissionManager` records these decisions in `alwaysAllowedCommands` and `alwaysAllowedDomains`, which bypass standard checks for subsequent invocations. Call `permMgr.whitelistCommand('curl')` to add a command to the session whitelist, or rely on the UI's "Always Allow" button to populate these sets automatically.

## Programmatically Managing Permission Modes

Developers can interact with the permission system directly through the TypeScript API exposed in [`packages/shared/src/agent/mode-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/mode-manager.ts) and [`packages/shared/src/agent/core/permission-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/core/permission-manager.ts).

### Switching Session Modes

Change the active permission mode for a specific session using `setPermissionMode`:

```typescript
import { setPermissionMode } from '@/shared/agent/mode-manager';
import { SESSION_ID } from './constants';

setPermissionMode(SESSION_ID, 'ask');

```

This updates the stored mode value, and the UI reflects the change via the `displayName` and `shortName` fields defined in `PERMISSION_MODE_CONFIG` in [`mode-types.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/mode-types.ts).

### Cycling Through Available Modes

To rotate through permission modes programmatically, use `cyclePermissionMode` which walks `PERMISSION_MODE_ORDER = ['safe','ask','allow-all']`:

```typescript
import { cyclePermissionMode } from '@/shared/agent/mode-manager';

cyclePermissionMode(SESSION_ID); // Rotates: safe → ask → allow-all

```

### Evaluating Tool Calls

Instantiate `PermissionManager` to evaluate specific tool calls against current permissions:

```typescript
import { PermissionManager } from '@/shared/agent/core/permission-manager';

const permMgr = new PermissionManager({
  sessionId: SESSION_ID,
  workspaceId: WORKSPACE_ID,
  workingDirectory: '/home/user/project',
  plansFolderPath: '/home/user/project/.craft/plans',
});

const result = permMgr.evaluateToolCall('Bash', { command: 'git status' });

if (!result.allowed) {
  console.error('Blocked:', result.reason);
} else if (result.requiresPermission) {
  // Show a prompt to the user before proceeding
}

```

### Whitelisting Commands

Add commands to the session whitelist to bypass future permission checks:

```typescript
permMgr.whitelistCommand('curl'); // Always allow for subsequent curl invocations

```

### Checking Bash Commands in Safe Mode

Validate specific bash commands before execution:

```typescript
permMgr.setPermissionMode('safe');
const rejectMsg = permMgr.checkBashCommand('rm -rf /tmp');
if (rejectMsg) {
  console.log('Rejected:', rejectMsg);
}

```

## Summary

- **Craft Agents** implement three permission modes—`safe` (Explore), `ask` (Ask to Edit), and `allow-all` (Execute)—defined in [`packages/shared/src/agent/mode-types.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/mode-types.ts).
- **Permission enforcement** flows through `PermissionManager.evaluateToolCall()` in [`packages/shared/src/agent/core/permission-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/core/permission-manager.ts), which delegates to `shouldAllowToolInMode()` in [`mode-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/mode-manager.ts).
- **Safe mode** blocks all write operations and restricts tools to a read-only whitelist.
- **Ask mode** allows all tools but requires user confirmation for commands listed in `DANGEROUS_COMMANDS`.
- **Allow-all mode** bypasses all checks, enabling fully autonomous agent execution.
- **Session whitelisting** via `alwaysAllowedCommands` and `alwaysAllowedDomains` persists user approvals for the duration of the session.

## Frequently Asked Questions

### How do I programmatically change the permission mode in Craft Agents?

Import `setPermissionMode` from [`packages/shared/src/agent/mode-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/mode-manager.ts) and call it with the session ID and desired mode key (`'safe'`, `'ask'`, or `'allow-all'`). The function updates the session state and triggers UI updates through the `PERMISSION_MODE_CONFIG` mapping.

### What is the difference between Safe mode and Ask mode in Craft Agents?

Safe mode operates as a read-only sandbox where write operations are blocked entirely, while Ask mode permits write operations but requires explicit user confirmation for commands identified as dangerous in the `DANGEROUS_COMMANDS` set. Safe mode never prompts the user; Ask mode may prompt depending on the tool being invoked.

### Where is the dangerous command list defined in the Craft Agents source code?

The `DANGEROUS_COMMANDS` set is defined in [`packages/shared/src/agent/core/permission-manager.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/core/permission-manager.ts). This hard-coded list ensures that commands like `rm`, `sudo`, and `git push` always trigger permission requests in Ask mode, regardless of any custom whitelist configurations.

### Can I whitelist specific commands for an entire session in Craft Agents?

Yes. The `PermissionManager` class provides `whitelistCommand()` and `whitelistDomain()` methods that add entries to `alwaysAllowedCommands` and `alwaysAllowedDomains` respectively. These session-scoped sets bypass standard permission checks for subsequent tool calls, effectively creating a temporary "always allow" policy for approved commands.