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:

AxisWhat it looks forSetting
DirectInstructions in the prompt itself that try to override your system prompt or exfiltrate itpi_mode
IndirectInjected instructions arriving inside retrieved content, a tool result, or a pasted documentpi_indirect_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:

ModeBehavior
offThe axis is bypassed. No screening, no alerts, no enforcement.
alertScreening runs on every request and emits alerts for detections, but never blocks. Use this to measure detection rate before enforcing.
blockDetections are enforced. The request is blocked, redacted, rerouted, or escalated based on your action configuration.

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.

ThresholdDefaultMeaning
pi_block_threshold0.57Classifier score at or above which a prompt is recorded as a detection
pi_pass_threshold0.30Classifier score at or below which a prompt is recorded as clean

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:

ThresholdDefaultMeaning
pi_tier2a_block_threshold0.60Heuristic confidence that a segment carries injected instructions
pi_tier2b_block_threshold0.45Embedding similarity to known indirect-injection patterns

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:

ActionEffect
observeRecord the detection only. No change to the request or response.
redactReplace the flagged span with a placeholder before sending it onward
routeReroute the request to a “safer” vendor configured via pi_safer_vendor_route
blockReject the request with a 4xx error
escalateBlock the request and mark the alert as escalated for human review

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 route action, 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 400 with a stable signal you can match on:

{
"error": {
"type": "invalid_request_error",
"message": "Request blocked: prompt injection detected.",
"code": "pi_blocked"
}
}

Output blocks return the same shape with a pi_output_blocked code. The stable detection signal is the code field (pi_blocked or pi_output_blocked), which doesn’t change across releases.


FAQ

The classifier sidecar adds a few milliseconds per request, negligible compared to LLM inference. The classifier runs in parallel with policy resolution where possible.

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.

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.

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.

Every request gets a pi_score field on its log entry, regardless of mode. That means you can backfill an analysis even if you ran in off mode. Re-enable alert and the score starts populating.


Next steps