Grok Bot
Grok Bot Inference Hooks: Setup, Modes, Frames and Policies
Grok Bot inference hooks, in beta for all Enterprise teams, send every governed model request, signed, to an AI security server your organization runs or uses through a vendor. Your server returns allow or deny before the model sees the request. They check model inputs only, and new configurations start in Shadow mode, which blocks nothing.

On this page
- What are Grok Bot inference hooks and how do they work?
- How do you set up Grok Bot inference hooks?
- How do request signing and Test Connection work?
- Which inference hook mode should you use, and how do timeout and rollout work?
- What happens when the circuit breaker trips or Cursor pauses hooks?
- What do members see when a request is blocked?
- What do Grok Bot inference hooks cover, and what do they miss?
- What does an inference hook request look like, and how do you write policies for it?
What are Grok Bot inference hooks and how do they work?
Inference hooks let your own policy check what Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. is about to send a model. Cursor signs each governed request, sends it to your security server, waits for an allow or deny verdict, and stops the request on a deny. That covers prompts and the content Grok Bot gathers, such as web pages and app results, before any model sees them.
Inference hooks are in beta and available to all Enterprise teams. Team admins set them up from the dashboard, and they cover Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. only.
The mechanics are worth getting straight before setup, because they decide what a policy can and can't catch:
- Each governed model request is checked. Cursor sends a signed
promptframe with the conversation so far and holds the request until a verdict arrives or the timeout passes. A turn that calls the model several times, for example between tool calls, sends one frame per call. - Your server decides.
allowlets the request go to the model.denystops it, ends the turn, and the member who sent the message sees a block notice. - Failures follow your mode. A timeout, an error or a non-verdict answer is handled by the mode you chose. A failure never counts as a deny.
- Only model inputs are checked. A tool call and its result appear in a frame only after the tool has run.
That last point has a consequence that's easy to miss. Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition.'s reply to a member is itself a tool call, so the reply reaches the member before any frame contains it, and a deny stops the next model call rather than an action that already happened. The security docs make the same point from the other side: keep the network policy and Auto Review in place to control what Bots do. Those controls are covered in Grok Bot security and privacy.
This exact topic is a hands-on Lesson: Privacy and data governance — about 6 minutes, free to read.
Rather do it than read about it? Run 11 interactive Cursor walkthroughs in a simulated editor. Free, no account needed.
How do you set up Grok Bot inference hooks?
You need to be a team admin on an Enterprise team. The setup itself is short, and most of the time goes into the server side.
- 1Prepare your security server: create an inference hooks integration in your vendor's console, or host your own server that meets the endpoint requirements. The Security Vendor list includes vendor presets with a setup checklist.
- 2In the Cursor dashboard, select the team, then open Inference Hooks from the Security & Compliance section of the Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. page.
- 3Click Set Up Endpoint, choose your vendor or Custom Endpoint, and enter the Endpoint URL and any Custom Headers your server needs, such as its API key. Cursor checks the URL when you save.
- 4Copy the signing secret. The first save that sets an endpoint generates one starting with
whsec_and shows it once. Paste it into your vendor's webhook secret field or your server's configuration. - 5Click Test Connection. Cursor sends a synthetic request and shows the verdict or why the check failed.
- 6Turn on Enforce Verdicts. New configurations start in Shadow Mode, so your endpoint receives every covered request and denials are logged, but nothing is blocked.
- 7Once the verdicts look right, set Mode under Failure Handling to Allow the Request or Block the Request.
Setting changes take effect within about a minute, and requests already in flight finish under the old settings. One side effect applies in every mode and at any rollout percentage: while an endpoint is saved, Enforce Verdicts is on and Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. is covered, Grok Bot skips some model calls it would otherwise make ahead of a turn, so replies can start more slowly.
The endpoint has strict requirements, and a URL that breaks any of them is refused:
- Use an
https://URL on port 443. The host must be publicly routable with a certificate from a public certificate authority. Private, loopback and carrier-grade NAT addresses are refused. - Redirects and tunnels don't work. Cursor treats a redirect as a failed check, and reverse-tunnel hosts aren't accepted.
- Keep secrets out of the URL. It can't carry credentials, a query string or a fragment, because admins see it in plain text. URLs are limited to 2,048 characters.
- Answer every request, Test Connection included, with HTTP 200 and a JSON verdict.
Credentials belong in custom headers, which are stored encrypted. You can add up to 16. Names use letters, digits and hyphens without underscores, up to 128 characters, and values are printable ASCII up to 8,192 characters. Values are write-only, so changing any header means re-entering every value, and a new URL clears saved values until you re-enter them in Edit. Requests go out without them in the meantime. Cursor also reserves some names, including Host, Cookie, User-Agent and anything starting with Content-, Proxy-, X-Forwarded-, Webhook- or X-Cursor-.
How do request signing and Test Connection work?
Every request carries Standard Webhooks headers, so your server can reject anything Cursor didn't send. Verify the signature rather than relying on the User-Agent or the source IP.
- Header
webhook-id- Value
- The frame's
request_id
- Header
webhook-timestamp- Value
- Unix time in seconds
- Header
webhook-signature- Value
v1,then the base64 HMAC-SHA256 of{webhook-id}.{webhook-timestamp}.{raw body}, keyed with the base64-decoded part of the secret afterwhsec_
| Header | Value |
|---|---|
webhook-id | The frame's request_id |
webhook-timestamp | Unix time in seconds |
webhook-signature | v1, then the base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{raw body}, keyed with the base64-decoded part of the secret after whsec_ |
Each request carries exactly one signature. To rotate, click Rotate Secret under Request Signing. The new secret is shown once and Cursor starts signing with it within about a minute, so keep accepting the previous secret until then. When a server rejects Cursor's requests, the docs say it's usually a signature or credential mismatch: paste the current secret (with the whsec_ prefix if your verifier expects it), check that it decodes as standard base64, and confirm the API key header is saved.
Test Connection sends a signed prompt frame with source.application set to config-test, a fixed message with no user content, and no member, session or model. It uses your saved secret and verdict timeout. The results map cleanly to causes:
- Result
- Allow or deny
- Meaning
- Your server returned a verdict. Resolve a deny before you enforce.
- Result
- URL rejected
- Meaning
- The URL doesn't meet the endpoint requirements.
- Result
- Private or internal IP
- Meaning
- The host isn't publicly routable.
- Result
- Timeout
- Meaning
- No verdict arrived within the verdict timeout.
- Result
- Transport error
- Meaning
- DNS, connection or TLS failure.
- Result
- Non-200 status
- Meaning
- Your server answered with another status, including a redirect.
- Result
- Unparseable response
- Meaning
- The body wasn't a JSON verdict, was compressed, or was over 64 KiB.
- Result
- Signing secret required
- Meaning
- Save the configuration first. Saving generates the secret.
| Result | Meaning |
|---|---|
| Allow or deny | Your server returned a verdict. Resolve a deny before you enforce. |
| URL rejected | The URL doesn't meet the endpoint requirements. |
| Private or internal IP | The host isn't publicly routable. |
| Timeout | No verdict arrived within the verdict timeout. |
| Transport error | DNS, connection or TLS failure. |
| Non-200 status | Your server answered with another status, including a redirect. |
| Unparseable response | The body wasn't a JSON verdict, was compressed, or was over 64 KiB. |
| Signing secret required | Save the configuration first. Saving generates the secret. |
A deny on the test deserves attention. It means your policy blocks Cursor's synthetic prompt, and in Allow or Block mode a policy like that blocks members too.
Which inference hook mode should you use, and how do timeout and rollout work?
Enforce Verdicts turns sending on and off; while it's off, Cursor sends nothing and keeps your settings. While it's on, Mode decides what happens on a deny and when a check can't finish.
- Mode
- Shadow Mode (default)
- On a deny
- Lets the request through
- When the check fails
- Lets the request through
- Mode
- Allow the Request
- On a deny
- Blocks the request
- When the check fails
- Lets it through uninspected (fails open)
- Mode
- Block the Request
- On a deny
- Blocks the request
- When the check fails
- Blocks the request (fails closed)
| Mode | On a deny | When the check fails |
|---|---|---|
| Shadow Mode (default) | Lets the request through | Lets the request through |
| Allow the Request | Blocks the request | Lets it through uninspected (fails open) |
| Block the Request | Blocks the request | Blocks the request (fails closed) |
In Allow and Block modes the model request waits for the verdict. Shadow mode sends the same frames at the same moments in the background: nothing waits, members see nothing, and denials and failures go to the audit log. Under heavy load Cursor can skip a Shadow check, and a skipped check writes no audit row, so Shadow numbers are a sample more than a census.
A check fails when your server times out, returns a non-200 status, returns a body that isn't a JSON verdict or is over 64 KiB, returns an action other than allow or deny, or can't be reached. A frame over 64 MiB also counts. Block mode blocks every check that can't finish once Cursor has your settings, even when the cause is on Cursor's side. If Cursor can't load your settings at all, it can't tell which mode you chose, so the request proceeds and is logged as failed open with reason config_unavailable.
Verdict Timeout (ms) accepts 1 to 10,000 and defaults to 5,000. It covers the whole exchange, from connection and TLS handshake to response. If the connection fails, Cursor retries once within the same timeout with the same webhook-id and signature, so deduplicate on webhook-id. It never retries after your server responds, and its own processing adds up to about half a second.
Requests Inspected (%) sends only a share of covered requests while you bring the endpoint up. The choice is sticky per turn, so every request behind one turn, subagents included, is either inspected or skipped. Requests outside the share proceed uninspected even in Block mode, and 0% turns inspection off.
What happens when the circuit breaker trips or Cursor pauses hooks?
Sustained failures your server is responsible for, such as timeouts, error statuses, TLS errors and malformed verdicts, trip the circuit breaker. DNS and connection errors, URLs Cursor refuses, and frames over 64 MiB count as failures but never trip it.
- While tripped, Cursor stops sending and your mode applies to every covered request. Block mode blocks them all; Allow and Shadow let them through uninspected. The audit log records one
inference_hooks_circuit_breaker_trippedevent per trip and no per-request events. - Recovery is automatic. Starting 10 minutes after the trip, Cursor periodically sends the Test Connection request, and an allow or a deny resets the breaker.
- Any settings change stops automatic recovery, rotating the secret included. Once the endpoint is fixed, click Reset, or turn Enforce Verdicts off and on again.
The third point matters more than it looks. If you edit anything after a trip, waiting won't bring hooks back, so fix the endpoint, run Test Connection, and click Reset yourself.
Separately, Cursor can pause inference hooks for a team or for everyone in an emergency. While paused, Cursor sends no frames, covered requests proceed, the audit log records most of them as failed open with reason kill_switch, and Test Connection shows "Inference hooks are temporarily paused by Cursor." Audit events across all of this carry identifiers and codes only, never prompt content, the deny reason, the signing secret or header values, and an allowed request writes no event.
What do members see when a request is blocked?
On a deny, the Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. desktop and mobile apps show a block notice to the member who sent the blocked message, in their own conversation with the Bot. It carries the title Blocked by your organization's policy, your server's deny_reason, your Blocked Message, and two buttons. Edit takes the blocked message back out and puts its text in the message box (unless a draft is already there). Reset clears the conversation. When Cursor can't roll the conversation back, only Reset appears.
Blocked Message accepts up to 500 characters and defaults to "Your organization's security policy blocked this request." Use it to tell members what to do next, such as who to contact. Neither Edit nor Reset undoes actions the Bot already took, such as files it wrote. A reset keeps the Bot's memory, files, routines and settings.
This interacts with policy design. A blocked message stays in the conversation until someone takes it back or resets, and Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. sends it with every later request. A policy that scans the whole transcript keeps denying that conversation, while one that judges the newest user message lets it continue once the member sends something different. If a conversation is blocked again right after a reset, the notice has no buttons and points to the Bot's memory or files.
Other surfaces show less. The list covers the cases the docs call out:
- Shared Bots notify only the sender, and the Bot's owner isn't shown the deny reason. Rooms and group chats get no Edit or Reset.
- Slack replies in the conversation. One-to-one DMs quote the deny reason and Blocked Message; channel threads and group DMs never do. The reply offers Remove blocked message and Reset.
- Mobile group chats and others' conversations show Bot failed to respond, without the deny reason or buttons.
- Other Cursor apps show only the title, and older desktop versions show no buttons.
- Routines stop, and the dashboard run history records the block without the deny reason.
- Email, Linear and other connected channels get no reply.
A failed check in Block mode looks different: the desktop app shows Your organization's policy check is unavailable, without your Blocked Message, Edit or Reset. Members see nothing on an allow or in Shadow mode, but Shadow mode still sends their conversations to your endpoint, so the docs say to tell members your organization checks Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. requests before you turn on Enforce Verdicts.
What do Grok Bot inference hooks cover, and what do they miss?
Covered requests are the ones behind your members' Grok BotAn early AI teammate product from SpaceXAI and Cursor that works across apps on a persistent cloud computer and asks for approval on selected actions; launch materials describe it as beta, but Cursor says Beta Services terms do not apply. Press Enter for the full definition. conversations: every step of a turn, subagents, the summaries Grok Bot writes of long conversations, and routines. A team Bot or room follows its team's hook, and a personal Bot follows the team its owner has selected.
- Model responses aren't checked.
- System prompts, tool definitions and the model's hidden reasoning never go to your endpoint, and most text Cursor adds for the model, such as reminders and timestamps, is left out.
- Ancillary calls aren't sent: chat titles, Auto Review and saving memories.
- Other Cursor features aren't covered: Cloud AgentsAgents that run in a Cursor-managed virtual machine, check out the repo, do the work and open a pull request, then shut down, with no load on your laptop. Press Enter for the full definition., agents in the editor, the CLI, the Agent SDKA programmatic interface for running Cursor agents from your own scripts, services or CI, locally or in the cloud. Press Enter for the full definition., Tab, embeddings and local models.
- Tool execution, connected-app actions and network traffic from the computer reach your endpoint only when their output returns as a tool result in a later frame.
On privacy, Cursor discards each frame once the verdict arrives and doesn't write frame content to its databases, logs, metrics or traces. What your endpoint keeps is up to you and your vendor. Privacy ModeCursor's setting that guarantees code data is not used for training by Cursor or its model providers, and that an admin can enforce org-wide; data-retention terms are a separate, contractual layer. Press Enter for the full definition. is unchanged, and hooks run for every covered member regardless of it, because your admins direct Cursor to send these requests to your endpoint.
What does an inference hook request look like, and how do you write policies for it?
Each frame is an HTTPS POST with a compact JSON body and lowercase header names, including content-type: application/json, user-agent: cursor-inference-hooks/1, accept-encoding: identity, the three webhook headers and your custom headers. This is the docs' example frame:
{
"type": "prompt",
"request_id": "req_6b1f0c2e-4d7a-4f1e-9a53-2c8d7e41b9a0",
"tenant_id": "team_4mQvT8yLcN2pR6",
"actor": {
"type": "user",
"id": "user_8hJw3KzP5sXq1V7nB2cF9mD4tR",
"email_address": null
},
"source": { "application": "grok-bot" },
"session_id": "3f2c9a71-58e4-4b0d-9c6a-0d1e7b25a4f8",
"model": "<Cursor model identifier>",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Check the Q3 renewals sheet for accounts at risk and draft a note to the account team."
},
{
"type": "attachment",
"file_name": null,
"media_type": "image/png",
"size_bytes": 184320,
"text": null
}
]
}
],
"metadata": {}
}A few fields need care. request_id matches webhook-id and the audit log's request_id, so you can join vendor records to Cursor's log. tenant_id and actor.id are opaque, actor.email_address is always null, and actor.id is null for Slack senders who haven't linked a Cursor account. session_id identifies the Bot across its chats and members, so it doesn't pin down one conversation. model is for reporting, not allowlisting, and metadata is always empty.
Messages use the roles user and assistant, with tool results under user, and the block types text, tool_use, tool_result and attachment. Every frame carries the whole conversation so far rather than a delta, though a summary replaces older messages in long conversations. Context such as rules, shared memory and connected apps usually arrives in attachment text. Images arrive as attachments with media type and size, but not their bytes or URL. Replies to members appear in tool_use input. Secret values are never included.
The verdict is HTTP 200 with a JSON object. This is the docs' example:
{
"action": "deny",
"deny_reason": "This message contains a customer account number. Remove it and try again.",
"reference_id": "policy-7f3c21"
}action is allow or deny, and anything else is a failed check. deny_reason is shown to the sender and truncated to 500 characters. reference_id is recorded in the audit log, up to 50 characters from letters, digits and ., _, :, /, -; a malformed value is dropped and the deny still applies. Unknown fields are ignored, and Cursor reads at most 64 KiB, uncompressed.
Cursor's policy guidance comes down to five habits:
- Verify the signature. If the Inference Hooks page lists Source IP Ranges under Request Signing, you can allowlist them as well.
- Treat IDs as opaque strings and map members by
actor.id, since frames carry no email. - Treat
source.applicationas an open set. Cursor adds values as coverage grows, and it's advisory, not a security control. - Scan every block type, not only
text. Context arrives in attachmenttext, and replies and connected-app calls arrive intool_useinput. - Don't rely on
tool_result.is_error. It'sfalsefor most failed tool calls too.
Answer config-test frames from Test Connection and circuit-breaker recovery with a verdict too, and keep them out of your reports on member traffic. For the controls that govern actions rather than model inputs, see the admin overview.
Frequently asked questions
Can our own security tooling check what Grok Bot sends to models?
Yes, with inference hooks, an Enterprise beta. Cursor sends each Grok Bot model request, signed, to an AI security server your organization runs or uses through a vendor, and your server allows or denies it before the model runs. Hooks check model inputs, not actions as they run.
Why don't I see Inference Hooks on the Grok Bot page?
The page appears for team admins on Enterprise teams and shows the team selected in the dashboard, so check the right team is selected. If the page says inference hooks aren't available yet, contact your account manager.
Why isn't my endpoint receiving requests?
Check that an endpoint is saved, Enforce Verdicts is on, Coverage includes Grok Bot, Requests Inspected (%) is above 0, and the circuit breaker isn't tripped. Only Grok Bot conversations of your team's members are covered. If Test Connection reports hooks are paused, Cursor has paused them.
Why do members see that the policy check is unavailable?
You're in Block mode and the check failed, or the circuit breaker tripped. Check Recent Errors on the Inference Hooks page. To keep members working while you fix the endpoint, switch to Allow the Request.
Why is every message in a conversation blocked after one block?
The blocked message stays in the conversation and goes to your server with every later request, so a whole-transcript policy denies each one. Use Edit in the app, or Remove blocked message in Slack, to take it back. If a block repeats right after Reset, the match is likely in the Bot's memory or files.
Does Cursor keep the frames it sends to my hook?
No. Cursor sends each frame over HTTPS and discards it once the verdict arrives, and frame content isn't written to Cursor's databases, logs, metrics or traces. What your endpoint stores depends on your configuration and your agreement with your vendor.
Sources & last verified
- Cursor docs: Grok Bot inference hooks
- Cursor docs: Grok Bot security
- Cursor docs: Grok Bot security FAQ
Cursor ships frequently. Facts verified against primary sources on October 25, 2026.