|
| 1 | +--- |
| 2 | +title: Human-in-the-Loop Approvals |
| 3 | +sidebar_label: Human-in-the-Loop |
| 4 | +description: Require real-time human approval before high-risk agent tool calls are executed. Configure per-tool, per-server, and per-trust-level approval policies with email and Slack notifications. |
| 5 | +sidebar_position: 7.5 |
| 6 | +--- |
| 7 | + |
| 8 | +# Human-in-the-Loop Approvals |
| 9 | + |
| 10 | +Human-in-the-Loop (HITL) adds a **real-time approval gate** to your agent workflows. When an agent requests a sensitive operation — such as deleting records, modifying production data, or accessing restricted resources — the gateway pauses execution and routes an approval request to a designated admin. Routine operations continue without interruption. |
| 11 | + |
| 12 | +:::note Enterprise Plan |
| 13 | +Human-in-the-Loop approvals are available on **Enterprise** plans. [Schedule a demo](https://calendly.com/permit-io/demo) to get started. |
| 14 | +::: |
| 15 | + |
| 16 | +:::tip Quick start |
| 17 | +1. Go to **MCP Servers** → select a server → toggle **HITL** on a tool |
| 18 | +2. Trigger that tool from an MCP client (e.g., Cursor, Claude Desktop) |
| 19 | +3. Open **Approvals** in the Platform → approve or reject the request |
| 20 | +::: |
| 21 | + |
| 22 | +## How it works |
| 23 | + |
| 24 | +1. An agent calls a tool that requires approval (e.g., `delete_repo`) |
| 25 | +2. The gateway checks authorization via Permit.io (existing [trust-level](/permit-mcp-gateway/guide) check) |
| 26 | +3. If the tool is approval-gated, the gateway **pauses the request** and creates an approval request |
| 27 | +4. Admins are notified via the Platform UI, email, and/or Slack |
| 28 | +5. An admin reviews the request and **approves or rejects** it |
| 29 | +6. The gateway resumes the tool call (on approval) or returns an error (on rejection/timeout) |
| 30 | + |
| 31 | +The MCP client simply waits for the response — no client changes are needed. If no decision is made within the timeout (default: 5 minutes), the request is automatically rejected. |
| 32 | + |
| 33 | +## Approval queue |
| 34 | + |
| 35 | +The **Approvals** page in the Platform is where admins review and act on pending requests. It has three tabs: **Pending**, **History**, and **Notifications**. |
| 36 | + |
| 37 | +### Pending approvals |
| 38 | + |
| 39 | +Each pending approval card shows the full context needed to make a decision: |
| 40 | + |
| 41 | +- **Tool name** and **server** — what the agent wants to do and where |
| 42 | +- **Trust-level badge** — shows the tool's risk level (high, medium, or low). High-risk cards have a red left border; medium-risk cards have a yellow border for quick visual triage |
| 43 | +- **Agent and user identity** — who is making the request |
| 44 | +- **Tool arguments** — the exact parameters being passed (e.g., which issue ID, which repository) |
| 45 | +- **Approval reason** — when present, a brief explanation of why this tool requires approval |
| 46 | +- **Countdown timer** — time remaining before automatic rejection |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +Admins can **Approve** or **Reject** each request. When rejecting, you can provide a reason — either a quick preset ("Unauthorized scope", "Suspicious arguments", "Wrong environment") or a custom message. |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | +The rejection reason is included in the error message returned to the agent, so the user understands why their request was denied. |
| 55 | + |
| 56 | + |
| 57 | + |
| 58 | +When multiple approvals are pending, select multiple cards using the checkboxes and use the batch action bar to approve or reject all selected requests at once. |
| 59 | + |
| 60 | +:::tip Keyboard shortcuts |
| 61 | +**J/K** navigate cards · **A** approve · **R** reject (opens reason input) · **X** select · **Esc** deselect |
| 62 | + |
| 63 | +Single-key shortcuts can be toggled off in the Approvals UI. **Esc** always works regardless of this setting. |
| 64 | +::: |
| 65 | + |
| 66 | +### Approval history |
| 67 | + |
| 68 | +The **History** tab shows all resolved approvals — who made each decision, how long it took, and the outcome (approved, rejected, timed out, or cancelled). Use the status filter to narrow down by outcome. |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | +## Configuring approval policies |
| 73 | + |
| 74 | +### Per-tool approval |
| 75 | + |
| 76 | +On any MCP server's detail page, each tool has a **HITL toggle**. Enable it to require approval for that specific tool — use this for individual high-risk operations. |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | +### Server approval policy |
| 81 | + |
| 82 | +The **Server Approval Policy** card on the server detail page provides broader controls: |
| 83 | + |
| 84 | +- **Require approval for all tools** — every tool on this server requires approval |
| 85 | +- **Trust level threshold** — require approval for tools at a specific [trust level](/permit-mcp-gateway/guide) or higher. For example, set to "High" to gate only the most critical tools, or "Low" to gate everything. |
| 86 | + |
| 87 | +Per-tool toggles, server policies, and trust level thresholds all stack — if any of them requires approval, the tool call is gated. |
| 88 | + |
| 89 | +### Trusted agent bypass |
| 90 | + |
| 91 | +A separate card on the same server detail page lets you configure bypass rules for trusted automation. For agents that should not require manual approval (e.g., CI bots, scheduled pipelines), add the agent's client ID to the **Trusted Agent Bypass** list. Bypassed agents skip the approval check entirely — this takes priority over all other policies. |
| 92 | + |
| 93 | + |
| 94 | + |
| 95 | +You can find an agent's client ID on the **Agents** page in the Platform. |
| 96 | + |
| 97 | +## Notifications |
| 98 | + |
| 99 | +Configure where approval notifications are sent so admins know immediately when a request is waiting. Go to **Approvals > Notifications** to set up: |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +### Email notifications |
| 104 | + |
| 105 | +Add email addresses to receive a notification whenever a new approval request is created. The email includes the tool name, server, agent identity, and a link to review in the Platform. |
| 106 | + |
| 107 | + |
| 108 | + |
| 109 | +### Slack notifications |
| 110 | + |
| 111 | +Paste a [Slack Incoming Webhook](https://api.slack.com/messaging/webhooks) URL to receive notifications in a Slack channel. The message includes the approval context and a button to open the Platform for review. For security, tool arguments are not included in Slack messages. |
| 112 | + |
| 113 | + |
| 114 | + |
| 115 | +### Browser notifications |
| 116 | + |
| 117 | +When the Platform is open in a browser tab, you can enable desktop notifications to be alerted when new approval requests arrive — even if the tab is in the background. Click **Enable desktop notifications** in the Approvals UI and allow the browser permission prompt. Once enabled, new approvals trigger a desktop notification whenever the Platform tab is not in focus. |
| 118 | + |
| 119 | +## Timeouts |
| 120 | + |
| 121 | +- **Default timeout:** 5 minutes — if no admin responds, the request is automatically rejected |
| 122 | +- **Extend:** When an approval is about to expire (last 60 seconds), an **Extend +5 min** button appears on the card — click it to add more review time |
| 123 | +- Timeouts always result in rejection, never automatic approval |
| 124 | +- If the agent disconnects while waiting, the request is automatically cancelled |
| 125 | + |
| 126 | +## What the agent user sees |
| 127 | + |
| 128 | +When a tool call is paused for approval, the agent receives a notification: |
| 129 | + |
| 130 | +> Tool 'delete_repo' requires admin approval before execution. Waiting for approval (timeout: 5 minutes)... |
| 131 | +
|
| 132 | +Most MCP clients (Cursor, Claude Desktop, Claude Code) display this message so the user knows the wait is intentional. If the request is rejected, the error message includes the reason provided by the admin. |
0 commit comments