> ## Documentation Index
> Fetch the complete documentation index at: https://docs.argentos.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Exec Approvals

> Command-level gating that controls which shell commands agents can execute, with allowlists, IPC approval daemons, and per-agent policies.

<Info>
  **ArgentOS Business** -- This feature is part of ArgentOS Business. The architecture is documented here for all users, but full functionality requires a Business license. [Learn more about Business](/business).
</Info>

## Overview

Exec Approvals is the command-gating layer that sits between every agent tool invocation and the host operating system. Before any shell command runs -- whether triggered by the `bash` tool, a skill, or the execution worker -- it passes through the exec approvals system for validation.

The system answers one question: **Is this agent allowed to run this command on this machine?**

<Warning>
  This is critical because agents can execute arbitrary shell commands during task processing. Without gating, an agent could `rm -rf /`, install packages, or exfiltrate data. Exec approvals enforce a principle-of-least-privilege model where agents start with zero shell access and gain permissions through explicit operator configuration.
</Warning>

## Security Modes (ExecSecurity)

| Mode        | Behavior                                                                           | Use Case                                        |
| ----------- | ---------------------------------------------------------------------------------- | ----------------------------------------------- |
| `deny`      | Block all commands. No shell access whatsoever.                                    | Default. Maximum safety for untrusted agents.   |
| `allowlist` | Only commands matching an allowlist entry may execute. Everything else is blocked. | Production agents with known tool requirements. |
| `full`      | All commands are permitted without restriction.                                    | Development only. Never use in production.      |

<Danger>
  The default security mode is `deny`. Agents cannot run any commands until the operator explicitly configures their permissions.
</Danger>

## Ask Modes (ExecAsk)

The `ask` field controls what happens when a command does not match the allowlist. This only applies when `security` is set to `allowlist`:

| Mode      | Behavior                                                                                                                                                       | Use Case                                                                   |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `off`     | Never prompt. Unmatched commands are handled by `askFallback` (default: `deny`).                                                                               | Fully automated environments.                                              |
| `on-miss` | Prompt the operator via the IPC socket when a command is not in the allowlist. If approved, the command's path is auto-added to the allowlist for future runs. | Default. Learn-as-you-go pattern.                                          |
| `always`  | Prompt the operator for every command, even if it matches the allowlist.                                                                                       | High-security environments requiring explicit approval for each execution. |

<Tip>
  When `ask` is `on-miss` and the operator approves a command, the resolved executable path is automatically appended to the agent's allowlist. This creates a progressive learning model where the allowlist grows as the agent encounters new tools.
</Tip>

## Allowlist Pattern Matching

Each agent can have an allowlist of executable patterns. Entries support:

* **Absolute paths**: `/usr/bin/git`, `/opt/homebrew/bin/node`
* **Home-relative paths**: `~/bin/my-tool`
* **Glob patterns**: `/usr/bin/*`, `/opt/homebrew/bin/p*`
* **Double-star globs**: `/usr/local/**/python3`

### How Matching Works

<Steps>
  <Step title="Parse command">
    The command string is parsed to extract the first token (the executable)
  </Step>

  <Step title="Resolve path">
    The executable is resolved against `$PATH` to find its absolute filesystem path
  </Step>

  <Step title="Test allowlist">
    Each allowlist pattern is tested against the resolved path using case-insensitive glob matching
  </Step>

  <Step title="Platform normalization">
    On Windows, paths are normalized (backslashes to forward slashes) and real paths are resolved for symlink-safe matching
  </Step>
</Steps>

```typescript theme={null}
type ExecAllowlistEntry = {
  id?: string;          // Auto-generated UUID for tracking
  pattern: string;      // Glob pattern or absolute path
  lastUsedAt?: number;  // Timestamp of last match
  lastUsedCommand?: string;    // The full command that matched
  lastResolvedPath?: string;   // The resolved executable path
};
```

Each entry tracks usage metadata so operators can audit which patterns are actively used and prune stale entries.

### Default Safe Binaries

The system recognizes a set of safe binaries that are commonly needed by agent tools:

```typescript theme={null}
const DEFAULT_SAFE_BINS = [
  "jq", "grep", "cut", "sort", "uniq",
  "head", "tail", "tr", "wc"
];
```

<Note>
  These are not automatically allowed -- they must still be in the allowlist -- but they serve as a reference for operators building initial configurations.
</Note>

## Per-Agent Configuration

Exec approvals support per-agent policies. Each agent can have its own security mode, ask mode, and allowlist:

```json theme={null}
{
  "version": 1,
  "socket": {
    "path": "~/.argentos/exec-approvals.sock",
    "token": "auto-generated-base64url-token"
  },
  "defaults": {
    "security": "allowlist",
    "ask": "on-miss",
    "askFallback": "deny",
    "autoAllowSkills": false
  },
  "agents": {
    "main": {
      "security": "allowlist",
      "allowlist": [
        { "pattern": "/usr/bin/git" },
        { "pattern": "/opt/homebrew/bin/node" },
        { "pattern": "/usr/local/bin/pnpm" }
      ]
    },
    "research-agent": {
      "security": "deny"
    },
    "*": {
      "allowlist": [
        { "pattern": "/usr/bin/cat" },
        { "pattern": "/usr/bin/ls" }
      ]
    }
  }
}
```

### Resolution Order

1. Agent-specific settings override defaults.
2. Wildcard agent (`*`) entries provide a baseline for all agents.
3. Allowlists are merged: wildcard entries + agent-specific entries.
4. The `askFallback` determines what happens when the IPC daemon is unreachable or `ask` is `off`.

## IPC Socket Daemon

When `ask` is `on-miss` or `always`, approval requests are sent to an IPC socket daemon. This enables real-time operator interaction:

* **Socket path**: `~/.argentos/exec-approvals.sock` (configurable)
* **Authentication**: A random base64url token is generated on first run and stored in the config
* **Protocol**: JSON messages over Unix domain sockets

The daemon is started by the gateway process. When a command needs approval, the agent runtime sends a request to the socket and blocks until the operator responds.

<Info>
  If the socket is unavailable (daemon not running, network issue), the system falls back to the `askFallback` security mode (default: `deny`).
</Info>

## Command Analysis

Before approval checks, commands undergo structural analysis:

```typescript theme={null}
type ExecCommandAnalysis = {
  ok: boolean;           // Whether the command structure is valid
  reason?: string;       // Why analysis failed
  segments: ExecCommandSegment[];  // Parsed pipeline segments
  chains?: ExecCommandSegment[][];  // Segments grouped by chain operators
};
```

The analyzer handles:

* **Shell quoting**: Single quotes, double quotes, escape sequences
* **Pipeline splitting**: Commands piped with `|` are split into segments, each validated independently
* **Chain operators**: `&&`, `||`, `;` split commands into chains
* **Blocked tokens**: Redirections (`>`, `<`), backtick substitution, `$()` subshells, and newlines are rejected
* **Windows compatibility**: Platform-specific token validation

Each segment in a pipeline is resolved independently. All segments must pass allowlist matching for the full command to be approved.

## Hash Validation

The exec approvals config file includes a SHA-256 hash mechanism for integrity verification:

```typescript theme={null}
type ExecApprovalsSnapshot = {
  path: string;
  exists: boolean;
  raw: string | null;
  file: ExecApprovalsFile;
  hash: string;  // SHA-256 of the raw file content
};
```

This hash is used by the gateway to detect external modifications to the approvals file. When the hash changes between reads, the system reloads the configuration to pick up operator edits made outside the dashboard.

## Auto-Allow Skills

When `autoAllowSkills` is `true`, commands executed by installed skills (from the ArgentOS skill marketplace) are automatically approved without allowlist matching. This provides a convenience layer for trusted skill packages while maintaining control over ad-hoc commands.

Default: `false` -- skills must have their commands explicitly allowlisted.

## Configuration in argent.json

Exec approvals can also be configured through the main config file at `~/.argentos/argent.json` under the `approvals` key. These settings serve as default overrides:

```json theme={null}
{
  "approvals": {
    "security": "allowlist",
    "ask": "on-miss",
    "askFallback": "deny"
  }
}
```

<Note>
  The dedicated `~/.argentos/exec-approvals.json` file takes precedence for per-agent allowlists and socket configuration. The `argent.json` approvals section provides default security/ask modes that apply when the dedicated file does not specify them.
</Note>

## Dashboard Integration

The dashboard exposes exec approvals through the gateway API:

* `exec.approvals.get` -- Read current approvals configuration
* `exec.approvals.set` -- Update approvals configuration
* `exec.approvals.node.get` -- Read node-specific approvals
* `exec.approvals.node.set` -- Update node-specific approvals
* `exec.approval.request` -- Submit an approval request (from agent runtime)
* `exec.approval.resolve` -- Resolve a pending approval (from operator)

## Key Files

| File                                           | Description                               |
| ---------------------------------------------- | ----------------------------------------- |
| `src/infra/exec-approvals.ts`                  | Core approval engine (1,509 LOC)          |
| `src/gateway/server-methods/exec-approvals.ts` | Gateway handlers for approval CRUD        |
| `src/gateway/server-methods/exec-approval.ts`  | Gateway handlers for request/resolve flow |
| `~/.argentos/exec-approvals.json`              | Persistent approvals configuration        |

## Best Practices

1. **Start with `deny`** and gradually build allowlists as you discover which commands your agent needs.
2. **Use `on-miss`** during initial setup to learn the required commands, then switch to `off` once the allowlist is stable.
3. **Never use `full` security** in production. It defeats the entire purpose of command gating.
4. **Use absolute paths** in allowlists rather than bare command names to prevent PATH manipulation attacks.
5. **Audit `lastUsedAt`** timestamps periodically and remove stale entries.
6. **Keep the wildcard agent (`*`) allowlist minimal** -- it applies to every agent including newly created ones.
