← Docs

Guardrails

Guardrails are policies matched against a query/command before it runs. Each rule has a regular-expression pattern and an action: allow, deny, or require_approval. Rules are evaluated by priority (lowest number first) and the first match wins; if nothing matches, the action is allow (RBAC still applies).

Rules are created and managed in the console at app.subnomic.com.

Create a rule

  1. Go to Guardrails → New rule.
  2. Give it a name and a regex pattern (matched case-insensitively against the statement).
  3. Choose an action and severity, and a priority (lower = checked first).
  4. Save. Toggle Enabled on/off any time.

Common rules (recipes)

Copy the pattern into a new rule and pick the action. Patterns are case-insensitive, so drop also matches DROP.

Guardrails run on every query before it executes — reads included. So yes, you can gate or block plain SELECTs too (e.g. require approval to read a sensitive table). RBAC's read/write split is separate and applies first.

SQL (Postgres / MySQL)

\bdrop\s+(table|database|schema)\bdeny

Block dropping tables, databases or schemas outright.

\btruncate\bdeny

Block TRUNCATE (instant, irreversible data wipe).

\b(delete|update)\b(?![\s\S]*\bwhere\b)deny

Block DELETE / UPDATE that has no WHERE clause (whole-table change).

\b(delete|update|insert)\brequire_approval

Require approval before any write (DELETE / UPDATE / INSERT).

\b(grant|revoke|alter\s+user|create\s+role)\bdeny

Block privilege / user-management statements.

\bfrom\s+payments\brequire_approval

Require approval to read a sensitive table (e.g. payments / pii) — yes, this gates SELECTs.

\bselect\s+\*require_approval

Discourage unbounded SELECT * (gate it behind approval).

\bselect\brequire_approval

Aggressive: require approval for any read on this target.

Redis

^\s*(flushall|flushdb)\bdeny

Block wiping the whole keyspace.

^\s*(config|shutdown|keys)\brequire_approval

Gate admin / expensive commands (CONFIG, SHUTDOWN, KEYS *).

Mongo

"(drop|dropDatabase|deleteMany)"deny

Block destructive Mongo commands (the query is a JSON command document).

Allow exceptions

Because the first matching rule wins, put a narrow allow rule at a lower priority (checked first) to carve an exception out of a broader deny:

# priority 10 — allow deletes on the scratch table
pattern:  \bdelete\s+from\s+scratch\b
action:   allow

# priority 100 — deny every other delete
pattern:  \bdelete\b
action:   deny
Regex tips: \b marks a word boundary so \bdrop\b doesn't match "dropdown"; \s+ matches any whitespace; ^ anchors to the start (handy for Redis commands). Patterns match the raw statement text, so they are a safety net, not a SQL parser — keep them simple and layer deny + require_approval.

What happens

  • deny — the query is blocked, recorded, and a critical system log is written.
  • require_approval — the query is blocked unless the user holds an active just-in-time grant for that target (see Access requests). The console shows a "Request access" button.

Guardrails currently apply to the database console — the enforcement seam the rest of the control plane builds on.

Permissions

guardrail.read guardrail.manage