New: Agent approvals, red teaming and model scanning. See how
MITRITY
Docs / Security / Injection Detection

Injection Detection

Injection detection finds prompt injection in your agents' actions in real time, and acts on it before the compromised instruction reaches its target.

Prompt injection is one of the most critical security threats to AI agents. An attacker crafts input that overrides the agent's instructions and makes it perform unintended actions: exfiltrate data, bypass access controls or execute malicious operations.

Overview

MITRITY inspects agent actions for prompt injection indicators, using three detection layers. When it detects a potential injection, the system:

  1. assigns an injection probability score (0.0 to 1.0);
  2. identifies matched patterns that describe the injection technique;
  3. creates an injection event in the audit log;
  4. takes the action for the detection method that fired: block, alert or log, as the policy's injection mode sets it.

Injection detection runs on every scanned agent action that the gateway intercepts, before policy rules are evaluated. A blocked injection therefore stops the action without any policy matching it.

Detection Methods

MITRITY scans with three layers: pattern matching, statistical analysis and an ML classifier. Each layer produces its own score, and the combined score is the injection probability.

Pattern Matching

Rule-based detection, using MITRITY's built-in library of known injection patterns. The edge lowercases the input and matches these categories. A pattern hit scores 0.9.

Pattern CategoryDescriptionExamples
instruction_overrideAttempts to override the agent's instructions"Ignore previous instructions", "New instructions:", "You are now"
system_promptSystem-prompt markers inside the input<|im_start|>system, <system>, [INST], <<SYS>>, "### System", "System:"
role_hijackingAttempts to change the agent's role"Act as a …", "Pretend to be …", "Your new role", "From now on you …"
exfiltrationInstructions to send data out"Send all data to …", "exfiltrate", "export all"
separator_attackDelimiters that open a new instruction blockA code fence labelled system or instructions, <instruction> or <prompt> tags, a "system" or "role" key in JSON
encodingInstructions hidden by encodingBase64 blocks that decode to a known injection phrase, zero-width characters

An event's matched_patterns names each hit as <category>:<name>, for example instruction_override:ignore-previous, encoding:base64-ignore-previous or encoding:zero-width-characters.

Statistical Analysis

This layer looks at statistical properties of the input, to catch injection that does not match a known pattern. Inputs shorter than 50 characters are not analyzed.

Signals analyzed:

  • Entropy shift: a large difference in character entropy between the first and the second half of the input
  • Instruction-like text: a high share of imperative, command-like verbs
  • High entropy: very high character entropy overall, as encoded or obfuscated content has

ML Classifier

The third layer reuses the edge's local ML model, DriftGuard, rather than a dedicated injection classifier. It runs only when both of these are true:

  • the edge runs with ml.enabled (off by default) and a model loaded;
  • the injection settings the control plane sends turn ml_classifier on.

The control plane sends ml_classifier: false in every mission profile (see Configuring detection), so this layer does not run in current profiles. Detections come from pattern matching and statistical analysis. When the edge runs with ml.enabled, model updates arrive with the heartbeat.

Combined Scoring

The edge combines the three scores into the injection probability, in this order:

  1. If a pattern matched, the probability is the highest of the three scores.
  2. Otherwise, if the statistical score is 0.6 or more, it is the higher of the statistical and ML scores.
  3. Otherwise, an ML score above 0 is used on its own.
  4. Otherwise, a statistical score of 0.3 or more is used on its own.

A probability below 0.3 is not a detection.

Injection Probability Scores

The injection probability is a number from 0 to 1. In current profiles, these are the scores an action can get, and what each one does:

ScoreWhat it meansAction
Below 0.3Not a detection. No injection event is createdNone
0.3 to 0.9, without a pattern hitA statistical detection. The score depends on which statistical signals firedpattern_action
0.9A pattern hitpattern_action

The score does not choose the action. Every detection in current profiles takes pattern_action, which the policy's injection mode sets, as the next section describes. The ML layer, and with it ml_action, does not run in current profiles (see ML Classifier).

Configuring detection

Injection detection is a policy feature. You set it per policy, on the policy form or through the policy API (POST /api/v1/policies to create a policy, PUT /api/v1/policies/{policy_id} to update one):

FieldForm labelValuesDefault on a new policyWhat it decides
injection_modePrompt Injection Detectionoff, log, enforceenforceThe scan on every tool-call surface. off turns the scan off everywhere, LLM prompts included
llm_injection_modeLLM prompt injectionoff, alert, enforcealertHow the scan treats a prompt sent through the LLM Gateway

A policy in the Debug override mode (override_mode: log_only) never blocks: an injection block becomes log, and enforce on LLM prompts is sent as alert.

From these fields, the control plane builds the injection settings that it sends to the edge in the agent's mission profile, as injection_config. Nothing else in them is configurable:

{
  "injection_config": {
    "enabled": true,
    "pattern_matching": true,
    "statistical_analysis": true,
    "ml_classifier": false,
    "pattern_action": "block",
    "ml_action": "alert",
    "ml_threshold": 0.7,
    "scan_targets": ["llm:*", "mcp:*", "egress:*", "delegate:*", "http:request", "builtin:*", "shell:*"],
    "llm_mode": "alert"
  }
}
FieldTypeValue the control plane sendsDescription
enabledbooleantrueSent only when injection_mode is not off
pattern_matchingbooleantrueRun the pattern matcher
statistical_analysisbooleantrueRun the statistical analyzer
ml_classifierbooleanfalseRun the ML classifier
pattern_actionenumblock; log when injection_mode is log or the policy is in DebugWhat a pattern or statistical detection does
ml_actionenumalertWhat an ML detection does
ml_thresholdfloat0.7The ML probability strictly above which an ML detection counts
scan_targetsarraythe list aboveAction-type globs to scan. An action type outside this list is never scanned
llm_modeenumthe policy's llm_injection_modeThe mode for LLM prompts (llm:* action types)

Two things are worth knowing about this model:

  • There is no hold. An injection verdict is block, alert or log. There is no alert_threshold / hold_threshold / deny_threshold triple, and no human-approval queue for injections: a blocked action is denied outright. Holds come from approval workflows on policy rules.
  • ml_threshold is the only threshold an action setting has. A pattern hit always fires pattern_action. A statistical detection needs a probability of at least 0.3, and then fires pattern_action too.

The policy's injection mode sits above all of this:

  • In log mode, a would-be block is recorded as logged, and the action proceeds.
  • In off mode, the scan does not run at all.

Prompts sent through the LLM Gateway follow llm_injection_mode (enforce · alert · off, default alert). A hit in a prompt is recorded and the call proceeds, unless the policy says enforce. The tool call that the prompt induces keeps injection_mode. off on injection_mode turns the scan off for prompts too.

Injection Events

When MITRITY detects an injection, it creates an injection event in the audit log.

Event Structure

{
  "id": "inj_evt_8k2m",
  "tenant_id": "tnt_4f9a",
  "agent_id": "agt_support-bot",
  "agent_name": "support-bot",
  "event_id": "evt_71c2",
  "action_type": "mcp:web__fetch_url",
  "detection_method": "pattern",
  "injection_probability": 0.9,
  "matched_patterns": ["instruction_override:ignore-previous", "exfiltration:send-to"],
  "flagged_content_hash": "9f2b1c…",
  "action_taken": "blocked",
  "false_positive": false,
  "occurred_at": "2026-03-01T14:30:00Z",
  "created_at": "2026-03-01T14:30:01Z"
}

detection_method is a single value (pattern, statistical, ml_classifier or combined), not a per-method breakdown. The flagged content itself is never stored. flagged_content_hash is a SHA-256 digest, so an event can be correlated without the payload leaving the edge.

Viewing Injection Events

Go to Monitoring > Injection Events in the dashboard. The injection events view shows:

  • all detected injection attempts;
  • the injection probability, and which detection method fired;
  • the matched pattern names;
  • the agent and action context;
  • the false positive status.

API Reference

List Injection Events

curl "https://api.mitrity.com/api/v1/injection-events?agent_id=agt_support-bot&limit=25" \
  -H "Authorization: Bearer mk_your-api-key"

Query parameters:

ParameterTypeDescription
agent_idstringFilter by agent
limitintegerResults per page
offsetintegerOffset for pagination

This endpoint does not support score, outcome, false-positive or date filters, so filter client-side. Injection events are not forwarded to SIEM destinations. A SIEM destination receives the agent's action and its decision, for example blocked, not the injection event's score or matched patterns.

Response:

{
  "data": [
    {
      "id": "inj_evt_8k2m",
      "agent_id": "agt_support-bot",
      "agent_name": "support-bot",
      "action_type": "mcp:web__fetch_url",
      "detection_method": "pattern",
      "injection_probability": 0.9,
      "action_taken": "blocked",
      "matched_patterns": ["instruction_override:ignore-previous", "exfiltration:send-to"],
      "false_positive": false,
      "occurred_at": "2026-03-01T14:30:00Z"
    }
  ],
  "meta": {
    "request_id": "req_inj001",
    "timestamp": "2026-03-01T15:00:00Z",
    "next_cursor": null,
    "total": 1
  }
}

Get a Single Injection Event

curl https://api.mitrity.com/api/v1/injection-events/inj_evt_8k2m \
  -H "Authorization: Bearer mk_your-api-key"

Returns the same event shape as the list endpoint.

Mark as False Positive

If an injection event is a false positive, mark it. The mark, your reason, who marked it and when are recorded on the event:

curl -X POST https://api.mitrity.com/api/v1/injection-events/inj_evt_8k2m/false-positive \
  -H "Authorization: Bearer mk_your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "false_positive": true,
    "reason": "Legitimate instruction from support workflow automation"
  }'

Response:

{
  "data": {
    "id": "inj_evt_8k2m",
    "false_positive": true,
    "false_positive_reason": "Legitimate instruction from support workflow automation",
    "false_positive_marked_by": "user_jsmith",
    "false_positive_marked_at": "2026-03-01T16:00:00Z"
  },
  "meta": {
    "request_id": "req_inj002",
    "timestamp": "2026-03-01T16:00:00Z"
  }
}

Marking an event does not change how later actions are scanned.

Get Injection Summary

curl "https://api.mitrity.com/api/v1/injection-events/summary" \
  -H "Authorization: Bearer mk_your-api-key"

Response:

{
  "data": {
    "total_events": 127,
    "blocked": 13,
    "alerted": 89,
    "by_method": {
      "pattern": 71,
      "statistical": 22,
      "ml_classifier": 18,
      "combined": 16
    },
    "by_agent": [
      { "agent_id": "agt_support-bot", "agent_name": "support-bot", "count": 78 },
      { "agent_id": "agt_chat-bot", "agent_name": "chat-bot", "count": 34 }
    ]
  },
  "meta": {
    "request_id": "req_inj003",
    "timestamp": "2026-03-01T17:00:00Z"
  }
}

False Positive Management

Common False Positive Scenarios

ScenarioCauseResolution
Support workflowsAgents forwarding user-written instructions containing command-like languageMark as FP; use Log for the agent's policy while you review
Code generationAgents generating code that includes prompt-like stringsMark as FP; use Log for the agent's policy while you review
Documentation retrievalAgents reading documentation containing injection examplesMark as FP
Multi-agent delegationAgent A instructing Agent B using natural languageMark as FP; see delegation chains

Reducing False Positives

  1. Mark false positives promptly, so that the events show which detections were wrong.
  2. Put the agent's policy on Log for Prompt Injection Detection while you measure, then switch to Enforce. Customer-facing agents see more injection-like input than backend agents.
  3. Keep LLM prompt injection on Alert for agents that read logs, web pages or tickets, which legitimately contain injection-shaped text.
  4. Monitor the false positive rate. Target a false positive rate below 5%. If it is above 10%, your settings may be too aggressive.

Integration with Policies

Injection detection is its own stage of the governance pipeline, not a policy rule. The outcome comes from the policy's injection mode, sent to the edge as pattern_action and ml_action, and it applies regardless of action type. scan_targets decides which action types are scanned at all.

There is no injection-score constraint on a policy rule. Rule constraints match the arguments of an action, and numeric constraints are integer upper bounds: see Writing Policies. A key such as injection_score_min is accepted by the API and then evaluated against nothing, so the rule matches as if it were not there.

Order matters here. The injection scan runs before policy rules are evaluated, so a detection set to block denies the action on its own, without any policy matching it. Policies decide what happens to the actions that the scan lets through.

Best Practices

Enable Detection on All Agents

Injection attacks can target any agent, not just customer-facing ones. Keep Prompt Injection Detection on in every policy, and choose between Log and Enforce by each agent's risk profile.

Separate the two detection paths

The two detection paths already act differently. With the policy on Enforce, a pattern or statistical detection blocks, because a pattern hit is a known technique, not a guess. An ML detection only alerts (ml_action: alert), and the ML layer does not run in current profiles.

Measure what gets through, not only what gets caught

Injection events tell you what detection caught. They cannot tell you what it missed. Red Teaming runs the other half of the measurement. It sends adversarial attempts at your own routes on a schedule, and records the ones that reached their goal. A detection gap then shows up as a finding with a remediation, rather than as silence in the event stream.

Review Injection Events Daily

Review injection events daily, especially statistical detections (detection_method: statistical). No known pattern matched them, so they are the most valuable for understanding your false positive rate, and for deciding between Log and Enforce.

Correlate with DLP Events

Injection attacks often come before data exfiltration. When you see an injection event, check for matching DLP events from the same agent.

Keep the ML Model Updated

When the edge runs with ml.enabled, it receives ML model updates through the heartbeat. Make sure your gateway or sidecar keeps its connection to the control plane, so that updates arrive on time.