A sensitive tool is one that should never run without a human paying attention. Sending an email, moving money, deleting a record — all of these have consequences the agent can't easily undo.
The way to express "this tool needs review" in NullRun is a
ToolBlock policy — a glob pattern that fails
the gate at /gate evaluation time, regardless of the SDK's local
context. This page covers the recommended patterns and how to wire
them.
There is no SDK-side built-in sensitive tool list. The shipped
behaviour is: every enforcement decision is server-side, evaluated by
the gate on every /gate call. You express "sensitive" with a
ToolBlock policy that matches the tool's canonical name.
Recommended starter patterns (see Tool catalog → Recommended ToolBlock starter list for the maintained list):
| Category | Pattern examples |
|---|---|
| Money | mcp://payments/refund*, mcp://stripe/charge, mcp://stripe/refund |
| Email & messaging | mcp://gmail/send, mcp://slack/post, send_email |
| Database destructive | mcp://postgres/drop_table, mcp://postgres/delete_row, execute_sql |
| External API writes | mcp://*/post, mcp://*/put, mcp://*/delete |
| Files & storage | mcp://s3/delete, file_delete, bash |
| Admin | mcp://admin/delete_user, mcp://admin/disable_user |
These are the canonical tool names a policy matches against. The exact name comes from your MCP server / framework integration — see the tool catalog for the curated list with risk ratings.
A built-in "sensitive tools" SDK list would force every framework to register its tools against NullRun's expectations — and would be silently wrong for any tool not on the list. The current model inverts this:
- You write a ToolBlock policy that names the tools you care about.
- The policy is evaluated server-side on every
/gatecall. - The decision is returned to the SDK as
TOOL_BLOCKED(403).
The gate does not inspect tool arguments — it cannot distinguish
two calls to the same tool by payload. If you want a narrower rule
(e.g. "block refunds over $500"), use a typed BusinessImpact
predicate (Разрыв 2 / 2026-07-27): the SDK extracts the argument bag
and the gate evaluates a DNF of up to 5 named parameters against
Equals / OneOf / NumericRange / Regex / Exists matchers. See
Human approval → typed predicates.
Per the Reliability matrix:
ToolBlock check → fail-CLOSED → 403
TOOL_BLOCKED
Letting through a stripe.charge when the policy check failed means
the agent could move money without anyone knowing. The blast radius
is "agent deleted production data" or "agent leaked your data to an
attacker" — worse than a noisy stop. ToolBlock is always Hard,
regardless of the budget's enforcement_mode.
A ToolBlock policy matches tool name only — not:
- prompt content or semantic intent
- the recipient of a payment (use a typed predicate instead)
- tool arguments beyond the
BusinessImpactextraction - the tool's runtime sandbox (that's your infrastructure concern)
Read operations are never sensitive regardless of the tool. The canonical name alone decides.
You write the policy in the dashboard under Policies → Tool policies → Create. The dashboard shows you the canonical tool name for every framework integration. Your policy applies to:
- All workflows under the org (default)
- A specific workflow (scope to
workflow_id) - A specific API key (scope to
api_key_id)
Per the aggregate rules: ToolBlock patterns union across applicable policies — every pattern that matches fires.
When a sensitive tool is blocked:
- Decision History records the block with reason
TOOL_BLOCKED, the pattern that matched, and the workflow + api_key + tool_name. audit_eventsgets a hash-chained row (content_hash + previous_hash) — see Audit records.
This gives you a complete audit trail of every blocked attempt,
regardless of whether the block came from your policy or from the
default TOOL_BLOCKED rejection of an unknown tool name.
For sensitive tools you want to allow after explicit human review,
pair them with an approval rule instead of removing them from
the blocking surface. The approval row in the dashboard gives you
the audit trail, and the SHA-256 action_digest ensures the grant
is bound to the exact action payload the SDK sent on /gate. See
Human approval.
- Tool policies — the actual rule structure
- Tool catalog — recommended patterns with risk ratings
- Human approval — the safer alternative to disabling a ToolBlock rule
- Circuit breaker → fail-CLOSED matrix