Get the latest, first
arrowBlog
Azure OpenAI Prompt Injection: What Prompt Shields Misses

Azure OpenAI Prompt Injection: What Prompt Shields Misses

Aug 18, 2026

Yossi Ben Naim
VP of Product Management

Key takeaways

  • Which agents does the Azure OpenAI guardrail system actually cover? Only agents built in Foundry Agent Service receive the agent-level controls, and those controls are in preview. An agent your own team wrote against the Azure OpenAI endpoint runs under the model deployment's guardrail, which has two intervention points available to it: user input and output.
  • Why do the controls that run differ from the controls you configured? Spotlighting and groundedness are documented as applicable to models and not to agents. Where an agent guardrail exists it fully replaces the model's rather than merging with it, so a stricter model-side setting disappears the moment an agent guardrail is assigned without the same controls.
  • What is left once every switch is on? Content inspection at four points in the conversation. The action that produces the incident happens after the last of them, inside your subscription, using an identity you provisioned, which leaves deviation from the agent's own behavior as the signal still standing.

Azure OpenAI’s prompt injection controls are scoped to a boundary, and most production agents sit partly outside it.

The controls themselves are sound. Prompt Shields is a real classifier, trained on known injection techniques across multiple languages and updated as new ones appear. Spotlighting came out of published Microsoft Research work with a measured reduction in attack success rate. The four intervention points cover the places a conversation can be poisoned, which is the job they were built for.

The scope itself is published. Microsoft documents which risks apply to agents, which intervention points apply to agents, and how an agent’s guardrail resolves against its model’s guardrail. Three tables on one page. Read separately they look like release notes. Read together they are a coverage map, and the map has three edges that a team who has turned Prompt Shields on would not expect to find.

Which agents the system covers at all. Which controls survive assignment to an agent. And what the whole system is structurally unable to see.

Your guardrail scope is decided by which product built your agent

Three build paths dominate production Azure deployments, and each one receives a different amount of the guardrail system.

The first is an agent your team wrote: a Python or .NET orchestrator running on AKS or Container Apps, holding its own tool registry, calling the Azure OpenAI endpoint over the Chat Completions or Responses API. The second is a Foundry standard agent, where the runtime is injected into a delegated subnet in your own virtual network and you bring your own storage, search and Cosmos DB. The third is a Foundry hosted agent, where each session runs in a VM-isolated sandbox that Microsoft operates and connects to your network.

The guardrail system currently applies to agents developed in Foundry Agent Service. Agents registered in the Foundry Control Plane by other means do not receive it.

That single sentence decides most of your coverage, because two of the four intervention points are agents only. Tool call, which scans the action and data the agent proposes to send to a tool, and tool response, which scans what comes back, are both unavailable to models. A model deployment has user input and output, and nothing else.

The tool plane is where the coverage question gets expensive, because Foundry agents can reach tool servers your organization did not write. An MCP server’s tool descriptions and responses arrive as content the agent trusts by default, which is its own injection surface with its own failure modes, and the intervention point that would inspect it is the one models do not have.

So the first build path, which is the most common one in Kubernetes shops, runs on two intervention points. Everything your orchestrator assembles arrives as user input and everything the model returns leaves as output.

Document attack detection runs at the user input point, so retrieved context that your orchestrator pastes into the prompt does get scanned for indirect injection. That is genuine coverage of the retrieval surface and it is worth having.

The qualifier is where the coverage stops being a platform property. Whether a tool response gets inspected depends entirely on whether your orchestrator resubmits it in a shape the shield sees, which is an application design decision made by whoever wrote the agent loop. You may have that coverage. Confirming it means reading your own agent loop, because the guardrail configuration does not describe what your orchestrator chose to resubmit.

The controls that run on your agent are a subset of the controls you configured

Configuration and execution come apart in three documented places.

Start with risk applicability. Microsoft publishes a table of which risks apply to models and which apply to agents. Spotlighting is marked applicable to models and not applicable to agents. Groundedness is marked the same way.

Spotlighting is the control built specifically for the problem this article’s keyword describes. It tags third-party document content with lower-trust formatting so the model treats it as data, and it is the technique Microsoft Research published for exactly the indirect case. It does not run on your Foundry agent. It is also still in preview, only available for models used through the Chat Completions API, and turned off by default.

For agents, annotate-only is not an available action. The action table lists annotate as applicable to models and not to agents, leaving annotate and block as the only option. Where an agent control does run, it blocks. That is a stronger default than the model side, where a shield can sit in annotate mode reporting detected: true and filtered: false on every request while passing the payload through untouched.

The override rule catches the teams who configured everything correctly. An agent’s risks are detected based on the guardrail assigned to the agent and not the guardrail of its underlying model, and the agentic guardrail fully overrides the model’s. There is no merge.

Microsoft works the example on its own page. A model deployment has violence detection at High for user input and output. An agent using that model has a guardrail set to Low for user input and output, with no controls at all for tool calls and responses. The documented result: tool calls generated internally by the model, including the content sent to the tool during execution, are not scanned. The response from the tool is not scanned. A stricter parent setting does not survive the child assignment.

The inheritance rule turns that example into the default case. If no custom guardrail is assigned to an agent, the agent inherits the guardrail of its model deployment. A guardrail authored against a model deployment has no reason to carry tool call or tool response controls, because neither intervention point applies to models. Inherit that guardrail onto an agent and the agent runs with its tool plane unscanned.

The default assignment path is also the one with the largest hole. Microsoft’s own troubleshooting section lists the symptom, “tool calls not being scanned,” with the cause given as intervention points not configured in the guardrail.

Microsoft’s security response team describes Prompt Shields as a probabilistic classifier-based approach. That characterization comes from the people who built it. The recommended fixes for false positives are equally candid: move a control from block to annotate, and exempt trusted input sources from document attack scanning. Both are reasonable engineering advice, and both reduce what the control stops.

None of this makes the guardrail layer worthless. It removes the opportunistic volume, and volume you never receive is volume nobody has to triage. What it cannot do is carry the load against a payload written for your stack, which is the finding that holds across every published defense tested against an adaptive attacker rather than a static benchmark.

Four intervention points read content, and the breach is an action

Every intervention point in the system evaluates content. User input reads the prompt. Tool call reads what the agent proposes to send. Tool response reads what comes back. Output reads the completion.

The incident happens after the fourth one.

An agent that has accepted an injected instruction is not compromised the way an exploited process is compromised. It is redirected. This is coercion: a trusted input steering an agent’s authorized capability toward someone else’s goal. The agent keeps its own identity, calls tools it is registered to call, and reaches endpoints it is permitted to reach. OWASP ranks prompt injection first among LLM application risks for this reason, and the publicly documented cases all share the property: identity valid, permission valid, destination approved, content screened.

On Azure that sequence has a specific shape. The workload asserts its Entra managed identity through workload identity federation. It reads a secret from Key Vault under a role assignment somebody granted for a legitimate reason. It queries a Cosmos DB container it queries every day. It opens an outbound connection to a destination that resolves and connects.

Run your controls against that sequence and watch them return valid. Azure RBAC returns valid, because the role assignment is real. The federated credential returns valid, because the subject claim matches. Network policy returns valid, because the destination is reachable by design. Each control was built to catch an actor who should not be there, and the actor is one you provisioned.

Hosted agents do get network egress controls in preview, which govern the outbound connections an agent makes so it reaches only destinations you allow. That is real containment and it belongs in the stack. It is also a destination control, and the destinations that matter in a coercion are usually the ones already on the list, because an agent whose job is calling an API needs to call that API.

What changes during a coercion is smaller and harder to fake. The agent stops behaving like itself.

The control that survives a missed injection measures execution

Measuring that requires a definition of normal belonging to one specific agent.

ARMO builds it as Application Profile DNA (APD™): a per-agent behavioral baseline assembled from kernel-level observation of what the workload actually does. Which processes it runs. Which files it touches. Which system calls are routine for it. Which destinations it reaches. Which tools it invokes, and in what order. The baseline comes from execution rather than from a manifest, which matters because declared permissions describe a ceiling and the ceiling is the space coercion operates inside.

The entry path is not one of the baseline’s inputs. A secret read outside the agent’s observed pattern, followed by an outbound connection to a destination with no history, scores as a deviation whether the instruction arrived at user input, at tool response, or through a surface that has no intervention point at all. That property is what makes one control sufficient for surfaces that enter through different doors and converge in the same context window. The control never had to know which shield missed.

Where this can be instrumented follows the same split as your guardrail scope, and it runs in the opposite direction. An agent on AKS or your own compute gives you the node, so kernel-level observation through an eBPF sensor is available and the guardrail system covers you least. A fully managed hosted agent gives you more of the guardrail system and none of the node, which pushes your instrumentation to the resources the agent reaches rather than the process itself. The build path decision you made for velocity set both of these, and it is worth writing down which side of it each agent sits on.

The standing objection to any blocking control is that it will eventually block the wrong thing during month-end close. Enforcement answers it by arriving in two stages. In Audit, every action the policy would have stopped gets recorded and nothing is blocked, so the quarterly reconciliation job surfaces as a log line instead of an outage. Enforcement graduates per agent once the audit log is clean, which is the progressive path from observation to enforcement applied one workload at a time.

Credential handling closes the loop from the other side. When an agent holds substituted keys and real credentials are supplied only for sanctioned operations, an action that clears every other check still fails at the point where it tries to use something real.

The good news is that none of this touches reasoning quality. Nothing enters the agent’s context and nothing sits between the model and its tools as a classifier, so the space of things the agent can consider is exactly as wide as you built it. What narrows is execution, scored against that agent’s own history. Overhead runs at 1 to 2.5% CPU and roughly 1% memory with no sidecars and no code changes, so what your platform team is approving is a DaemonSet on the node pools that run agent workloads.

Audit your guardrail scope before you buy another filter

The exercise is five columns and one afternoon, and it answers the question a board or an auditor asks first: which of your agents are covered, and by what.

For each agent calling Azure OpenAI, write down the build path: custom orchestrator, Foundry standard agent, or Foundry hosted agent. Then the assigned guardrail, and specifically whether it was authored against the model deployment or against the agent, because an inherited one carries no tool-plane controls. Then the intervention points that guardrail actually has controls for. Then whether spotlighting is enabled at the model and therefore absent at the agent. Then reach.

Then verify rather than assume. Each request with a shield enabled returns annotation results carrying detected and filtered, and those two booleans are the ground truth about what ran. detected: true with filtered: false is a control in annotate mode, which is a record and not a stop. Nothing returned at an intervention point is that intervention point telling you it has no controls.

Reach is the column that decides the ranking, and on Azure it is concrete. Every role assignment on the agent’s managed identity. Every Key Vault the identity can read, and at what scope. Every storage container and Cosmos DB collection it can write to that something else later reads. Every destination its egress permits. Every other agent it can hand context to, because a delegation edge is an exit, and an instruction that survives one hop can survive several.

Rank by reach. The instinct runs the other way, toward the agent handling the most attacker-controlled text, because that is the one most likely to be injected. Two agents in the same subscription can read identical hostile input and produce entirely different Tuesdays. The one whose managed identity carries a single reader role on a public content index gives someone a wrong answer. The one whose identity carries Key Vault Secrets User and a write on the finance container gives you something to disclose.

On whatever reach stays open, the signal lives in the distance between permitted and actual: the targets this agent has genuinely used against the far larger set its role assignments allow, the tool orderings it has run before, the credentials it exercises rather than merely holds. We have set out the telemetry that detection chain needs, stage by stage.

The guardrail layer owns the arrival rate and it does that job well. The layer underneath owns the consequence, and on Azure that layer runs in your subscription, on your nodes, under your identities. Both tiers together are what securing an agent against prompt injection actually requires, and the second one is the one your guardrail configuration cannot staff for you. Cloud-native security for AI workloads scores a coerced agent against its own baseline and contains it before the sequence completes. Book a demo and bring your own guardrail configuration to it.

Frequently Asked Questions

Do Prompt Shields protect agents the same way they protect models?

Not identically. Microsoft’s risk applicability table marks user prompt attacks and indirect attacks as applicable to both, and marks spotlighting and groundedness as applicable to models only. Agent guardrails are also still in preview. Treat the model-side configuration you tested as an upper bound on what your agent receives, then verify against the assigned guardrail rather than the deployment’s.

Are tool calls and tool responses scanned by default?

No. Both are agent-only intervention points, both are in preview, and both require controls explicitly configured in the guardrail assigned to that agent. If the agent inherited its model deployment’s guardrail, those controls almost certainly do not exist, because neither point applies to models and nobody would have authored them. Microsoft lists “tool calls not being scanned” as a documented troubleshooting symptom with exactly that cause.

Does any of this apply if my agents are not built in Foundry Agent Service?

The agent-level controls do not. An orchestrator you wrote against the Azure OpenAI endpoint runs under the model deployment’s guardrail, which gives you user input and output. Retrieved content your code places in the prompt is scanned for indirect attacks at the user input point, which is real coverage of the retrieval surface. Anything your agent does after the completion returns is outside the system entirely.

Does runtime behavioral detection replace Prompt Shields?

No. The two answer different questions and removing either one leaves the other doing work it was not built for. Prompt Shields reduces how many injected payloads reach the model at all, which lowers the number of events anything downstream has to adjudicate, and it is the only tier that can stop an attempt before the agent acts. Behavioral scoring starts where that tier’s residual begins, which on a probabilistic classifier facing a motivated attacker is never zero. Budget for both and expect them to cost differently.

What telemetry do I need before per-agent baselines work on Azure?

Process execution, system calls, file access and network connections attributable to the specific agent workload rather than the pod or namespace, plus tool invocation records and identity attribution that resolves through workload identity federation to the Entra managed identity the agent actually asserted. On AKS, an eBPF sensor at the node supplies most of that without touching application code. Correlate it with Kubernetes deployment events, because a behavioral shift arriving with a new image digest is drift and the same shift with no deployment behind it is a deviation.

Close

Your Cloud Security Advantage Starts Here

Webinars
Data Sheets
Surveys and more
Group 1410190284
Ben Hirschberg CTO & Co-Founder
Rotem_sec_exp_200
Rotem Refael VP R&D
Group 1410191140
Amit Schendel Security researcher
slack_logos Continue to Slack

Get the information you need directly from our experts!

new-messageContinue as a guest