Skip to main content

Permissions API

Manage permission requests for agent tool calls using a tiered classification system. Commands are classified at runtime into three tiers:
  • Safe — auto-approved (read-only operations like ls, cat, git status)
  • Dangerous — routed to the dashboard for user approval (code execution, network writes, git push)
  • Destructive — blocked by default (rm -rf /, DROP TABLE, terraform destroy)
This is Phase 1 of sandbox governance. Safe commands pass through automatically. Dangerous commands are queued for approval and can be reviewed in the dashboard. Destructive commands are blocked and require explicit user enablement via the dashboard.

List pending permission requests

Returns all pending permission requests for the authenticated user. You can optionally filter by agent. Requires bearer token authentication.

Query parameters

Response

Errors

Submit permission decision

Approve or reject a pending permission request. Requires bearer token authentication.

Request body

The approve_always decision approves the current request and is intended to auto-approve similar commands in the future. Auto-approval persistence is not yet implemented — currently approve_always behaves the same as approve.

Response

Response (backend)

The backend returns the decision along with the classification tier:

Response (web proxy)

The web proxy returns the decision without the tier:
The backend response includes a tier field indicating the classification tier of the resolved request. The web proxy does not include this field.

Errors

Command classification tiers

The classifier evaluates commands and tool calls against built-in pattern lists. Unknown commands default to the dangerous tier.

Safe tier (auto-approve)

Commands that are read-only or informational:

Dangerous tier (requires approval)

Commands that modify state or execute code:

Destructive tier (blocked by default)

Commands that can cause irreversible damage:

Tool call classification

In addition to shell commands, the classifier handles structured tool calls:

WebSocket real-time notifications

Instead of polling GET /api/permissions, you can connect via WebSocket to receive instant push notifications when a permission request is created. The WebSocket endpoint replaces the previous 5-second polling approach with real-time delivery.

Connection

Connect by passing your userId as a query parameter. On successful connection, the server sends a connected message:
If the userId parameter is missing, the server closes the connection with code 4001.

Server-to-client messages

Permission request example

Client-to-server messages

Decision example

The decision field accepts approve, reject, or approve_always. The approve_always option approves the current request and is intended to auto-approve similar commands in the future (see the REST endpoint for details).

Connection lifecycle

  • Heartbeat — the server sends a heartbeat every 30 seconds. If you do not receive a heartbeat within the expected interval, reconnect.
  • Cleanup — the server removes the client from its tracking map on disconnect. No explicit close handshake is required beyond the standard WebSocket close frame.
  • Multiple sessions — a single user can have multiple concurrent WebSocket connections. All sessions for a user receive the same permission_request broadcasts.
The REST API (GET /api/permissions and POST /api/permissions) remains fully supported. The WebSocket endpoint is an alternative real-time channel. If the WebSocket connection drops, you can fall back to polling the REST endpoint.

Pre-tool-use hook

The permission system integrates with Docker agent containers through a pre-tool-use hook. When an agent makes a tool call inside its container:
  1. The --hook-pre-tool-use flag triggers the hook script
  2. The hook script sends tool details to POST /api/hooks/classify
  3. The classify endpoint evaluates the tool name and input
  4. Safe tools are auto-approved — the agent proceeds immediately
  5. Dangerous tools are queued — the server pushes a permission_request message via the WebSocket endpoint (or the dashboard can poll GET /api/permissions)
  6. Destructive tools are blocked — the agent cannot proceed
The hook system is fail-closed. If the classify endpoint is unreachable, all tool calls are denied by default. See the hooks classify API for full endpoint details including request format and authentication.