> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vikat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Regex

> Write organisation-specific content rules with RE2 regular expressions, and use the built-in PII patterns.

<Warning>
  Earlier revisions of this page described a `/api/guardrails/{provider}` REST API,
  guardrail profiles, rules with `cel_expression`, and linking profiles to rules.
  None of that exists. Guardrails are configured through the guardrails plugin's
  config — in the console or in `config.json`. This page has been rewritten to
  match the gateway.
</Warning>

## When to use a regex rule

A `keyword` rule matches fixed substrings. Reach for `regex` when the thing you
want to catch has a shape rather than a spelling: an internal ticket reference, a
customer identifier, a document classification marker, an account number format.

For credentials specifically, see
[Secrets Detection](/enterprise/guardrails/secrets-detection), which is the same
provider type with a ready-made pattern set.

## Configuration

```json theme={null}
{
  "id": "internal-refs",
  "name": "Internal references",
  "type": "regex",
  "enabled": true,
  "apply_to": "both",
  "message": "This request was blocked because it referenced internal material.",
  "patterns": [
    "(?i)\\bPROJ-[0-9]{4,6}\\b",
    "(?i)\\bCONFIDENTIAL[ -]INTERNAL\\b",
    "\\bACC[0-9]{10}\\b"
  ]
}
```

Add it to the `providers` array of the guardrails plugin config, or build it on
the **Guardrails → Providers** page.

## Writing patterns

Patterns are [RE2](https://github.com/google/re2/wiki/Syntax). This matters:

**No backtracking, lookahead or backreferences.** RE2 runs in time linear in the
input, which is why a pattern cannot hang the gateway on a crafted prompt — the
catastrophic-backtracking class of denial of service is not reachable. It also
means expressions written for PCRE may be rejected: `(?=...)`, `(?!...)` and
`\1` have no RE2 equivalent.

**Case-insensitivity is a flag, not an option.** Prefix with `(?i)`.

**Anchor with word boundaries.** `\bACC[0-9]{10}\b` avoids matching inside a
longer token.

**A rejected pattern is refused at save time**, with the reason from RE2 and the
position of the offending pattern in your list — the pattern itself is not echoed
back, because a rule as ordinary as `\w+\.go:\d+` would otherwise trip the
gateway's own error sanitiser and you would get "an internal error occurred"
instead of the reason.

If a stored policy contains a pattern that no longer compiles, the plugin drops
that pattern, keeps the rest, and reports status **degraded** — shown as a red
banner in the console. A policy running on less than it was given never appears
healthy.

## The built-in PII patterns

For common personal data, use the `pii` type rather than writing the expressions
yourself:

```json theme={null}
{
  "id": "pii-out",
  "name": "Outbound PII",
  "type": "pii",
  "enabled": true,
  "apply_to": "output",
  "categories": ["email", "ssn", "credit_card", "phone", "ip"]
}
```

<Note>
  These are five hand-written, US-centric patterns. `credit_card` matches a
  13–16 digit run and does **not** perform a Luhn check, so it will match some
  non-card digit sequences. There is no IBAN, passport, driving-licence or
  date-of-birth category, no locale support, and no way to add a category — for
  anything beyond the five, write a `regex` rule.
</Note>

## Choosing the side

`apply_to` selects what the rule inspects: `input` (the default), `output`, or
`both`. An outbound-only rule is often what you want for PII — the model
repeating a customer record is the leak, whereas a support agent typing one into
a prompt may be the job.

## Limits

* **Blocking is the only outcome.** No redaction, no log-only mode, no
  per-rule severity.
* **One policy for the whole gateway.** Rules cannot be bound to a virtual key,
  team, customer or model.
* **Which rule matched is not persisted.** The block appears on the log row as
  `policy_decision=deny` with `policy_reason=guardrails_violation`; the matching
  rule goes to the process log only.

## See also

* [Guardrails](/enterprise/guardrails) — the policy model and full coverage list.
* [Secrets Detection](/enterprise/guardrails/secrets-detection) — credential
  patterns.
