Skip to main content
Someone runs this against production:
The WHERE clause is missing. 500,000 rows change. The statement was valid, the credentials were valid, the permissions were valid — nothing in the database’s own model of correctness had an objection. Guardrails are the objection. Every statement is decoded and evaluated before it reaches the resource, and a rule that matches refuses it with a message you wrote.
Free tier: one Data Masking rule and one Guardrail per Sidecar are free, forever. Running more than one rule per feature, or managing rules centrally across Sidecars, requires Enterprise.

How a rule set resolves

Three sentences cover the entire semantics:
  1. A rule matches, and by default it denies.
  2. First match wins among the rules that deny.
  3. A rule set is an ordered deny list. No match means allowed.
config.yaml
Every rule takes name, message and action in addition to its own fields.
policy.enforce defaults to false. Without it every listener inspects and audits but denies nothing — which is exactly how you want to roll out, and not how you want to leave it. /config on the admin API reports enforcing per listener.

Rule types

operation reads the statement’s worst effect, not its leading verb. A delete hidden in a CTE — WITH d AS (DELETE FROM customers RETURNING *) SELECT count(*) FROM d — reports delete and this rule catches it. EXPLAIN DELETE … reports explain; EXPLAIN ANALYZE DELETE … reports delete, because it runs.Vocabulary: select insert update delete merge create drop alter truncate grant revoke call copy explain show set begin commit rollback, plus other (parsed but unclassified) and unknown (the scanner could not finish). HTTP verbs are their own values: get post put patch head options connect trace.
access is read or write. Add require_table_match: true to also deny when the relations could not be determined — the fail-closed posture for anything genuinely off limits.
Case-insensitive, matched against the raw statement text.
RE2 syntax — no lookaround, no backreferences. A bad regex is rejected at startup, naming the listener and the rule.
Requires a top-level pii.entities block. A rule naming an entity absent from that list is refused at startup — otherwise the guardrail would look live while allowing through everything it was written to stop.
http_status is response-side, which is why an authorization filter running before the upstream can never ask it.
This is the Agentic Access path. It takes per-risk-level actions instead of an action field, and setting action on it is refused at startup.
CALL and EXECUTE report unknown rather than call, because their bodies live in the catalog and no parser can say what they touch. A rule written operations: [call] matches neither. Write operations: [call, unknown].

Actions

action on a regular rule is either empty or defer. That is the whole list.
defer with no policy.opa.url configured is refused at startup — a finding nobody reads forwards every statement while looking like enforcement.
action: warn and require_review are refused at startup. warn exists only as a per-tier action on ai_analysis rules. Human review needs a review backend the current build does not ship — see Agentic Access. For everything else, defer is how a rule stops short of deciding.

Inheritance: policy rules concatenate

A listener’s rules are evaluated first, then the top-level defaults:
config.yaml
Concatenation is safe here precisely because first-match-wins applies to denials: adding rules can never turn a deny into an allow, only change which message the user reads. policy.opa and policy.enforce replace rather than merge, and mask replaces too.

Roll out without breaking anything

1

Start observe-only

Leave policy.enforce: false. Every statement is inspected and audited, nothing is denied.
2

Validate the config

3

Read what would have been denied

4

Turn on enforcement

Set policy.enforce: true. /config confirms enforcing per listener.

Looking for guardrails on the Hoop Gateway instead? That is a different implementation — Python regex patterns configured in the web app, with Block, Warn and Require Approval actions. See Guardrails.

Next

Policy Rules Reference

Every field of every rule type, deferring to Rego, and the full findings vocabulary.

Data Masking

Control what comes back, not just what goes in.