Skip to content
⚠️ Before You Start
Risk: High
Duration: 30 minutes to contain, 1-3 days to close
Last Validated: Not yet validated (draft)
Kind: Runbook
Risk Note: High (delay lets the agent repeat the action across tenants)

Respond to an agent acting outside its permission envelope

Draft outline: not validated

Drafted with AI from official sources on 16 Oct 2026. Checked and verified against official sources on 10 November 2026. Do not use on a live system until it is written, dry-run by someone other than the author and signed off (planned 2026-11-11). Author: Prasanna · dry-run: Sivaraj · sign-off: James. Work items: AGT-08-T13, AGT-08-T14, AGT-08-T15, AGT-08-T16.

1. Summary

Use this runbook when an agent takes, or tries to take, an action outside its permission envelope. Typical causes are a prompt injection, a misconfigured grant or a change in model behaviour. Start it from the first report, before the root cause is known. It contains the agent first, then preserves the evidence, finds the affected runs, fixes the cause and restores permissions through PB-AGT-08-03.

The default path uses two stops together: the kill switch the agent reads, and removal of the role assignments behind the misused action. The target is containment within 30 minutes (team default). Facts checked against official documentation on 10 November 2026. Prompt Shields scanning of tool responses is preview; check the current API version in the docs.

Risk: High (delay lets the agent repeat the action across tenants). Typical duration: 30 minutes to contain, 1-3 days to close.

2. When to use and when not to

Use this runbook when:

  • An agent calls a tool on its deny list, or a tool that needs approval without approval.
  • An agent takes an action outside its envelope, for example after a prompt injection, a wrongly granted role or a model change.
  • A report, alert or customer says an agent did something it should not have, and you do not yet know why.

Do not use it when:

  • You are only changing permissions on purpose. Use PB-AGT-08-03.
  • You are defining or reviewing an envelope before launch. Use PB-AGT-08-01.
  • You are adding the allow-list and approval gate to the agent code. Use PB-AGT-08-02.
  • The agent is stuck in a loop or burning budget but has not left its envelope. Use PB-AGT-09-01.
  • A tool or model is down and the agent is failing safely. Use PB-AGT-09-02.

3. What you must know first

  1. Contain first, investigate second. Stop the actions before you look for the cause (team guidance). A tool that is still callable can repeat the harm while you investigate.
  2. Two stops that do not depend on each other. The kill switch is a flag or setting that the agent code reads, so it fails if the agent caches the value or a worker ignores it. Removing the role assignments behind the action stops cloud access even if the code keeps running. Use both. Source: Best practices for Azure RBAC (access is limited by roles and scopes).
  3. az role assignment delete removes every match. The command deletes all role assignments that satisfy the query. The docs say to run az role assignment list first with the same arguments. The --yes option is currently a no-op, so nothing asks you to confirm. list shows only subscription-scoped assignments unless you add --all. Source: az role assignment (Azure CLI).
  4. App Configuration commands need the right sign-in and role. The default --auth-mode is key. Use --auth-mode login so that Microsoft Entra ID authorises the call. Writing a feature flag needs the App Configuration Data Owner role. After a role assignment, allow up to 15 minutes for it to take effect, so assign the role before an incident, not during one. Sources: az appconfig feature (Azure CLI); Access Azure App Configuration using Microsoft Entra ID.
  5. Entra Agent ID can stop agents at scale. Disabling an agent identity blueprint prevents all its agent identities from authenticating. Conditional Access policies can also target every agent identity from one blueprint. Source: Agent identity blueprints in Microsoft Entra Agent ID.
  6. Traces are your evidence, and they expire. Foundry tracing records tool executions as execute_tool spans, with the attributes gen_ai.tool.call.arguments and gen_ai.tool.call.result. The OpenTelemetry GenAI conventions are in development status and can change. Retention follows your Application Insights configuration. Reading traces needs the Log Analytics Reader role. Trace content can be sensitive, so apply the same access controls as production logs. Sources: Agent tracing overview - Microsoft Foundry; Set up tracing for AI agents in Microsoft Foundry.
  7. Name the risk in the review. Prompt injection (LLM01:2025) and Excessive Agency (LLM06:2025) are in the OWASP Top 10 for LLM Applications 2025. OWASP also publishes a Top 10 for Agentic Applications 2026. Its entry names are in a downloadable document. Prompt Shields can detect document attacks, which is how a prompt injection often arrives through a retrieved document.

4. Prerequisites and access

Arrange these before an incident. Several cannot be created quickly during one.

Item Detail
Roles for containment App Configuration Data Owner on the App Configuration store (to switch a flag). A role that can create and delete role assignments at the agent's scopes, held by the on-call engineer. Only users with Owner or User Access Administrator can make role assignments (App Configuration documentation). Assign these in advance because of the propagation delay.
Roles for evidence Log Analytics Reader on the Application Insights resource connected to the project. Privileged Monitoring Data Reader as well if the tables are protected.
Kill switch A flag or setting that the agent reads (for example agent-actions-${AGENT}), tested in the last quarter (team default). The autonomyTier setting in PB-AGT-08-02 is the same idea.
People An incident channel and an on-call rota that includes a security engineer. A contact list for the business owner and the client.
Records Access to traces, activity logs and the approval log. The permission envelope (agent-policy.json) and the last signed-off version.
Tools Azure CLI signed in with Microsoft Entra ID.
export APPCONFIG_NAME="${APP_CONFIG_STORE}"
export AGENT="${AGENT_NAME}"
export AGENT_PRINCIPAL_ID="${AGENT_OBJECT_ID}"
export INCIDENT_ID="${INCIDENT_NUMBER}"
export MISUSED_ROLE="${ROLE_NAME_OR_ID}"
export MISUSED_SCOPE="${SCOPE_OF_THE_ASSIGNMENT}"

5. Decide your approach

Always flip the kill switch first. Then choose how hard to cut access.

Situation Contain with Why
The agent is still acting and you do not know why Kill switch, then remove the role assignments behind the misused action Two independent stops.
The kill switch did not stop the actions Remove the role assignments now Roles are the hard stop. Fix the flag refresh later.
Many agents built from one blueprint show the same flaw Disable the Entra Agent ID blueprint, after checking the blast radius One action stops every agent of that kind.
The agent identity is shared with another application Remove only the role assignment behind the misused action. Do not disable the identity Disabling it would break the other workload. Give each agent its own identity afterwards (PB-AGT-08-01).
Only one tool was misused Remove that tool's role, and deny the tool in the envelope file The rest of the agent can keep working in suggest-only mode.
The trigger was injected content from one source Contain as above, then quarantine the source The source can hit other runs.

6. Steps

Placeholders: ${PLACEHOLDER} (what it is, for example ${AGENT} is the agent's name). Never paste keys or tokens into tickets or chat. Write the time of each step in the incident log.

Stage 1: Contain (target 30 minutes, team default)

Step 1. Declare the incident and name the lead. Open the incident channel. Name the incident lead, the security engineer and the agent lead. Note the start time.

Verify: the channel exists, the three roles have names, and the start time is written down.

Step 2. Flip the kill switch. Turn off the flag the agent reads.

az appconfig feature disable --name "${APPCONFIG_NAME}" --feature "agent-actions-${AGENT}" --auth-mode login --yes

Verify: az appconfig feature show --name "${APPCONFIG_NAME}" --feature "agent-actions-${AGENT}" --auth-mode login shows the flag as off. The agent makes no new tool calls after that time (step 4).

Step 3. Cut the agent's access. Record its role assignments first, then remove the one behind the misused action.

This step removes access and cannot be undone by the command

Removing a role assignment stops the agent's cloud access straight away for that scope. If another application shares the identity, it loses access too. Run list first and read the result before you run delete. To undo, restore the assignment from the saved record through PB-AGT-08-03. See section 8.

az role assignment list --assignee-object-id "${AGENT_PRINCIPAL_ID}" --all -o json > "incident-${INCIDENT_ID}-roles.json"
az role assignment delete --assignee-object-id "${AGENT_PRINCIPAL_ID}" --role "${MISUSED_ROLE}" --scope "${MISUSED_SCOPE}"
az role assignment list --assignee-object-id "${AGENT_PRINCIPAL_ID}" --scope "${MISUSED_SCOPE}" -o table

Verify: the saved file lists the assignments from before. The last command shows nothing left for ${MISUSED_ROLE} at ${MISUSED_SCOPE}.

Step 4. Confirm the agent has stopped. Query the agent's tool executions after the time of steps 2 and 3.

Verify: no new execute_tool spans for the agent over a quiet period (team default 15 minutes). If any appear, go to the "kill switch did not stop the actions" row in section 5.

Stage 2: Preserve and assess

Step 5. Preserve the evidence. Export traces, tool-call logs and approval records for the window, before retention or redaction jobs remove them. Use snippets/ops/agent-tool-calls.kql.

Verify: the exports are saved with the time range in the file name. Retention follows the Application Insights setting, so note the retention period in the incident log.

Step 6. List every affected record, tenant and user. Use the run, tenant and tool attributes in the traces.

Verify: the list is complete. The number of misused tool executions in the list matches the number of execute_tool spans for that tool in the window. If the traces have no run or tenant attribute, record that gap and treat it as a known issue (section 9).

Step 7. Find the entry point. Decide which of these applies: injected content, a grant change, a prompt change or a model change. Check Prompt Shields detections on tool results, the role assignment change log (az role assignment list-changelogs, which defaults to the last hour, so set --start-time), and the prompt and model version history.

Verify: one entry point is named with its evidence, or marked unknown with an owner and a date.

Stage 3: Recover

Step 8. Reverse the actions where possible. Use the compensation steps in PB-AGT-09-03. Some actions cannot be reversed, such as a sent message. Record those as accepted harm and tell the business owner.

Verify: each affected record is marked reversed, not reversible or accepted, with an owner.

Step 9. Fix the cause and add a test that reproduces it. Add an evaluation case and a guard test that reproduces the incident (PB-AGT-07-02 and PB-AGT-08-02). If the entry point was a retrieved document, quarantine the source.

Verify: the new test fails on the old configuration and passes after the fix.

Step 10. Restore permissions through the change runbook. Use PB-AGT-08-03, not by hand. Restore only what the signed-off envelope allows.

Verify: the agent's role assignments match the signed-off envelope, compared with the saved incident-${INCIDENT_ID}-roles.json.

Step 11. Bring the agent back in suggest-only mode. Turn the flag on only after step 10, with the agent in suggest-only mode. Restore its autonomy tier after a clean day (team default).

Verify: in suggest-only mode, the agent makes no write calls. After a clean day, the tier is restored and the lead has signed off.

Stage 4: Close

Step 12. Write the post-incident review and update the envelope. Use snippets/docs/agent-incident-review.md. Name the OWASP risks (section 3, point 7), the timeline, the harm and the decisions. Update the envelope in PB-AGT-08-01 if it was part of the cause.

Verify: the review is filed, has a named owner for each action, and the envelope's review date is updated.

Draft snippet: Contain an agent, kill switch then access removal

#!/usr/bin/env bash
set -euo pipefail
# 1. Stop actions: turn off the flag the agent reads
az appconfig feature disable --name "${APPCONFIG_NAME}" --feature "agent-actions-${AGENT}" --auth-mode login --yes
# 2. Record the roles, then remove the one behind the misused action
az role assignment list --assignee-object-id "${AGENT_PRINCIPAL_ID}" --all -o json > "incident-${INCIDENT_ID}-roles.json"
az role assignment delete --assignee-object-id "${AGENT_PRINCIPAL_ID}" --role "${MISUSED_ROLE}" --scope "${MISUSED_SCOPE}"
# 3. Confirm nothing is left at that scope
az role assignment list --assignee-object-id "${AGENT_PRINCIPAL_ID}" --scope "${MISUSED_SCOPE}" -o table

Snippets to add:

  • snippets/ops/agent-containment.sh: Kill switch and access removal commands (bash)
  • snippets/ops/agent-tool-calls.kql: Find all tool calls by an agent in a time window (kql)
  • snippets/docs/agent-incident-review.md: Post-incident review template (markdown)

7. Monitoring and alerts

The thresholds below are team defaults, not platform recommendations. Tune them. The signals marked custom are metrics or queries that your own code and pipeline must provide.

Signal Alert when Action
Denied or unapproved high-risk tool attempts (custom, from execute_tool spans) Any attempt on a deny-listed tool Page the on-call engineer and start this runbook.
Prompt Shields document attack detections on tool results (custom, from the detection result you log) Any detection on a write-capable agent Review the run and the source document within 1 hour.
Role assignment changes for the agent identity (Azure Activity Log; check the exact operation name in the docs) Any change not made through PB-AGT-08-03 Review the change. If it was not approved, start this runbook.
Kill switch state (custom) Stopped for more than 24 hours Escalate to the agent lead for a restore decision.

8. Rollback

Containment is meant to be reversible, except for the harm already done. Undo in this order, and only after the cause is fixed.

Situation Rollback Time
Kill switch turned off Turn the flag on with az appconfig feature enable ... --auth-mode login, after step 10 and in suggest-only mode Seconds, plus the agent's flag refresh time
Role assignment removed Restore it from incident-${INCIDENT_ID}-roles.json through PB-AGT-08-03, not by hand. The create command takes --assignee-object-id, --assignee-principal-type, --role and --scope. Minutes, plus the role propagation delay
Entra Agent ID blueprint or identity disabled Enable it again, after the fix Check the docs
A wrong role was removed in step 3 Restore that one assignment from the saved record Minutes
Business actions the agent already took Compensate where possible (PB-AGT-09-03). Some actions have no rollback, such as a sent message or a completed payment that cannot be recalled Varies. Say so plainly in the review

Rollback trigger (any one): another application loses access because of step 3; the wrong role was removed; the cause is shown to be a false alarm.

9. Known issues and fixes

Symptom Likely cause Fix
Kill switch flipped but actions continue The agent caches the flag, or a worker ignores it Remove the role assignments as the hard stop and fix flag refresh
az appconfig returns an authorisation error The caller lacks App Configuration Data Owner, or the command used the default key auth mode Use --auth-mode login and assign the role before an incident. Allow up to 15 minutes after a new assignment
Too many role assignments disappeared delete removes every match, and no confirmation is asked Run list with the same arguments first. Restore from the saved record
Cannot tell which runs were affected Tool calls were not traced with run and tenant ids Add run, tenant and tool attributes to spans before re-enabling
Traces are missing for the window Sampling, retention or missing permissions Check the Application Insights retention and sampling settings, and the Log Analytics Reader role
Injection came from a retrieved document Indirect prompt injection in tool output Enable document attack scanning on tool results and quarantine the source
Identity disabled breaks other workloads The identity is shared with another application Remove only the misused role. Give each agent its own identity afterwards

10. Cost and capacity notes

  • Trace and log volume. Tracing stores data in Application Insights, which can cost money by data volume and retention. Exporting and keeping evidence adds storage. Check the current price before approval.
  • Judge and replay runs. Reproducing the incident in tests can call a judge model. Use a small sample first.
  • People. The first 30 minutes need the on-call engineer, a security engineer and the agent lead at the same time.

11. AWS and open-source equivalents

Platform Equivalent Key differences
AWS: Amazon Bedrock AgentCore Policy in AgentCore Policies are checked at the AgentCore Gateway before any tool call. To contain an agent, add a policy that forbids the tool. The enforcement sits outside the agent's code.
AWS: IAM Detach or deny the policy on the agent's IAM role
Open source A policy engine such as Open Policy Agent in front of the tool route Deny the tool in the policy. Revoke the workload identity in your identity provider.

12. Checklist

Pre-flight

  • Kill switch wired in and tested in the last quarter (section 4).
  • Containment roles assigned in advance, with the propagation delay allowed for (section 4).
  • On-call rota includes a security engineer (section 4).
  • Traces carry run, tenant and tool attributes (step 6).

Post-incident

  • Agent stopped, with no new tool calls for the quiet period (step 4).
  • Evidence exported before retention removed it (step 5).
  • Affected records, tenants and users listed (step 6).
  • Permissions restored through PB-AGT-08-03 (step 10).
  • Post-incident review filed and the envelope updated (step 12).

13. Validation record

Pending. Filled in by the dry-runner (see docs/validation-protocol.md).

Sandbox scenario: in the sandbox, a second engineer triggers a scripted injection that makes the demo agent call a deny-listed mock tool. The dry-runner follows the runbook from the alert to the post-incident review, including one deliberate rollback of the kill switch and one restore of a role assignment through PB-AGT-08-03.

Pass criteria: containment completes within 30 minutes; the agent makes no further calls; the affected runs are listed from traces; permissions are restored through the change runbook.

Record

Item Detail
Playbook PB-AGT-08-04 at commit [hash]
Dry-run by [Name] (must not be author or reviewer)
Date YYYY-MM-DD
Sandbox [Resource group or tag, tier and region]
Scenario [Scenario followed]
Time taken [Hands-on time] hands-on, [waiting time] waiting
Result [PASS / PASS WITH NOTES / FAIL]
Notes 1. [Step number: defect or explanation; blocking/non-blocking; fixed/logged]
Signed off by [Reviewer name and date]

14. Sources

Checked on 10 November 2026.

  • PB-AGT-08-01: Define an agent's permission envelope (the envelope this runbook protects and updates).
  • PB-AGT-08-02: Enforce action allow-lists and approval gates in agent code (the guard, and the suggest-only switch).
  • PB-AGT-08-03: Change an agent's permissions safely (how permissions are restored).
  • PB-AGT-09-03: Build compensating actions and checkpoint resume (reversing harm).
  • PB-AGT-07-02: Run the agent regression gate (where the new evaluation case runs).