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
Query parameters
Response
Errors
Submit permission decision
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 thedangerous 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 pollingGET /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 youruserId as a query parameter. On successful connection, the server sends a connected message:
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
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_requestbroadcasts.
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:- The
--hook-pre-tool-useflag triggers the hook script - The hook script sends tool details to
POST /api/hooks/classify - The classify endpoint evaluates the tool name and input
- Safe tools are auto-approved — the agent proceeds immediately
- Dangerous tools are queued — the server pushes a
permission_requestmessage via the WebSocket endpoint (or the dashboard can pollGET /api/permissions) - 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.