Databricks AI Gateway
An External service policy connects Databricks Unity AI Gateway to your runtime guards. On every governed call — a model request, a model response, an MCP tool call, or a tool result — the AI Gateway sends the content to Willow and holds the call until Willow returns an allow or deny verdict. Databricks enforces that decision itself, so your applications do not change.
Where Guard Hooks run inside each coding agent on the endpoint, this runs server-to-server, like Inference Hooks: one connection plus one policy attachment in Databricks routes every governed call through Willow, with nothing to install on user machines.
Where this fits
| Guard Hooks | Inference Hooks | Databricks AI Gateway | |
|---|---|---|---|
| Where it runs | On the machine, in each agent | Anthropic → Willow | Databricks → Willow |
| Coverage | Claude Code, Cursor, Codex | Claude Enterprise surfaces | Model, model-provider, and MCP services in Unity Catalog |
| Verdicts | block / ask / warn / redact | allow / deny only | allow / deny only |
| Auth | Org HMAC token | Org HMAC token | OAuth M2M (client ID + secret) |
| If Willow is unreachable | Call proceeds | Your choice in claude.ai | Call is denied — not configurable |
If Willow is unreachable, times out, or returns something Databricks cannot parse, the governed call is denied. Databricks offers no setting to let traffic through when the guardrail is unavailable, so an External service policy in Enforce mode puts Willow on the critical path of every governed call. Start in Log mode and confirm behavior before enforcing.
This is the opposite of Guard Hooks and Inference Hooks, which fail open so a guardrail outage cannot block work.
The contract carries a decision, not content. Willow maps a guard block to DENY and a warn to ALLOW. Two guard actions behave differently here than on the gateway:
- Redact guards cannot mask anything, because there is nowhere to return rewritten content. Each redact guard instead falls back to its configured redact fallback action, which defaults to blocking. See Actions.
- Require approval guards deny, since there is no user session to prompt.
Prerequisites
- Private Preview access on both sides. External service policies are in Private Preview at Databricks, and Service Policies (the underlying mechanism) are in Beta. Databricks must enable the feature on your workspace — if External does not appear as a guardrail type in the policy form, that is the reason. On the Willow side the Databricks AI Gateway Policies flag has to be turned on for your organization; contact Willow support to have it enabled.
- At least one active runtime guard, so the policy has something to enforce. See Create a Guard.
- Databricks permissions. These can sit with two different people:
- To create the connection:
USE CATALOGandUSE SCHEMAon the target catalog and schema, plusCREATE CONNECTION. - To attach the policy:
MANAGEon the AI service being governed,USE CONNECTIONon the connection, and access to that connection's parent catalog and schema.
- To create the connection:
How it works
- A user or application calls a governed service — a model serving endpoint, a model provider, or an MCP server registered in Unity Catalog.
- The AI Gateway POSTs a
{event, config}envelope to Willow and holds the call. - Willow authenticates the request with the OAuth bearer token it issued, resolves your organization from that token, and evaluates the content against your active runtime guards.
- Willow returns
{"result": "ALLOW"}or{"result": "DENY", "reason": "..."}. On a deny the caller sees the blocking guard's message; the decision is recorded in Monitor → Logs.
Willow answers within about four seconds to stay inside the platform's five-second deadline, and always answers with HTTP 200 — the contract reserves error statuses for evaluation failures, which Databricks treats as a denial with its own generic message.
Step 1 — Enable it in Willow
Go to Admin → Settings → Security and find Databricks AI Gateway. Click Enable.
Willow creates an OAuth M2M credential and reveals the four values the Databricks connection form needs:
| Field | Value |
|---|---|
| Host | https://<org>.<your-domain> |
| API path | /api/databricks/external-policy |
| Token endpoint | https://<org>.<your-domain>/api/databricks/oauth/token |
| Client ID / Client secret | Generated for you |
The secret is stored hashed and is shown only once. If you lose it, revoke the credential and create another — it cannot be recovered.
The host is your Willow connect host, the same one that serves your OAuth and connect endpoints.
Step 2 — Create the Unity Catalog HTTP connection
The connection holds your endpoint's base URL and its credentials. Create it either inline while attaching the policy (Create new connection in the policy form) or ahead of time in Catalog Explorer → Create → Connection. Creating it ahead of time is better if several policies will share one endpoint, or if a different team owns credentials.
| Field | What to enter |
|---|---|
| Connection name | For example, willow_guardrail |
| Catalog, Schema | Where the connection object lives in Unity Catalog |
| Host | The Host value from Step 1, including the scheme |
| API path | /api/databricks/external-policy |
| Auth type | Fixed to OAuth M2M — not editable |
| Client ID, Client secret | From Step 1 |
| Token endpoint | The Token endpoint value from Step 1 |
| OAuth scope | Leave empty. Willow does not require a scope. |
OAuth M2M is the only supported authentication method. API keys, Basic auth, and user-based OAuth are not supported.
One connection can serve several policies, so you normally create one connection per endpoint rather than one per policy.
Step 3 — Attach the External policy
Attach the policy to the service you want governed: a model service, a model provider service, or an MCP service. In the policy form set Guardrail type to External, then:
| Setting | What to choose |
|---|---|
| Connection | The connection from Step 2 |
| Phase | Input only to start. Input runs before the service is called, Output after it responds. |
| Rank | Evaluation order when several policies are attached. Lowest rank runs first on the request and last on the response, and the chain stops at the first deny. |
| Mode | Log to start. See below. |
| Policy configuration | Optional. See Policy configuration. |
Input and Output are two separate requests to Willow, so enabling both roughly doubles the calls Databricks makes and the latency budget you spend.
Log mode first
Log mode is a dry run: the policy is evaluated and the result recorded, but nothing is blocked. Enforce applies the decision.
Databricks surfaces Log-mode results through inference tables, so enable inference tables on the service before you start — otherwise the evaluations still run, and still cost you, with no way to read them.
Log mode removes the risk of blocking, not the dependency: a broken endpoint still records denials, so a flood of them in Log mode is the signal to fix the endpoint before enforcing.
Step 4 — Test it
Wait 60 to 90 seconds after attaching before testing. Policy changes propagate through a config cache, and testing immediately is the most common reason people conclude the integration is not working.
Then send a request your guard should catch — for example a prompt containing a test credit card number, if you have a card or PII guard active.
Databricks traffic has no Willow end user, so a guard attached to specific groups will not fire on it. Guards attached org-wide, or scoped by integration, do. Check your attachment scope if a guard you expected to catch something stays quiet.
Step 5 — Enforce
Once the decisions in Log mode look right, switch the attachment's Mode to Enforce, and add the Output phase if your guards need to inspect responses. Allow another 60 to 90 seconds.
Before you enforce, confirm your own latency and availability headroom: the platform deadline is about five seconds, and anything slower fails closed.
What Willow inspects
The event type tells Willow which surface and phase it is looking at, and what to evaluate:
| Event | Surface and phase | Willow evaluates | Direction |
|---|---|---|---|
tool_call | MCP service, before the tool runs | The tool's arguments | Input |
tool_result | MCP service, after the tool runs | The tool's result payload | Output |
model_call | Model or model-provider service, before the call | The prompt text from the chat request | Input |
model_result | Model or model-provider service, after the call | The response text | Output |
For model events Willow extracts the message text rather than evaluating the raw request envelope, so guards see prose instead of JSON scaffolding — this keeps fields like max_tokens or a tool schema from tripping a check.
The Direction column matters for guard attachments: a guard attached with direction Output only fires on the *_result events, exactly as it does on the MCP gateway path.
An External service policy sends the content under evaluation to a third party. Depending on the service and phase, that can include raw model request and response bodies, MCP tool names and arguments, and MCP tool results.
External service policies do not require a restricted egress network policy. If your workspace has none, outbound access is unrestricted and a policy can send evaluated content to any endpoint reachable through a configured connection. A Unity Catalog connection governs credentials and configuration — it does not restrict network reachability. Databricks recommends applying a restricted-access network policy and allowing only approved destinations.
Policy configuration
Policy configuration is an optional JSON object Databricks passes through to Willow verbatim on every request, without reading it. Willow accepts one key:
| Key | Effect |
|---|---|
mode | "log" (or "dry_run") makes Willow always answer ALLOW while still recording the verdict it would have returned. Anything else, or omitting the key, enforces. |
{ "mode": "log" }
This is a second, independent dry run from the Databricks Mode setting. It is useful when you cannot change the attachment yourself, or when you want to shadow-test a guard change without touching the policy. Setting both is the safest first pass.
Reviewing decisions
Each verdict is recorded in Monitor → Logs as a guard check with the source databricks-ai-gateway and the governed service's fully-qualified Unity Catalog name (for example main.default.github_mcp). The record carries the verdict, the reason, and whether it was a dry run — which is how you tell "nothing fired" apart from "a block was recorded but not applied".
Logging follows the same Log Settings as the other guard surfaces.
Managing credentials
Back in Admin → Settings → Security → Databricks AI Gateway, expand Setup to see the connection values again, add another credential, or revoke one.
Revoking a credential stops Databricks from reaching Willow with it. Because external policies fail closed, any policy still using that credential will deny every governed call until you attach a new one. Create and install the replacement before revoking the old credential.
Limitations in this preview
- Allow and deny only. External policies cannot pause for human approval, and cannot redact or rewrite content.
- One service per policy. A policy attaches to a single model, model-provider, or MCP service. Applying one policy across many services needs attribute-based attachment, which is not available yet.
- The Databricks UI is the only way to attach. Programmatic attachment through REST or Terraform is not available yet.
- Log-mode results need inference tables. Without them enabled on the service you have no view of dry-run results, though the evaluations still run.
Troubleshooting
| What you see | Likely cause |
|---|---|
| The policy seems to do nothing right after attaching | You tested inside the 60-to-90-second propagation window. Wait and retry. |
| Everything is denied, with a reason mentioning the credential | The bearer token was rejected. Confirm the client ID and secret, and that the credential has not been revoked or disabled in Willow. |
| Everything is denied, with a reason about a malformed request | Willow could not read the envelope. Check that the API path is /api/databricks/external-policy and not pointed at another endpoint. |
| Everything is denied, with a reason about not being able to evaluate | Willow reached its guard engine but the evaluation failed or exceeded the deadline. Check your guards and the Willow logs. |
| Everything is denied with a generic platform message | Databricks never got a usable response — the host is unreachable or the connection is misconfigured. Check the host, path, credentials, and egress rules. |
| Denies show a generic reason instead of your guard's | The blocking guard has no message configured. Add one in the guard editor. |
| A guard you expected to fire stays quiet | It is attached to specific groups, which never match Databricks traffic. |
| The connection saves but calls fail | Credentials or the token endpoint are wrong. OAuth M2M is the only supported method. |
Turn it off
- Pause enforcement: set the policy's Mode to Log in Databricks, or detach the policy from the service. Allow about a minute.
- Cut Willow off entirely: revoke the credential in Willow. Note the fail-closed warning above — detach the policy in Databricks first.