Contain, Don't Trust Agentic Orchestration

 

Evaluating Windows Security Frameworks as Infrastructure for Agentic Orchestration

 

Scope: this piece is about local agentic orchestration: an orchestrator, its tools, and either a local model or a local execution layer for a cloud model's decisions, all running on the same Windows machine someone controls.

·       In scope:  the primitives an orchestrator can call into or run under to contain its own tool execution, with no kernel driver required.

·       Out of scope, by design, not oversight:  a fully remote pipeline where the orchestrator, the model, and the tools all run as someone else's cloud API. Windows-level containment isn't even an available lever there.

·       Also out of scope, by design:  WFP, minifilter drivers, TDI/NDIS filters, and PnP filters. Those are how a security vendor builds a kernel driver that polices every other process on the box (a different threat model, watching untrusted processes from outside, and a different deployment model, a signed, WHQL-certified driver, not application code).

Executive Summary

·  The problem:  most agent frameworks run planning, tool execution, and credentials in one unmediated process. Even where MCP splits the process, the split is rarely a security boundary.

·    The approach:  nine Windows-native containment mechanisms (VBS Enclaves, Chromium-style and AppContainer sandboxing, Windows Sandbox, eBPF for Windows, ETW, WDAC/AppLocker, AMSI, and ProjFS/CfApi), evaluated against one rubric, composed into a reference architecture, then pressure-tested with an ATAM pass.

·    The conclusion:  no single mechanism wins. The honest answer is a risk-tiered mix: an allow-list gate and a secrets enclave as hard, independent gates, then process-level or VM-level containment depending on how well-scoped the code being run is.

·  The caveat:  this is inference from primitives built for browsers and macros, not agents. It's unvalidated as a reference implementation, untested at agent-invocation latency, and does nothing against prompt injection itself, only against what a manipulated decision can do once it's made.

Most agent orchestration frameworks run tool-execution code in the same process as the planning loop, sharing its credentials, with no OS-level boundary between deciding and doing:

·       LangGraph, CrewAI:  tool calls are direct in-process Python function calls by default. No sandbox exists unless a developer bolts one on separately.

·      AutoGen:  the same story out of the box (LocalCommandLineCodeExecutor runs generated code on the host, in AutoGen's own process). A Docker-based executor exists, but it's opt-in, not what most deployments ship with.

·       The MCP ecosystem:  the one architecture here that actually splits the tool-execution process from the host. But that split is rarely a security boundary either. An MCP server typically runs with the same OS-level trust as any other process the user launches, no restricted token, no job object, no integrity level gating what it can touch.

Whichever side of a process boundary the tool-execution code lands on, the underlying problem is identical: an unpredictable decision translates directly into unmediated OS access. There is no boundary between deciding and doing, only whatever an engineer built by hand.



Figure 1. LangGraph and CrewAI never split the process; AutoGen doesn't either unless a developer opts into the Docker executor; MCP is the one ecosystem that splits the process by design, but the split is a process boundary, not a security boundary.

Windows has spent over two decades solving a structurally identical problem for a different class of untrusted code:

·       A browser rendering an arbitrary web page.

·       A script host executing a macro from an email attachment.

·       A third-party security engine that needs to inspect but never fully control the OS.

The primitives that came out of that work were not built with agents in mind:

·       Process-level sandboxing.

·       Virtualization-based secure enclaves.

·       Brokered telemetry.

·       Verified-bytecode extension points.

But the problem they solve is the one agentic orchestration mostly ignores: contain code whose behavior you can't predict, without trusting it to police itself.

This article evaluates that stack against one question per framework: which quality attribute of agent orchestration it serves, and what it doesn't help with at all. The stack: VBS Enclaves, Chromium-style broker/target sandboxing (and Windows' own AppContainer/LPAC), Windows Sandbox, eBPF for Windows, ETW, WDAC/AppLocker, AMSI, and ProjFS/CfApi.

What's Actually at Risk

Before the survey, here is the data flow this article keeps coming back to, and a STRIDE pass over it. Every threat below is answered by something later in this article. Nothing here is invented to make the diagram look complete.



Figure 2. Every arrow in this diagram crosses zero mediated boundaries in the default architecture. The rest of this article is, in effect, a catalog of where a boundary could go.

STRIDE

Applies To

Threat Here

Addressed Later By

Spoofing

Planning Loop's inputs

A tool result or retrieved memory entry impersonates a legitimate instruction

Not solved by OS containment; needs input-provenance checks outside this article's scope

Tampering

Local Memory / Context Store

Attacker-writable local state is read back into context on a later run, becoming persistent poisoned instructions

ProjFS/CfApi narrows what's writable; doesn't validate content integrity

Repudiation

Tool Execution

No brokered, tamper-resistant record of what a tool call did at the OS level

ETW

Information Disclosure

Credentials / API Keys

Same-process execution gives a successful prompt injection direct memory access to whatever credentials the process holds

VBS Enclave (verdict/ciphertext only), AppContainer/LPAC

Denial of Service

Tool Execution

Unbounded resource consumption from a single unsandboxed process

Job objects (Chromium-style sandbox, Windows Sandbox)

Elevation of Privilege

Tool Execution → OS

A model's decision becomes OS-level action with no capability check narrower than the process's own token

WDAC/AppLocker, restricted token + integrity level

 

Spoofing is the one row nothing downstream fixes. It's a reminder that OS-level containment bounds what a bad decision can do, not whether the decision was manipulated in the first place; that's still the orchestrator's own tool-call policy's job, not the OS's.

The Rubric

These frameworks solve different problems, and it's easy to reach for the wrong one. Four questions, asked of every entry below:

·       What does it isolate:  Code execution, secrets and credentials, telemetry, or a policy decision?

·       What's the adversary model:  A compromised host attacking a trusted computation, or hostile/unpredictable guest code attacking the host?

·       Where does the logic run:  Inside the isolation boundary, or outside it with only a verdict crossing the line?

·       What's the practical cost:  Signing or certification requirements, tooling maturity, latency per decision, and how much capability you give up to get the isolation?



Figure 3. The default shape of most agent orchestration today: no containment boundary, only whatever discipline an engineer imposed by hand.

The Taxonomy

Framework

Isolates

Adversary model

Where the logic runs

Practical cost

VBS Enclaves

Secrets, keys, sensitive computation (VTL1)

Compromised host (even kernel/admin) attacking a trusted secret

Inside the enclave, but with no network, file I/O, or dynamic loading

Trusted Signing certificate; near-zero general capability

Chromium-style broker/target sandbox

Arbitrary code execution

Hostile/unpredictable guest code attacking the host

Outside; target process is fully contained, broker holds every decision

User-mode only, no signing cert; ongoing policy-authoring cost

AppContainer / LPAC

Code execution, capability-scoped

Same as above, finer-grained

Outside, with named capability grants (lpacCom, registryRead, …)

OS-native, no custom broker/target plumbing needed

Windows Sandbox

Whole-OS execution

Untrusted, unpredictable code

Inside an ephemeral VM (HCS-managed Hyper-V container)

Seconds of spin-up, VM-level resource cost per session; sibling WDAG is deprecated/removed on 24H2+

eBPF for Windows

A narrow, verified slice of vendor logic at a fixed hook

Buggy or malicious vendor bytecode, verified before it loads

Inside, for network and process-lifecycle hooks; file-system hooks remain proposal-only

Mature for network hooks; process create/delete hook (with veto) ships via the separate ntosebpfext repo

ETW

Telemetry stream

None; it's an observation channel, not an enforcement point

N/A; fire-and-forget instrumentation

Low; brokered by the OS, tamper-resistant by session ACL

WDAC / AppLocker

What's allowed to execute at all

Anything not on an explicitly signed allow-list

Outside; vendor supplies data (policy), never code, at the choke point

Policy authoring and signing; near-zero runtime cost

AMSI

Script/buffer content, pre-execution

Malicious content passed to a script host

Outside; pure user-mode API call, no kernel component

Lowest cost on this list; only covers script-host paths

ProjFS / CfApi

A virtual filesystem namespace, scoped to a provisioned root

A tool that shouldn't see or touch the real filesystem outside that root

Outside; Microsoft's own minifilter relays to a user-mode provider

No custom minifilter/altitude needed; provider DLL only; covers nothing outside the root

WHP / HCS

Not extensibility; the virtualization substrate itself

N/A (infrastructure layer)

N/A

Only relevant if building a bespoke VM tier

 



Figure 4. Recast along the rubric's third question: only three of the ten entries let vendor or agent logic execute inside the boundary itself. The rest are deliberately built to keep logic outside and let only a verdict cross the line.

Deep Dives

VBS Enclaves: A Secrets Vault, Not a Runtime

VBS enclaves isolate a software-based trusted execution environment (VTL1, Hyper-V-backed) from the normal OS (VTL0), strong enough that even a compromised kernel or admin account cannot read enclave memory. VTL1 itself has two layers: the kernel-mode Secure Kernel (securekernel.exe), which manages VTL transitions and validates code signatures, and Isolated User Mode (IUM) running under it, where Trustlets (LsaIso.exe for Credential Guard, BioIso.exe for Windows Hello) and VBS enclaves execute. An enclave is IUM user-mode code, not part of the Secure Kernel itself; it gets no kernel privileges of its own, only the isolation the hypervisor enforces between VTL0 and VTL1. That same isolation disqualifies enclaves from running an agent:

·       No network sockets, no file I/O, no dynamic code loading from inside the boundary.

·       Production code must be signed via Microsoft's Trusted Signing service before it loads.

The right role for an enclave in an agentic architecture is narrow and specific: a vault for API keys, signing keys for audit attestation, or a policy verdict function, called into by an orchestrator that does everything else outside it.



Figure 5. The enclave runs as IUM user-mode code supervised by the kernel-mode Secure Kernel, not as part of the kernel itself; nothing crosses the VTL0/VTL1 boundary except explicit data copies, no shared memory or pointer the host side can dereference.

Chromium-Style Broker/Target Sandboxing: The Strongest Fit for Code Containment

Chromium's renderer sandbox is a two-process design:

·       Broker:  holds every credential and makes every access decision.

·       Target:  runs the untrusted code under a token stripped of nearly every privilege, inside a job object that forbids child-process creation and desktop interaction, at Untrusted integrity level (SECURITY_MANDATORY_UNTRUSTED_RID, one level below Low).

The broker intercepts the target's resource-touching operations (file opens, registry access, process creation, named pipes, synchronization objects) and forwards each to the policy engine before allowing it to happen. Everything else the target might attempt is denied outright by the restricted token, job object, and integrity level below it, with no broker round trip involved. Process mitigations layer on top:

·       Arbitrary Code Guard (ACG):  blocks the sandboxed process from generating and executing new code pages at runtime.

·       Code Integrity Guard (CIG):  ensures only Microsoft-signed modules load, not merely any validly signed binary.



Figure 6. The target cannot act on the host unilaterally; every call is a round trip through the broker's policy engine. This is the shape a code-execution tool for an agent should take.

This maps directly onto the standing rule that safety constraints belong at the permission/credential layer, enforced outside the agent's own process; the broker isn't asking the target to behave, it structurally cannot do otherwise, because the broker holds everything the target would need to misbehave with.

AppContainer / LPAC: The Same Idea, Capability-Scoped

AppContainer/LPAC (Less Privileged App Container) is the OS-native evolution of the restricted-token approach: instead of a near-total denial, a process gets a Low Box token with specific named capabilities (lpacCom, registryRead, lpacWebPlatform, lpacClipboard, …) explicitly granted. For an agent tool that needs some defined slice of capability (read-only registry access, clipboard, one specific COM interface), this is a better fit than a hand-rolled restricted token, without building a full Chromium-style broker/target plumbing from scratch.

Windows Sandbox: When Process-Level Isolation Isn't Enough

Windows Sandbox runs the untrusted workload inside a genuine ephemeral virtual machine, not a token/ACL scheme inside a shared kernel. It's a lightweight Hyper-V container (Microsoft's internal name for the tech is “Krypton”), provisioned through the Host Compute Service and backed by the Microsoft hypervisor. The isolation boundary is the hypervisor, not a policy the kernel enforces on itself.

·       Use it when  the code an agent is about to run is unknown, an agent-authored script executing against untrusted input, for instance, rather than a routine, well-scoped tool call.

·       Cost:  seconds of VM spin-up plus per-session resource overhead, real enough to make this the wrong default for every tool call, and the right one for the minority that are high-risk.

Its sibling, Windows Defender Application Guard (WDAG), is not a live option to weigh against it: Microsoft deprecated Application Guard for Office in November 2023, and as of Windows 11 24H2, Application Guard for Edge (including the Isolated App Launcher APIs) is no longer available at all. Microsoft's own guidance now points organizations needing container-based isolation to Windows Sandbox instead.

eBPF for Windows: Verified Bytecode, and Now a Process Hook

eBPF for Windows loads statically-verified bytecode at a fixed kernel hook. The PREVAIL verifier itself runs in a user-mode protected process, not in-kernel, so a verifier bug crashes a service, not the OS. That's a direct, structural contrast with the class of incident that took down CrowdStrike-affected machines in July 2024. Architecturally, it's the closest thing on this list to letting a constrained slice of an agent's or vendor's own logic run with kernel-adjacent visibility, rather than returning a verdict from outside.

The hook categories, by maturity:

·       Network (shipped, mature):  bind, XDP/WFP-L2, cgroup connect, in the core ebpf-for-windows tree.

·       Process lifecycle (shipped):  BPF_PROG_TYPE_PROCESS hooks PsSetCreateProcessNotifyRoutineEx for process creation and deletion; a verified program can return a failure NTSTATUS to deny the launch outright, not just observe it. Ships through a separate, actively maintained Microsoft repo, ntosebpfext, not the core tree, so adopting it means a two-repo dependency.

·       File system (proposal only):  no program type has shipped yet.

For an agent orchestrator, the process hook is directly relevant to tool-call gating; the still-missing file-system hook leaves data-exfiltration paths uncovered by this mechanism alone.

ETW: The Audit Trail, Never the Enforcement

ETW is a brokered telemetry stream with three deliberately decoupled roles: provider (emits events), controller (creates sessions, enables providers), consumer (reads the stream). A session is the buffered channel connecting them, not a fourth independent actor. Nothing a provider does can intercept, block, or modify anything; a provider firing an event is fire-and-forget instrumentation, full stop.

·       What it's for:  a tamper-resistant record of what a sandboxed tool call did at the OS level, correlated against what the orchestrator authorized, for post-incident reconstruction.

·       What it isn't:  a policy gate. It was built to be incapable of acting as one.

WDAC / AppLocker: The One That Maps onto the Standing Rule

WDAC and AppLocker both gate execution at a Microsoft-owned choke point, but split responsibility differently:

·       WDAC:  evaluates every PE image at a single choke point (ci.dll in the image-load path).

·       AppLocker:  a kernel-mode Application Identity component computes file attributes and evaluates policy on process creation and DLL load; the same component runs in user mode when a script host calls it to verify a script before running it.

In both cases, the vendor or operator never adds executable logic at the enforcement point: only declarative data, a signed policy or a rule set, that existing OS logic evaluates. This is the closest real-world implementation of “the constraint has to be enforced outside the agent's own process model”: a WDAC or AppLocker policy is independent of the orchestrator's judgment by construction. A compromised orchestrator cannot talk its way past it, because the orchestrator was never the thing making that decision.

AMSI: Content Inspection at the Last Honest Moment

AMSI is the one entry with zero kernel component: a pure user-mode API (amsi.dll) that script hosts (PowerShell, VBA, .NET dynamic-eval paths) call before executing a buffer, submitting it to whatever engine is registered as the provider. It matters the moment an agent's output reaches a script host: an agent that generates and then executes its own script content is functionally the same case AMSI already defends against for a malicious macro.

ProjFS / CfApi: A Provisioned Virtual Workspace, Not a Filesystem-Wide Mediation Layer

ProjFS (prjflt.sys) and the Cloud Files API (cldflt.sys) are Microsoft's own minifilters at a fixed altitude, exposing pre/post file-operation callbacks to a user-mode provider (populate this placeholder, deny this delete) instead of granting a third party its own minifilter and altitude allocation.

·       Scope is narrow by design: a provider must explicitly designate a virtualization root (PrjMarkDirectoryAsPlaceholder followed by PrjStartVirtualizing) before any interception happens.

·       Only paths inside that root are projected; everything outside it is invisible to ProjFS entirely.

That makes it the right tool for giving a sandboxed agent tool a purpose-built, on-demand workspace, a project directory the provider populates and gates file-by-file, not a general mediation layer over wherever the agent's tool calls happen to touch on disk. Anything outside the virtualization root still needs the sandbox's own file-access policy (Chromium's AddRule(), for instance) or has to be unreachable from the target process in the first place.

WHP / HCS: The Substrate, Not a Framework

Windows Hypervisor Platform and Host Compute Service are what Windows Sandbox, WSL2, and Hyper-V-backed container runtimes sit on. Not an extensibility model in the sense of anything else on this list: only relevant if the right answer for a given agent workload is a bespoke VM-based execution tier rather than Windows Sandbox as shipped.

A Reference Architecture

Composing the pieces that fit the agent-orchestration problem, rather than every entry in the taxonomy:



Figure 7. The orchestrator never runs untrusted code itself, never holds a secret it can't get from the enclave on demand, and never gets to be the only thing standing between agent-generated code and the host.

One thing the diagram compresses: the ProjFS/CfApi box only covers a virtualization root the orchestrator provisions ahead of time, typically the agent's working directory. Paths outside that root aren't virtualized at all; they're either denied by the sandbox's own file-access rules or unreachable from the target process to begin with. ProjFS gives the agent a mediated, on-demand workspace, not a system-wide filesystem interception layer.



Figure 8. Two independent gates, WDAC's allow-list and AMSI's content check, sit outside the orchestrator's own reasoning, on purpose. Neither can be argued with by a compromised agent.

An ATAM Pass

ATAM (Architecture Tradeoff Analysis Method) is a structured way of evaluating whether a proposed architecture satisfies the quality attributes it's supposed to, developed at the SEI for exactly this kind of problem: a composition of independently-designed pieces, not a system built from scratch. It runs in a fixed sequence:

·       Rank the quality attributes that matter into a utility tree.

·       Trace each one through the architecture and assess whether it's satisfied.

·       Surface sensitivity points:  places where a small change to one part of the design swings a single quality attribute sharply.

·       Surface tradeoff points:  decisions that pull two or more quality attributes in opposite directions.

·       Close with an explicit list of risks (attributes that may end up unsatisfied) and non-risks (decisions already validated elsewhere).

Applied here:

Quality attribute utility tree, ranked:

·       Containment:  Can hostile or buggy agent-generated code affect the host beyond its sandbox.

·       Secrecy:  Can a compromised orchestrator host recover credentials the agent used.

·       Auditability:  Can the actual sequence of events be reconstructed independent of the orchestrator's own account of what happened.

·       Latency:  Cost per tool call, not per process launch.

·       Development and certification cost:  Signing requirements, tooling maturity.

Sensitivity point (a small change here moves one attribute sharply): the interception/policy layer. Every framework here that enforces anything (Chromium's AddRule(), a WDAC policy, an AppLocker rule, a sandbox capability grant) shares one property: every new tool capability the agent needs is a policy change at this layer. It scales with agent capability, not agent count, the same 20-year operational tax Chromium itself still carries.

Tradeoff point (one decision, multiple attributes pulled in opposite directions): isolation strength against iteration speed and functional capability. VBS enclaves sit at one extreme: strongest secrecy guarantee, weakest general capability, no network or file I/O at all. A flat, unsandboxed agent process sits at the other: fastest to build, zero containment. Everything surveyed here sits somewhere on that line, and the honest answer to “which one should I use” is a risk-tiered mix, not a single winner.



Figure 9. The risk-tiered mix from the tradeoff point above, as an actual decision path. The allow-list and the enclave are hard gates; everything after them is a matter of degree.

Risks:

·       No public evidence any agent orchestration framework has assembled this stack into a reference implementation. This is inference from primitives built for other purposes, not a validated pattern; treat it as a starting architecture to pressure-test, not a proven one.

·       Per-tool-call latency, at agent invocation rates that can run many times a second, is a different design point than AppLocker's per-process-launch rate (an RPC round trip per launch) or a browser's per-navigation rate. Nothing here has been load-tested at that granularity.

·       None of these frameworks were designed against prompt injection or agent-specific manipulation: they contain what code can do, not what an LLM can be tricked into deciding to do. The orchestrator's own tool-call policy still has to do that job; the sandbox only bounds the blast radius once a bad decision has already been made.

Non-risk: two decades of production hardening against a comparably hostile input class, arbitrary web content, already validate containment via broker/target plus job object plus integrity level. This isn't a novel security model for agents; it's a proven one, pointed at a new kind of untrusted input.

Pre-Deployment Checklist

  Is agent-generated or tool-execution code running in a process boundary distinct from the orchestrator that holds credentials?

  Is there an independent, declarative allow-list (WDAC/AppLocker) gating what can execute at all, separate from the orchestrator's own judgment?

  Are secrets and credentials the agent needs held somewhere a compromised orchestrator host cannot read outright, not just somewhere “the agent doesn't normally look”?

  Is every tool call's actual OS-level behavior logged via a brokered, tamper-resistant channel (ETW), correlated against what the orchestrator authorized?

  Does the sandbox tier match the risk tier: process-level containment for routine tool calls, VM-level (Windows Sandbox) for untrusted, agent-authored code?

  Is there a content-inspection point (AMSI) before any agent output reaches a script host?

  Has the interception/policy layer been budgeted as an ongoing cost, not a one-time build, given that every new tool capability is a new rule?

  Has the orchestrator's own tool-call policy been treated as the thing that stops a bad decision, separately from the sandbox that only bounds a bad decision's blast radius?

 

None of this replaces the orchestration-level discipline (bounded execution, independent verification, circuit breakers outside the loop) that agentic systems need regardless of what OS they run on. What it adds is a host-level containment boundary underneath that discipline, built by people who spent twenty years hardening it against a different kind of untrusted code, so the orchestrator's judgment isn't the only thing standing between an agent's decision and the machine it runs on. (For cross-platform tool execution, WebAssembly's capability-based sandboxing is the closest analog to AppContainer/LPAC's model, enforced a layer up the stack instead of by the OS.)

 


Sources

·       Virtualization-based security (VBS) enclaves - Microsoft Learn

·       VBS Enclaves Development Guide - Microsoft Learn

·       Chromium Windows sandbox design document

·       eBPF for Windows - microsoft/ebpf-for-windows (GitHub)

·       NTOS eBPF Extension (process create/delete hook) - microsoft/ntosebpfext (GitHub)

·       Defender for Endpoint on Linux: eBPF-based Auditd replacement - Microsoft Learn

·       The Windows Resiliency Initiative - Windows Experience Blog (Microsoft)

No comments:

Post a Comment