Docs

Documentation

Coding-agent deploy approvals

Step-by-step demo: Claude Code or Codex attempts a production deploy, BehalfID blocks it, you approve in the dashboard, the agent retries and succeeds.

Overview

This guide walks through the complete approval loop for a coding agent that can deploy to staging autonomously, but must pause for human approval before touching production.

The full flow is:

  1. Agent calls verify_action("deploy_production", "vercel.com")
  2. BehalfID returns approvalRequired: true — the agent pauses and reports the request
  3. A pending request appears in the Approvals dashboard
  4. You click Approve — a 30-minute grant window opens
  5. Agent retries verify_action — now allowed: true
  6. Deploy runs. Every step is logged with a stable requestId.

Step 1 — Create permissions

Create two permissions for your coding agent. Staging deploys are allowed automatically; production deploys require human approval.

terminal
# Staging: allowed automatically
behalf permissions create agent_xxx \
  --action deploy \
  --resource vercel.com \
  --allowed "deploy to staging,create preview deployment,update environment variables on staging" \
  --blocked "deploy to production,promote to production,delete production deployment"

# Production: pauses for approval
behalf permissions create agent_xxx \
  --action deploy_production \
  --resource vercel.com \
  --allowed "promote staging to production" \
  --blocked "rollback without approval,delete production deployment" \
  --requires-approval

Step 2 — Wire up MCP enforcement

Run this once in your project directory to register the BehalfID MCP server and write the agent context file:

terminal
behalf config set agent-id agent_xxx
behalf config set api-key bhf_sk_xxx
behalf mcp init

This creates .mcp.json (registers the MCP server) and .behalf/context.md (tells the agent its permissions and the approval protocol).

Step 3 — Launch your agent with enforcement active

terminal
behalf claude      # Claude Code
behalf codex       # Codex CLI
behalf run cursor  # Cursor

The launcher refreshes the permissions cache and starts the MCP server before launching the tool. Every verify_action call during the session goes through your live BehalfID permissions.

Step 4 — The agent hits the approval gate

When the agent attempts a production deploy, it calls verify_action("deploy_production", "vercel.com"). BehalfID responds with approvalRequired: true and creates a pending request.

what verify_action returns to the agent
{
  "requestId": "req_Abc123xyz",
  "allowed": false,
  "approvalRequired": true,
  "approvalId": "apr_Def456uvw",
  "reason": "Permission requires approval before execution.",
  "risk": "medium"
}

The MCP server formats this into a clear instruction block so the agent knows exactly what to do:

what the agent sees in its context
APPROVAL REQUIRED — do not execute this action.

Action:      deploy_production on vercel.com
Request ID:  req_Abc123xyz
Approval ID: apr_Def456uvw

A human must approve this request before the action can proceed.
Approve at: https://behalfid.com/dashboard/approvals

Instructions:
1. Tell the user: "I need approval to run this action. Please visit the BehalfID Approvals
   dashboard and approve the pending request (apr_Def456uvw)."
2. Do not execute the action.
3. After the user confirms they have approved, call verify_action again with the same arguments.
4. If verify_action returns allowed: true, proceed. If it still returns approvalRequired, wait.

The agent then reports this to you in the chat and waits. A verification.approval_required webhook event fires to any configured endpoint (Slack, PagerDuty, etc.).

Step 5 — Approve in the dashboard

Open the Approvals pagein the BehalfID dashboard. You'll see the pending request with the agent name, action, vendor, and the approvalId.

Click Approve. BehalfID opens a 30-minute grant window for that (agent, permission) pair. If the agent doesn't retry within 30 minutes, the grant expires and it must request approval again.

Step 6 — Agent retries and deploys

Tell the agent you've approved. It calls verify_action("deploy_production", "vercel.com") again. BehalfID finds the active grant, marks it used, and returns:

retry response
{
  "requestId": "req_Ghi789rst",
  "allowed": true,
  "approvalRequired": false,
  "reason": "Action allowed by approved permission grant.",
  "risk": "low"
}

The agent proceeds with the deploy. The grant is consumed — a second verify call within the same window would require another approval.

Step 7 — Audit trail

Every step is logged. Filter the Logs view by Decision → Approval required to see the approval gate, or export as CSV for incident reviews.

terminal
# See recent decisions for your agent
behalf logs agent_xxx

# The full lifecycle appears in the logs:
# req_Abc123xyz → denied (approvalRequired)   ← first verify call
# req_Ghi789rst → allowed                     ← retry after approval

Webhook integration (optional)

Configure a webhook to receive verification.approval_required events and route them to Slack, PagerDuty, or a custom approval bot.

approval_required webhook payload
{
  "type": "verification.approval_required",
  "data": {
    "requestId": "req_Abc123xyz",
    "approvalId": "apr_Def456uvw",
    "agentId": "agent_xxx",
    "action": "deploy_production",
    "allowed": false,
    "approvalRequired": true,
    "risk": "medium",
    "permissionId": "perm_yyy"
  }
}

See the Webhooks guide for signature verification and retry behavior.

Troubleshooting

  • Grant expired before retry — the 30-minute window passed. The agent will get approvalRequired: true again and a new pending request will appear in the dashboard.
  • Agent not pausing — check that .behalf/context.md is loaded by the tool. Run behalf mcp init --refresh to regenerate it.
  • approval_required in logs but no pending request in dashboard — the request may have already been resolved. Change the status filter on the Approvals page to All.
  • Webhook not firing — run behalf doctor and check the Webhooks delivery log in the dashboard.