Skip to main content
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.

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?
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.

Security Modes (ExecSecurity)

ModeBehaviorUse Case
denyBlock all commands. No shell access whatsoever.Default. Maximum safety for untrusted agents.
allowlistOnly commands matching an allowlist entry may execute. Everything else is blocked.Production agents with known tool requirements.
fullAll commands are permitted without restriction.Development only. Never use in production.
The default security mode is deny. Agents cannot run any commands until the operator explicitly configures their permissions.

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:
ModeBehaviorUse Case
offNever prompt. Unmatched commands are handled by askFallback (default: deny).Fully automated environments.
on-missPrompt 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.
alwaysPrompt the operator for every command, even if it matches the allowlist.High-security environments requiring explicit approval for each execution.
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.

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

1

Parse command

The command string is parsed to extract the first token (the executable)
2

Resolve path

The executable is resolved against $PATH to find its absolute filesystem path
3

Test allowlist

Each allowlist pattern is tested against the resolved path using case-insensitive glob matching
4

Platform normalization

On Windows, paths are normalized (backslashes to forward slashes) and real paths are resolved for symlink-safe matching
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:
const DEFAULT_SAFE_BINS = [
  "jq", "grep", "cut", "sort", "uniq",
  "head", "tail", "tr", "wc"
];
These are not automatically allowed — they must still be in the allowlist — but they serve as a reference for operators building initial configurations.

Per-Agent Configuration

Exec approvals support per-agent policies. Each agent can have its own security mode, ask mode, and allowlist:
{
  "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.
If the socket is unavailable (daemon not running, network issue), the system falls back to the askFallback security mode (default: deny).

Command Analysis

Before approval checks, commands undergo structural analysis:
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:
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:
{
  "approvals": {
    "security": "allowlist",
    "ask": "on-miss",
    "askFallback": "deny"
  }
}
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.

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

FileDescription
src/infra/exec-approvals.tsCore approval engine (1,509 LOC)
src/gateway/server-methods/exec-approvals.tsGateway handlers for approval CRUD
src/gateway/server-methods/exec-approval.tsGateway handlers for request/resolve flow
~/.argentos/exec-approvals.jsonPersistent 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.