Prompt injection protection
Detect and block prompt-injection attempts before they reach the model
Prompt injection is the most common attack against LLM-backed products. Gateway screens every inbound prompt and outbound completion, surfaces detections in the dashboard, and, when configured to enforce, blocks or redacts the requests that match.
Screening runs on two independent axes, each with its own mode:
The axes are configured separately, so an organization can run direct detection in alert while indirect runs in block, or the reverse.
Modes
PI protection has three modes, set per organization:
Roll out PI protection in alert mode first. Watch the Alerts tab for a week, tune your allowlist, then flip to block.
How detection works
The direct axis
Two layers run on every inbound prompt.
The enforcement layer is a curated set of lexical patterns for known injection phrasings, each carrying its own confidence. A prompt that matches one of them at or above the axis’s sensitivity triggers the configured input action, and that is the only path to a block on the direct axis.
Alongside it, a fine-tuned DeBERTa v3 classifier hosted as a sidecar scores each prompt from 0.0 (clean) to 1.0 (almost certainly injection). The score is recorded on the request as pi_score and drives the alerts feed and any analysis you run over it, but it does not decide whether a request is rejected. Calibration against a labelled probe set found the two classes not separable at any threshold, so enforcement sits with the lexical layer instead, where a false-positive rate of zero is measurable.
pi_pass_threshold must always be less than or equal to pi_block_threshold. Raising or lowering either one changes what the alerts feed reports, not what gets blocked, so tune the allowlist rather than the thresholds when you are chasing false positives on the direct axis.
The indirect axis
Indirect injection arrives in content the model retrieves rather than in the prompt a user typed, so it is screened separately, on two signals:
Both are bounded 0 to 1 and both are enforced when pi_indirect_mode is block. Per-project overrides for either axis are covered in per-project guardrails.
Actions on detection
Two action settings control what happens when a detection crosses the block threshold:
pi_input_action: applied when the inbound prompt is flagged. Default:block.pi_output_action: applied when the model’s response is flagged. Default:redact.
Each accepts one of five values:
Allowlist patterns
Some legitimate workflows look like injection. For example, security researchers querying a model about jailbreak techniques, or a customer-support tool that summarizes spammy emails. To suppress those false positives, configure an allowlist of regex patterns. A prompt segment that matches at least one pattern is skipped before it is screened.
Limits:
- Up to 50 patterns per org
- Each pattern can be up to 200 characters
- Patterns must compile as valid Python regex (
re.compile). Invalid patterns are rejected on save.
Anchor each pattern to something specific to your traffic. A pattern broad enough to match ordinary prose, s or .* for example, is dropped when the allowlist is evaluated rather than applied, so it cannot switch an axis off while the mode still reads block. Gateway tests each entry against the empty string and against a neutral sentence containing every letter and digit, and drops the ones that match either; a genuinely specific phrase survives that test. Dropped entries are recorded on the request’s detection record, so an allowlist that is not doing what you expect is visible rather than silent.
Allowlist matches are also logged so you can audit what’s being suppressed.
Configuring PI protection in the dashboard
Open Security → Prompt injection in the Merge Gateway dashboard and configure:
- Mode for each axis (
off/alert/block) - Direct-axis sensitivity, and the classifier’s block and pass thresholds
- Indirect-axis heuristic and similarity thresholds
- Input and output actions
- Allowlist patterns
- A “safer” vendor for the
routeaction, if used
Only org members with the Manage security rules permission can change PI settings. Every change is written to the audit log.
Security alerts
In alert and block modes, every detection generates a security alert visible under Security → Alerts in the dashboard. Each alert includes:
- Timestamp and request ID
- Mode at the time of the event (
alert/block) - Classifier score and the configured thresholds
- The action that was applied (
observe,redact,route,block,escalate) - The triggering segment of the prompt or completion
Alerts are indexed in the same store as the request log, so you can filter by customer, project, or API key when investigating a spike.
The full triggering text is stored on the alert by default. If you handle sensitive prompts, set pi_log_full_text_on_block: false to redact the text from the alert record while keeping the metadata.
What a blocked request looks like
When PI protection blocks an inbound prompt, Gateway returns HTTP 422 with a stable signal you can match on:
The stable detection signal is type: "blocked_by_pi_protection", which doesn’t change across releases. code names which rule fired: pi_block_threshold for a direct-injection score over your threshold, and pi_indirect_* codes for the indirect axis. On a streaming request the block arrives as the same 422 JSON body, since it happens before the first token.
Reading the score on each response
Set include_guardrails_metadata: true on a request (or send the include-guardrails-metadata: true header) and the response carries a guardrails.prompt_injection object with the mode, the action taken, the maximum direct-injection score next to your block_threshold, which input segment produced it (by id and kind, never by text), the indirect-injection signals, and the output-side credential scan result. It is on blocked 422 responses as well, beside error. In alert mode this is how you see, per request, what block mode would have done.
One trade to know about: in alert mode the scan normally runs after the response is sent, because it never changes the outcome. Asking for the object runs it on the request path for that one request, within the same bounded budget as block mode and the same small pool of scan slots alert-mode scoring already uses. When the budget runs out or every slot is busy, the response says so (skipped_reason of alert_timeout or saturated) instead of delaying the request. Leave the flag off where latency matters and turn it on where you are measuring. Requests that do not set the flag are unaffected.
FAQ
Does PI protection add latency?
The classifier sidecar adds a few milliseconds per request, negligible compared to LLM inference. The classifier runs in parallel with policy resolution where possible.
What happens when the classifier sidecar is unreachable?
By default, Gateway fails open: if the sidecar errors or times out, the request proceeds as if no detection occurred. Set pi_fail_closed: true to reject the request instead. This is appropriate for high-stakes workloads where any inference is unacceptable when scanning is degraded.
Can I tune the thresholds per project or per customer?
Per project, yes. A project can override the modes, thresholds, output action, fail-closed behavior, and allowlist patterns; anything it does not set inherits the organization value. Configure it on the project’s Configuration tab or over the API, see per-project guardrails. One limit worth knowing: a project named per request, with the project_id body field or the X-Project-Id header, can only tighten the organization policy, since a caller that names its own project could otherwise ask for your protections to be turned off. A project pinned to an API key can relax it.
Per customer, no. Use customer-scoped blocklist rules to vary routing decisions by customer, but the classifier settings themselves resolve at the organization and project level only.
How is PI protection different from DLP?
DLP scans for structured sensitive data like SSNs, credit cards, and API keys. PI protection scans for adversarial intent: prompts trying to override system instructions, leak training data, or exfiltrate prior conversation. Run both for full coverage.
Where is the detection score stored?
Every scanned request records its scores on its request log entry (pi_score_tier1 for direct injection, pi_score_tier2/pi_score_tier2b for the indirect signals) and, when it clears the alert floor, in the Security Alerts feed. Scores are only produced while protection is in alert or block mode; a request served in off mode has none to backfill. To see the score on the response itself, set include_guardrails_metadata: true on the request.