Written by AI agents, curated and verified by me.
Inference hooks: the veto sits before inference, the server sits with you
- Claude
- Verification
- Agentic Engineering
On 5 August, Anthropic announced Inference hooks in beta for Claude Enterprise organizations. The release note puts it plainly: point Claude at your organization’s AI security server, and each governed prompt across claude.ai, Cowork and Claude Code is held for that server’s allow or deny verdict before inference proceeds. Requests are signed, failure handling is configurable, and every denial is recorded in the compliance Activity Feed. My thesis: the control point now sits in the right place, before the model rather than in a log afterwards. The price is in the fine print. From that moment on you operate a service in the critical path of every request.
What are Inference hooks?
Inference hooks route every governed request in a Claude Enterprise organization through an AI security server before the model runs. That server is an HTTPS service the organization or its security vendor operates. Anthropic sends the conversation transcript there and waits for allow or deny. A denied request never reaches the model.
Where the hook sits is what matters: on Anthropic’s servers, after the request leaves the client and before inference begins. There is nothing to install on user devices. One hook governs conversations on claude.ai, in Cowork and in Claude Code sessions, on the web, in the desktop app or in the CLI. The feature is not available on Amazon Bedrock or Google Cloud, Platform organizations with API access are out of scope, and voice mode is not covered. Ancillary requests such as conversation title generation are not sent to your endpoint.
There is exactly one hook event today: prompt, fired once per governed inference request, before inference begins. Response-side enforcement is announced as a later event, so it does not exist yet. Configuring hooks requires the organization:manage permission in claude.ai, held by the Admin, Owner and Primary owner roles.
What does one round trip look like?
Anthropic sends an HTTPS POST to the configured URL. The body is the transcript up to the point of inference, signed per the Standard Webhooks specification once your organization has generated a signing secret. Three headers carry the signature: webhook-id, webhook-timestamp and webhook-signature, the last one an HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{raw body bytes}. You verify it over the raw bytes, with a constant-time comparison, and reject a timestamp more than five minutes away from your clock.
The reply is small. {"action": "allow"} lets inference proceed. A deny carries two more fields. deny_reason is the text the person on the other end gets to read, at most 500 characters, followed by a standing message your administrators configure. reference_id is your own identifier for the evaluation, at most 50 characters, never shown to the user, and recorded on the inference_hooks_request_denied compliance activity. That is how you join a denial in the Activity Feed to the record in your own system.
One detail in the flow diagram is easy to miss: the hooked points are the arriving prompt and the returning tool result. Both are inference requests, and each triggers its own exchange with your server. For agentic runs that means it is not the one input that gets inspected, but every step where the model thinks again.
What your server sees, and what it does not
Your server sees what the user sees: transcript text, tool calls and their results, text extracted from attachments, plus fields such as actor, source.application, model and session_id. It does not see system prompts, tool definitions, Anthropic-internal context, Claude’s hidden reasoning, or raw file and image bytes.
That boundary has a practical consequence, listed openly as a limitation in the docs. Attachments arrive as metadata plus extracted text, so image-only content is not inspected. A screenshot of a document walks past your check. Second, verdicts are binary, allow or deny. Rewriting or redacting a prompt is not supported. Anyone hoping for an inline redaction layer gets a gate, not a filter.
Where the decision is actually made
Not in your scanner’s rule set, but in failure handling. Your administrators set a verdict timeout between 1 and 10,000 milliseconds, 5,000 by default. The budget covers connection, TLS handshake, request and response. Anthropic retries exactly once, after 100 milliseconds, and only when the connection attempt itself fails. Once your server has answered, the exchange is never retried.
Anything other than HTTP 200 with a parseable verdict is a webhook failure, redirects and oversized response bodies included. Such a failure never becomes a deny. Your setting decides instead: block the request, or let it proceed without inspection. If failures persist, a circuit breaker stops enforcement entirely. Anthropic stops calling your server and failure handling applies to every request. Recovery happens on the admin side, by turning enforcement back on.
The sharpest example sits in the developer docs. Transcripts are sent untruncated, up to a ceiling of 10 MB. Nginx caps the body at 1 MB by default, express.json()at 100 kB. A rejected body counts as a webhook failure. Under the “allow the request” setting, that means the long prompt with the large attachments is exactly the one that reaches the model uninspected. The request that needed your check most slips through because a default in the reverse proxy was never raised.
At least nobody has to be blocked on day one. Shadow mode observes verdicts on live traffic without blocking anything, a rollout percentage limits the share of inspected requests, and exclusions exempt members of chosen roles entirely.
What does this mean for your work?
First, budget for the latency. Enforcement adds your server’s round trip to every governed request in the organization. Anthropic explicitly recommends load-testing the server before a wide rollout. A verdict that takes 800 milliseconds at the median is invisible with a handful of users and a noticeably slower product with a thousand.
Second, decide fail open or fail closed deliberately, and write the decision down. This is not an operational preference, it is your security policy expressed as a switch. “Allow” means every outage of your server removes the control for the duration of the outage. “Block” means your scanner now has to be as available as Claude itself. Both are defensible, neither should be chosen in passing.
Third, write deny_reason for people. That text is what a colleague sees when their request is blocked. A scanner code helps nobody there. Say what to change.
Fourth, the division of labour. Anthropic places Inference hooks explicitly next to the Compliance API: the hook inline before inference, the API afterwards for audit and export. Together they cover what was allowed to happen and what did happen. Neither answers whether the answer was any good. An allow is not sign-off on a result, and today it is not even a check of the response, because only the input side is inspected.
You know the pattern from the caps in Claude Code: reliability does not come from the model, it comes from the architecture around it, and every new guardrail shifts work to whoever operates it. That is the line in agentic engineering. Inference hooks hand you a real control point in front of the model. Whether it becomes control is decided by the code you write there, and the responsibility for it stays with you.