Govern

Grants & HITL

Who may use which connector/tool — and when a human must approve before a side effect proceeds.

What it is

Grants are durable allow rules (tenant/agent/connector). Predicates deny or pending a connector tools/call from argument values (config-only; never allow). Mandatory HITL forces matching tool calls to pending even when a grant would allow. Pending is the operator queue to approve or deny.

Why it is here

Secrets and side effects must not rely on “the agent was careful.” Governance sits on the plane next to minting and audit.

How to implement

  1. Define connector policy / grants (config defaults + Admin overlays on SQL).
  2. For argument gates (amount, destination), add policy.predicates in the first langgraph.json — not the Grants form. Restart the control plane.
  3. Add mandatory HITL rules for high-risk tools (Admin or config).
  4. Drive a connector MCP tools/call that matches. Over-threshold → JSON-RPC -32000 pending; under-threshold reaches the connector.
  5. Admin → Pending → approve or deny; hover Args on that row for the capped display map. The agent retries the same arguments. A different amount is a new row, not a silent send.
# langgraph.json — grant opens the connector; predicate tightens by amount
"policy": {
  "grants": [
    { "tenant_id": "acme", "agent_id": "payroll", "connector": "bank" }
  ],
  "predicates": [
    {
      "id": "transfer-over-100",
      "tenant_id": "acme",
      "agent_id": "payroll",
      "connector": "bank",
      "tool": "transfer",
      "when": { "path": "amount", "op": "gt", "value": 100 },
      "effect": "pending",
      "reason": "approval required for transfers over 100",
      "reason_code": "predicate_amount"
    }
  ]
}

Ops: eq neq gt gte lt lte in contains exists. Numeric compares use JSON numbers only ("100" vs 100 does not match). Empty agent_id = whole tenant; empty tool = every tool on that connector. Predicates never allow. There is no Admin CRUD for them this release.

# From the try path — approval_agent pauses until resume
curl -sf -N -X POST "$BASE/threads/$THREAD/runs/stream" \
  -H 'Content-Type: application/json' \
  -d '{"agent_id":"approval_agent","input":{"messages":[{"role":"user","content":"send the email"}]}}'

In the product

Admin → Grants — durable connector overlays (SQL)
Runkite Admin Policy grants page
Admin → Audit — policy decisions on SQL backends
Runkite Admin Audit page

What to expect

Reference: docs/trust-governance.md · Connectors · Try HITL