The policy store will be unavailable at some point. What happens then is the entire security posture of the system, expressed in a catch block.
try
{
return await _engine.EvaluateAsync(proposal, ct);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_audit.RecordFailure(proposal, ex);
return Verdict.Deny("policy-unavailable", "That action is not available right now.");
}An agent that stops working when the gate cannot answer is an incident. An agent that keeps working is a breach, discovered later, by someone else. Write the test for this path on the day you write the gate, because it is the path that never gets exercised in development and always gets exercised at three in the morning.
Plenty of teams have an existing Semantic Kernel codebase and no appetite for a migration. The equivalent hook is IAutoFunctionInvocationFilter, and the mechanism is the next delegate. Microsoft's own documentation states it plainly: without calling next, the operation will not be executed, and the reason given is cases of malicious prompts or arguments.
There is a trap worth knowing about. Filters registered through dependency injection have no guaranteed order. A security filter that runs after a filter with side effects is not a control, and nothing will tell you this is happening. Where order matters, add filters directly to the kernel instead.
kernel.AutoFunctionInvocationFilters.Add(new ActionGateFilter(policy, audit));That is the whole Semantic Kernel section. Everything else in this book assumes Agent Framework.
Every tool now needs a policy, and a tool without one does not work. Developers will discover this by adding a tool and watching it get denied, which is the correct way to discover it and an irritating way to spend a Friday.
Policies also rot. The capability a tool needed in March is not the one it needs in September, and nothing in the system notices drift. The honest mitigation is unglamorous: policies live in source control next to the tools they govern, they are reviewed when the tool changes, and the audit log is read often enough that a rule denying everything gets spotted in days rather than quarters.
The gate is also the component most likely to be argued about, because it is where somebody's feature stops working. That argument is the system functioning as designed, and it is worth saying so out loud the first time it happens.
Chapter 10 closes the outbound leg, which is cheaper than this chapter and stops more published attacks.
| Claim | Source | Status |
|---|---|---|
| Excessive Agency moved LLM06 (2025) to LLM03 (2026) | 2025 ordering: https://genai.owasp.org/llm-top-10/ · 2026 list: https://cybersecuritynews.com/owasp-genai-llm-top-10-2026/ | PRIMARY / SECONDARY |
DelegatingChatClient, FunctionCallContent, rejection via Exception | Microsoft Learn, Agent Framework middleware — https://learn.microsoft.com/en-us/agent-framework/agents/middleware/ | PRIMARY |
Middleware requires an agent using FunctionInvokingChatClient | Microsoft Learn, Agent Framework middleware | PRIMARY |
Approval middleware placed before UseFunctionInvocation | https://www.devleader.ca/2026/03/11/tool-approval-and-humanintheloop-in-microsoft-agent-framework | SECONDARY |
Not calling next prevents execution; DI does not guarantee filter order | Microsoft Learn, Semantic Kernel Filters — https://learn.microsoft.com/en-us/semantic-kernel/concepts/enterprise-readiness/filters | PRIMARY |
The proposal and verdict types, the three-outcome model, the split between ReasonForModel and ReasonForAudit, and the rule forbidding tainted arguments in irreversible actions are the author's design, not a published standard. The argument that a second model must never police the first follows from chapter 4's evidence but is not itself a measured finding. The claim that policies rot is experience, offered as such.
Download the full PDF for free?
Free download — no account required