Tool Approvals
Agent Port is safe by default: every tool call requires explicit approval before execution.
How it works
Default deny — All discovered tools start in
require_approvalmode. Nothing runs unless explicitly allowed.Per-tool modes — Each tool on an installed integration has an execution mode:
require_approval(default) — calls are blocked until approvedallow— calls execute immediately without approval
Approval flow — When a blocked call happens:
- Agent Port creates a pending approval request
- Returns a
403(REST) or an approval-required text response (MCP) with anapproval_urland theapproval_request_id - The agent presents the link to the user
- The user reviews and decides in the UI
- The agent either retries the call (REST) or long-polls
agentport__await_approval(request_id)(MCP — see below)
MCP long-poll flow — Over the MCP surface, the agent should call
agentport__await_approval(request_id)immediately after sharing the approval URL with the human, instead of waiting for a chat reply. The meta-tool blocks until the human approves, denies, or the server's long-poll budget (approval_long_poll_timeout_seconds, default 240 s) elapses. On approve it returns the real upstream tool result — no retry needed. On timeout it returns a "still pending" message so the agent can loop back in without human intervention.Decision options:
- Approve once — allows this exact call one time; the agent must retry to consume it
- Allow exact forever — creates a permanent policy for this exact tool + arguments combination
- Deny — rejects the request
Optional second factor (TOTP) — Users who turn on two-factor in Settings must enter a 6-digit authenticator code (or a recovery code) alongside every decision. Recovery codes are single-use.
Exact-match policies
When a user chooses "allow exact forever", Agent Port creates an exact-match approval policy. Future calls with the same integration, tool, and normalized arguments are allowed automatically, even if the tool is in require_approval mode.
Arguments are normalized (stable key ordering, compact JSON) and hashed with SHA-256 for matching.
Request lifecycle
pending → approved (approve_once) → consumed (on retry)
pending → approved (allow_exact_forever) → policy created
pending → denied
pending → expired (after 24 hours)
Duplicate blocked calls with the same arguments reuse the same pending request.
Policy evaluation order
For each tool call:
- Check for an exact-match approval policy → allow
- Check the tool's execution setting → if
allow, execute - Otherwise → block and create/reuse approval request
API endpoints
See API Reference for full details:
PUT /api/tool-settings/{integration}/{tool}— set execution modeGET /api/tool-approvals/requests— list approval requestsPOST /api/tool-approvals/requests/{id}/approve-once— one-time approvalPOST /api/tool-approvals/requests/{id}/approve-forever— permanent exact-match rulePOST /api/tool-approvals/requests/{id}/deny— deny request
Logging
All blocked calls generate log entries with outcome: "approval_required" and a reference to the approval request ID. Successful calls log outcome: "executed".