Block secrets
The most common thing an organisation wants from an LLM firewall is this: do not
let a developer paste a production connection string into a chat window. That is a
blocked_pattern rule with a block action.
vulnetix ai-firewall policy guardrail no-connection-strings \
--rule-type blocked_pattern \
--action block \
--pattern '(?i)postgres://\S+' \
--priority 10 \
--enable
Now this request is refused:
“why does
postgres://svc:hunter2@db.internal:5432/prodtime out?”
{
"error": {
"message": "request blocked by AI firewall policy: content matched pattern for policy \"no-connection-strings\"",
"type": "policy_violation",
"code": "request_blocked",
"blocked_by": "no-connection-strings"
}
}
And this one is not:
“why would a postgres connection from our service time out?”
The developer still gets their answer. The credential never left.
--action flag first. Run it for a week, look at what it actually
caught, then switch it to block. A block rule that fires on legitimate work
gets the whole firewall switched off. See rollout.Why block rather than redact
For a secret, block is almost always right and redact almost always wrong.
Redaction rewrites the match to [REDACTED] and lets the request through — so the
developer gets a useless answer about a redacted string, and does not know why.
They will assume the model is being unhelpful and rephrase until it works, possibly
around your rule.
A block is loud. It names the rule that fired. The developer learns the policy
exists in the moment it matters. Save redact for data the model does not need in
order to be useful — which is what PII redaction is for.
A pattern library
These are starting points, not a finished policy. Test each one against your own
traffic at flag before you block on it — every organisation has legitimate text
that looks like a secret.
Database connection strings
(?i)(postgres|postgresql|mysql|mongodb(\+srv)?|redis|amqp)://[^\s'"]+:[^\s'"]+@
Requires a user:password@ to be present, so it fires on credentialed URLs and not
on postgres://localhost/dev.
Cloud provider keys
AKIA[0-9A-Z]{16}
AWS access key ID.
AIza[0-9A-Za-z_\-]{35}
Google API key.
Private keys and certificates
-----BEGIN [A-Z ]*PRIVATE KEY-----
The single highest-value, lowest-false-positive rule on this page. There is no legitimate reason for a private key to be in a prompt.
Tokens
gh[pousr]_[0-9A-Za-z]{36,}
GitHub personal access, OAuth, user-to-server, server-to-server, and refresh tokens.
xox[baprs]-[0-9A-Za-z\-]{10,}
Slack tokens.
sk-[A-Za-z0-9]{20,}
OpenAI-style provider keys. Worth blocking: a developer pasting a provider key into a prompt is both a leak and a sign they have misunderstood the two keys.
eyJ[A-Za-z0-9_\-]{10,}\.eyJ[A-Za-z0-9_\-]{10,}\.
A JWT. Note this matches the shape, so it will catch example tokens in
documentation too — a good candidate for flag rather than block.
Internal infrastructure
(?i)[\w.\-]+\.(internal|corp|local|intranet)\b
Adjust the suffixes to your own naming. This one is about not leaking your network
topology into a third party’s logs. Usually a flag, sometimes a redact.
Composing with priority
Rules run lowest priority first, and a block short-circuits. So put your
highest-confidence, highest-severity rules at the lowest numbers:
vulnetix ai-firewall policy guardrail no-private-keys \
--rule-type blocked_pattern --action block \
--pattern '-----BEGIN [A-Z ]*PRIVATE KEY-----' --priority 1 --enable
vulnetix ai-firewall policy guardrail no-connection-strings \
--rule-type blocked_pattern --action block \
--pattern '(?i)(postgres|mysql)://[^\s]+:[^\s]+@' --priority 10 --enable
vulnetix ai-firewall policy guardrail flag-internal-hosts \
--rule-type blocked_pattern --action flag \
--pattern '(?i)[\w.\-]+\.(internal|corp)\b' --priority 50 --enable
Regex caveats
Patterns are RE2. There is no lookahead, no lookbehind, and no backreferences — by design, because RE2 cannot be made to hang on a hostile input. If you are porting patterns from a secret scanner that uses PCRE, some will not compile.
A rule whose pattern does not compile is silently skipped. It will sit in your
policy looking enabled and enforce nothing. This is exactly why
vulnetix ai-firewall status compiles your patterns locally and reports
guardrail_pattern_invalid — run it after any rule change.
See the regex reference.
Related
- Regex reference — the RE2 subset, and why.
- Rollout — flag → redact → block.
- Tuning false positives — when a block rule is too eager.
vulnetix secret-scan— catching secrets in the repository, before they ever reach a prompt. The firewall is the last line, not the first.