Skip to main content
Rules are good at effects you can name. DROP is destructive, /admin/** is off limits, the salaries table is not yours. They are useless against intent you could not enumerate in advance — which is most of what an agent does. Agentic access closes that gap. The AI Analyzer sits in front of the resource, classifies the statement, and the risk it reports selects a tool.
This runs entirely in the Sidecar. The Sidecar holds the provider credential and reads one YAML file, and no statement is sent anywhere you did not configure.

The tools

The listener’s analyzer block maps each risk level the model can report to a tool. A risk level you do not name defaults to allow, so you opt into blocking a tier by writing it down.
review is not available yet — require_review is refused at startup, because holding a statement for approval needs a review backend the current build does not ship. Until it lands, defer is the closest working thing: the statement is classified and annotated, and Rego makes the call.
Guardrails and Data Masking reach the same request from the other direction. Local rules run before the analyzer, so a DELETE a type: operation rule already refuses never costs a model call; masking runs on the response regardless of which path the request took.

Configuration

Two pieces: a top-level analyzer section that says which model to call, plus the defaults every lane inherits, and the listener’s own analyzer block that says when to call it and what to do with the answer.
config.yaml
The trigger is the gate in front of the model call: only statements matching one of its lists — the normalized SQL verb (operations), a referenced table (tables), or an HTTP resource glob (resources) — are classified; everything else forwards for free. Here only UPDATE and DELETE statements reach the model, and the high/medium/low map decides what happens with the risk that comes back. Omit the trigger and every statement on the lane is classified; see cost controls for what bounds that. A blocked statement reaches the user the same way every other denial does:

What leaves the process

send decides how much of a statement the provider sees: Neither mode needs a pii section: with the section omitted every supported entity is enabled, and a pii.entities list only narrows what the redactor looks for before the statement leaves the process. The credential is always a path (credentials_file), never inline, and the file must be 0600 or stricter.

HTTP listeners must opt into capture

The HTTP codec captures nothing by default, so an analyzer block on an HTTP listener without capture_body is refused at startup:
authorization, cookie and proxy-authorization cannot be allowlisted as captured headers.

Cost controls

This is the only evaluator that leaves the process, costs money per statement and can take a second. An ORM issues the same statement shape thousands of times in one session, so read this before enabling it anywhere real.
1

trigger narrows what is classified

Only statements naming these operations, tables or resources are sent. Everything else allows for free. Omit the trigger and every statement on the lane is classified — declaring the analyzer is the opt-in, the cache and max_calls bound the bill, and --validate prints a note naming the per-statement cost. Under opa.gate: true, an omitted trigger means Rego decides what is worth classifying, and its silence means skip.
2

The cache keys on the statement shape

WHERE id = 1 and WHERE id = 2 are one verdict: literals are stripped from SQL, and HTTP resources are already normalized by the codec. This is also more correct than caching on bytes — the shape is what is risky, not the parameter.
3

max_calls is a backstop

A budget per lane. max_calls on the listener’s block bounds that lane’s spend; the top-level value is the default every lane inherits. The budget keys on the listener name and survives hot reloads. Past it, statements fall through to the local rules, the same outcome as a listener with no analyzer.
Watch the hit rate on the admin API before you enable a blocking action:
Trigger on operations for anything load-bearing. tables comes from a scanner rather than a full SQL grammar, and a statement whose relations it could not determine does not match a table trigger. operations reads the statement’s most consequential effect, so a data-modifying CTE triggers on the delete it performs.

It fails open, and everything else fails closed

The analyzer defaults to fail_open: true. It depends on a third-party API, and a provider outage that closes every database connection in your fleet is a worse incident than the one it prevents. Guardrails and OPA fail closed, as they should — they depend on nothing outside your own infrastructure. Decide which you want per environment, and know that fail_open: false makes your model provider a hard dependency of your database.

Next

AI Analyzer Reference

Every field, the gate phase, prompt precedence and the full findings vocabulary.

Direct Access

The deterministic path, and when to prefer it.

Guardrails

The rules that run before the analyzer and keep it cheap.

Data Masking

Rewrite sensitive values on the way back.