6server your organization runs or uses through a security vendor. Cursor signs6server your organization runs or uses through a security vendor. Cursor signs
7each request, waits for an allow or deny verdict, and stops the request on a7each request, waits for an allow or deny verdict, and stops the request on a
8deny, so your policy checks prompts and the content Grok Bot gathers before a8deny, so your policy checks prompts and the content Grok Bot gathers before a
9model sees them. For Grok Bot's other controls, see9model sees them, and can check the tools a model asks to run before they run. For Grok Bot's other controls, see
10[Grok Bot security](/grok-bot/security).10[Grok Bot security](/grok-bot/security).
11 11
12> **Beta** Inference hooks are in beta and available to all Enterprise teams.12> **Beta** Inference hooks are in beta and available to all Enterprise teams.
27 error, or answers with something other than a verdict, the [mode](#modes)27 error, or answers with something other than a verdict, the [mode](#modes)
28 decides whether the request proceeds or is blocked. A failure never counts as28 decides whether the request proceeds or is blocked. A failure never counts as
29 a deny.29 a deny.
30* **Only model inputs are checked.** Your endpoint judges what is about to go30* **Tool calls can be checked before they run.** With **Validate Tool Calls**
31 to the model. A tool call and its result appear in a frame only after the31 on, the tool calls in each model response wait while Cursor sends your
32 tool has run. Grok Bot's reply to a member is a tool call too, so the reply32 endpoint one signed `tool_call` frame covering all of them. `allow` lets them
33 reaches the member before any frame contains it. A deny stops the next model33 run. `deny` stops them all and ends the turn. See
34 call, not an action that already happened.34 [Tool call frames](#tool-call-frames).
35* **Some calls are never checked first.** Grok Bot's replies to members, and a
36 few internal tools such as memory, run without a `tool_call` frame, so a
37 reply reaches the member before any frame contains it. With
38 **Validate Tool Calls** off, every tool call and its result appear in a frame
39 only after the tool has run, and a deny stops the next model call, not an
40 action that already happened.
35 41
36## Set up inference hooks42## Set up inference hooks
37 43
514. **Copy the signing secret.** The first save that sets an endpoint generates574. **Copy the signing secret.** The first save that sets an endpoint generates
52 a signing secret starting with `whsec_` and shows it once. Paste it into your58 a signing secret starting with `whsec_` and shows it once. Paste it into your
53 vendor's webhook secret field, or your server's configuration, so it can59 vendor's webhook secret field, or your server's configuration, so it can
54 verify each request.60 verify each request. Later saves keep the current secret, which isn't shown
61 again; to get a new one, use **Rotate Secret** under **Request Signing**.
555. **Test the connection.** Click **Test Connection**. Cursor sends a synthetic625. **Test the connection.** Click **Test Connection**. Cursor sends a synthetic
56 request and shows the verdict or the reason the check failed. A deny here63 request, plus a synthetic tool call request when **Validate Tool Calls** is
64 on, and shows the verdict or the reason the check failed. A deny here
57 means your policy would block the test prompt, so fix that before you65 means your policy would block the test prompt, so fix that before you
58 enforce.66 enforce.
596. **Start in Shadow mode.** New configurations start in **Shadow Mode**. Turn676. **Start in Shadow mode.** New configurations start in **Shadow Mode**. Turn
61 covered request and denials are recorded in the audit log, but nothing is69 covered request and denials are recorded in the audit log, but nothing is
62 blocked. Once the verdicts look right, set **Mode** under70 blocked. Once the verdicts look right, set **Mode** under
63 **Failure Handling** to **Allow the Request** or **Block the Request**.71 **Failure Handling** to **Allow the Request** or **Block the Request**.
727. **Decide on tool calls.** **Validate Tool Calls**, under
73 **Enforce Verdicts**, sends each model response's tool calls to your
74 endpoint before they run. It's on by default for new configurations, and
75 configurations saved before it existed have it off. It has no effect while
76 **Enforce Verdicts** is off.
64 77
65Setting changes take effect within about a minute, and requests already in78Setting changes take effect within about a minute, and requests already in
66flight finish under the old settings.79flight finish under the old settings.
124verdict timeout. It uses the URL and headers in the form when you run it from137verdict timeout. It uses the URL and headers in the form when you run it from
125the endpoint dialog, and the saved ones when you run it from the page.138the endpoint dialog, and the saved ones when you run it from the page.
126 139
140When **Validate Tool Calls** is on, Test Connection also sends a synthetic
141`tool_call` frame, and the result shows each check on its own line, starting
142with **Prompt request:** or **Tool call request:**.
143
127| Result | Meaning |144| Result | Meaning |
128| --- | --- |145| --- | --- |
129| Allow or deny | Your server returned a verdict. Resolve a deny before you enforce |146| Allow or deny | Your server returned a verdict. Resolve a deny before you enforce |
148| **Block the Request** | Blocks the request | Blocks the request (fails closed) |165| **Block the Request** | Blocks the request | Blocks the request (fails closed) |
149 166
150In Allow and Block modes the model request waits for the verdict. In Shadow167In Allow and Block modes the model request waits for the verdict. In Shadow
151mode Cursor sends the same frames at the same moments, but in the background:168mode Cursor sends the same prompt frames at the same moments, but in the
152nothing waits, members see nothing, and denials and failures are recorded in169background: the model request doesn't wait, members see nothing, and denials
153the audit log. Under heavy load, Cursor can skip a Shadow check, and a skipped170and failures are recorded in the audit log. Under heavy load, Cursor can skip a
154check writes no audit row.171Shadow prompt check, and a skipped check writes no audit row.
172
173Tool calls wait for each verdict in every mode, Shadow included, and use the
174same failure handling, verdict timeout, rollout, and circuit breaker as prompts.
175Shadow mode still never blocks them, so with **Validate Tool Calls** on, Shadow
176mode adds your server's latency before each tool call.
155 177
156A check fails when your server times out, answers with a status other than 200,178A check fails when your server times out, answers with a status other than 200,
157returns a body that isn't a JSON verdict or is larger than 64 KiB, returns an179returns a body that isn't a JSON verdict or is larger than 64 KiB, returns an
308 330
309**Not covered:**331**Not covered:**
310 332
311* **Model responses aren't checked.** See [How it works](#how-it-works).333* **Model responses' text isn't checked on its own.** A `tool_call` frame
334 carries the response's text alongside its tool calls, but a response without
335 checked tool calls sends no frame. See [How it works](#how-it-works).
312* **Parts of a request that aren't conversation stay out.** System prompts,336* **Parts of a request that aren't conversation stay out.** System prompts,
313 tool definitions, and the model's hidden reasoning never go to your endpoint,337 tool definitions, and the model's hidden reasoning never go to your endpoint,
314 and Cursor leaves out most of the text it adds for the model, such as338 and Cursor leaves out most of the text it adds for the model, such as
318 memories.342 memories.
319* **Other Cursor features aren't covered.** That includes Cloud Agents, agents343* **Other Cursor features aren't covered.** That includes Cloud Agents, agents
320 in the editor, the CLI, the Agent SDK, Tab, embeddings, and local models.344 in the editor, the CLI, the Agent SDK, Tab, embeddings, and local models.
321* **Actions aren't checked as they run.** Tool execution, connected-app345* **Actions aren't checked as they run.** With **Validate Tool Calls** on,
322 actions, and network traffic from a member's Grok Bot computer reach your346 your endpoint judges each tool call before it starts, but not what the tool
323 endpoint only when their output returns to the model as a tool result in a347 then does: commands, connected-app actions, and network traffic from a
324 later frame. Use the [network policy](/grok-bot/security#network-policy) and348 member's Grok Bot computer reach your endpoint only when their output returns
349 to the model as a tool result in a later frame. Use the
350 [network policy](/grok-bot/security#network-policy) and
325 [Auto Review](/grok-bot/security#approvals-and-auto-review) to control351 [Auto Review](/grok-bot/security#approvals-and-auto-review) to control
326 actions.352 actions.
327 353
380 406
381| Field | Value |407| Field | Value |
382| --- | --- |408| --- | --- |
383| `type` | Always `prompt` |409| `type` | `prompt`, or `tool_call` for a [tool call frame](#tool-call-frames) |
384| `request_id` | A unique ID for the request. It matches `webhook-id` and the audit log's `request_id` |410| `request_id` | A unique ID for the request. It matches `webhook-id` and the audit log's `request_id` |
385| `tenant_id` | An opaque ID for your team |411| `tenant_id` | An opaque ID for your team |
386| `actor.type` | Always `user` |412| `actor.type` | Always `user` |
410* **Cursor never adds secret values.** Context can name and describe the436* **Cursor never adds secret values.** Context can name and describe the
411 secrets a Bot can use, but never includes their values.437 secrets a Bot can use, but never includes their values.
412 438
439### Tool call frames
440
441With **Validate Tool Calls** on, Cursor sends a `tool_call` frame after a model
442response asks for tools and before any of them runs. It has the same envelope
443and headers as a `prompt` frame, with its own `request_id`, the same
444`session_id` as the conversation's prompt frames, and `type` set to
445`tool_call`.
446
447* **`messages` holds only the latest assistant message.** Its visible `text`
448 blocks and `tool_use` blocks appear in the order the model wrote them. One
449 verdict covers every call in the frame.
450* **`tool_name` names the tool that actually runs.** Aliases are resolved, so
451 `bash` reads `Shell`. Calls to connected apps and MCP servers keep the
452 meta-tool name the model called, such as `CallMcpTool` or `CallDynamicTool`,
453 with the server in `tool_info.toolset_name`. The prompt frames keep each call
454 as the model wrote it; match the two by the `tool_use` block's `id`.
455* **`input` holds the arguments the tool runs with.**
456* **`tool_info.type` says where the tool runs.** `platform` is a Grok Bot
457 built-in tool and carries `tool_type`. `application` runs in Cursor's
458 backend. `third_party` runs on a remote service and carries `origin`, with
459 its scheme, host, and port, when known; `verified_origin` is true only when
460 the service connected itself. `client` runs on a computer outside Cursor's
461 backend and may carry `tool_type`. Optional fields are left out rather than
462 set to null. Treat names as labels, not trust boundaries.
463* **Some calls are left out.** Replies to members, memory tools, the skill
464 loader, plugin and server lookups, transcript tools, and tool discovery never
465 appear. A response whose only calls are left out sends no frame.
466* **Browser tools used by computer use are checked one at a time.** Each sends
467 its own one-call frame before it runs.
468* **Subagents use the parent's session.** Their responses are framed under the
469 parent conversation's `session_id`.
470
471On a deny, the turn ends with the same [block notice](#what-members-see), and
472every call in the response gets the result "Blocked by your organization's
473policy before it ran". If Cursor can't load your settings in time, the calls
474run without a frame, and once the settings load the audit log records them as
475failed open with reason `config_unavailable`.
476
413### Write policies for these frames477### Write policies for these frames
414 478
415* **Verify the signature.** Don't rely on the User-Agent or source IP. If the479* **Verify the signature.** Don't rely on the User-Agent or source IP. If the
419 members by `actor.id`, since frames carry no email.483 members by `actor.id`, since frames carry no email.
420* **Treat `source.application` as an open set.** Cursor adds values as484* **Treat `source.application` as an open set.** Cursor adds values as
421 coverage grows. It's advisory, not a security control.485 coverage grows. It's advisory, not a security control.
486* **Match tool names in `tool_call` frames.** A policy that denies `Shell`
487 there also catches `bash`, which isn't true of the prompt frames' transcript.
422* **Scan every block type, not only `text`.** Context usually arrives in488* **Scan every block type, not only `text`.** Context usually arrives in
423 attachment `text`, and replies to members and connected-app calls arrive in489 attachment `text`, and replies to members and connected-app calls arrive in
424 `tool_use` input.490 `tool_use` input.
481The `request_id` on denied and failed events matches the frame's `request_id`547The `request_id` on denied and failed events matches the frame's `request_id`
482and `webhook-id`, so you can join your vendor's records to the audit log.548and `webhook-id`, so you can join your vendor's records to the audit log.
483 549
550When tool call checks are available to your team, the denied and failed events
551also carry an `event_type` field in their payload, `prompt` or `tool_call`, and
552the dashboard labels tool call rows **(Tool Calls)**.
553
484The Inference Hooks page also shows endpoint health: status, verdict latency,554The Inference Hooks page also shows endpoint health: status, verdict latency,
485failures per minute, block rate over 24 hours, and recent errors with their555failures per minute, block rate over 24 hours, and recent errors with their
486type and status code. Its figures don't cover all traffic, so they can be lower556type and status code. With **Validate Tool Calls** on, it splits the figures
487than your vendor's counts.557into **Prompts** and **Tool Calls** rows, and shows **Not reported** where a
558figure isn't available. Its figures don't cover all traffic, so they can be
559lower than your vendor's counts.
488 560
489## Privacy and Privacy Mode561## Privacy and Privacy Mode
490 562