jane@acme.com → [EMAIL]), so the model still reads a
coherent prompt while the raw value never leaves your workspace.
This page is the focused take on what masking renders, how to change
the tag, and how to mask some entities while blocking others on a single
rule. For the full engine — every rule type, stage, and route — see
the Guardrails reference, and for masking on the
request specifically, Input-stage rules.
1. Mask sensitive data llm prompts carry, with typed tags
Apii rule with the mask action detects an entity and replaces each
match with a typed redaction tag — an uppercased label in brackets
that names what was removed without revealing the value:
| Entity | Rendered tag |
|---|---|
email | [EMAIL] |
credit_card | [CREDIT_CARD] |
ssn | [SSN] |
email, phone, credit_card, ssn,
ip, iban, mac_address, jwt, aws_access_key, api_key_openai,
bitcoin_address, plus regional jp_mynumber, kr_rrn, and
cn_resident_id — each renders its own bracketed tag ([PHONE],
[IBAN], [JP_MYNUMBER], and so on). The tag is deterministic: the same
entity always renders the same label, so downstream prompts stay stable
and your logs read cleanly.
Typed tags beat a blanket
[REDACTED] for model quality. The model still
knows it’s looking at an email vs. an account number vs. a phone number,
so it can keep reasoning about the shape of the data — “reply to
[EMAIL]” stays an actionable instruction — without ever holding the
real value.2. One concrete example
Author the rule in the console under your own session — guardrail config requires Developer+, not a relay key. Add a singlepii rule
to a guardrail named pii-shield:
guardrail_id, or mark it the workspace default —
see Attach to a key), then call the
gateway with that sk-orca-... relay key:
[EMAIL] about her SSN
[SSN]” before forwarding. The upstream model never sees the address or
the number. Prove the exact rendering in the editor’s Test tab first
(no upstream call, no quota) — see
Testing & eval.
3. Override the tag with mask_with
Built-in entities render a fixed tag. Custom entities — your own
regex detectors layered on top of the built-in set — let you set the
replacement text yourself with mask_with:
What mask_with does
What mask_with does
mask_with is the verbatim replacement string for that entity’s
matches. EMP-004217 becomes [STAFF_ID]. Leave it empty and the
match renders the default tag [<UPPERCASE_NAME>] — here,
[EMPLOYEE_ID] — so a custom detector always produces a readable,
typed redaction even with no override.Custom entity fields
Custom entity fields
name (lowercase ASCII / digits / underscore, must start with a
letter), pattern (a Go RE2 regex — linear-time, no backreferences),
optional checksum (luhn validates card-shaped numbers), and
optional mask_with. Up to 25 custom entities per rule — each is
a scan over the full text, so the cap keeps the hot path linear. See
Custom PII entities.4. Mask some entities, block others — entity_actions
A single pii rule can apply different actions to different entities
via entity_actions, instead of stacking three overlapping rules. The
classic shape: mask low-sensitivity contact data, but block the
high-sensitivity fields outright.
email, phone, and ip follow the rule’s top-level mask and
render [EMAIL] / [PHONE] / [IP]; a credit_card or ssn match
instead blocks the whole request with HTTP 400
guardrail_blocked.
| Field | Rule |
|---|---|
| Keys | Must be an entity declared on the rule (built-in or custom). |
| Values | block, mask, flag, or annotate. |
A blocked request costs no quota — an input-stage block fires before
metering. A masked request goes through with the sanitized text. So one
rule can quietly redact the routine fields and hard-stop the regulated
ones, with a single attachment and no application change.
5. Mask vs. block vs. flag
Masking is one of the actions a rule (or per-entity override) can take. Pick by how much you want to disturb the traffic:mask
Redact the match to a typed tag and let the request through with the
sanitized text. The model never sees the raw value.
block
Reject the whole request with HTTP 400
guardrail_blocked. Nothing
reaches the model. Use it for data that must never transit.flag
Change nothing about the traffic — only record a match. Measure how
often a rule would fire before you enforce it.
6. Verify what got masked
Every rule that fires records a match in the workspace Matches feed — rule type, action, stage, and a detail string. The matched substring itself (the raw email, the actual card number) is recorded only when Log raw content is on, which is off by default — the privacy-conservative posture, since the whole point is to keep raw values out of your logs.7. Where to go next
- PII Shield preset — the one-rule, mask-everything starting point you can apply in a click.
- Custom PII entities — author
your own regex detectors with
mask_withand optionalluhn. - Input-stage rules — where masking runs live today, before the model and before metering.
- Block secrets — for credentials, blocking (not masking) is the right call.
- Streaming coverage — which stage/stream combinations mask vs. block today.
