A working prototype for reviewing identity, secrets, and guardrails together, managing policy changes as code, and exposing drift before audit does.
I have not posted in a while. I was down in a rabbit hole of agent sandboxing and policy enforcement, specifically adding on OPA (pronounced OPAH) and rego. Thank goodness for AI to help with code. I am only now climbing out with alot learned and alot to say.
What I am going to show is a real, working build. However, I would consider this still highly conceptual. It comes from months of conversations with customers and people across the industry. The idea is a single management plane for the policies that govern agents. It does not have to be a plane for IBM Agent Identity only, or Vault only. The identity side could be Okta, Ping, or Microsoft Entra. The authorization side could be Cedar, the language behind Amazon Verified Permissions, or OPA, or a relationship engine like OpenFGA. Whatever you run, you are going to end up with disparate policy management, teams each with their own requirements and views, overlap nobody owns, and confusion about which copy is the real one.
When compliance or audit asks you to show the controls around your agents, will you be able to? Will you be able to prove these are in sync because automation keeps them in sync, and not because a person remembered to, or better yet, is the creation and ideology of the policies in sync with the CISO, Security teams, and compliance teams? Who is the ultimate owner? Who is going to stand up in front of a change review board and answer the questions.
I do not want to digress from the policies themselves, but this is a new world. Agentic AI is nearly limitless, and we have a chance to start fresh, build with security in mind, and get it right the first time. Agents can and will break out of the sandbox. I have seen it and I have shown it. The industry has shown it. The walled garden is not the garden of Eden. We cannot rely on a sandbox or a network layer. We need full control over our agents, which means defense-in-depth.
I spent weeks inside an open source agent sandbox runtime, on a laptop, on a cloud host, and on OpenShift. One thing in that stack is right; the sandbox never holds a credential value. Out of the box the runtime kept credential values in its own gateway database; you handed it the literal secret and it stored it. The Vault credential driver changes that. The runtime stores only a reference to a Vault path, the driver resolves that reference against Vault at the moment a sandbox is created, the sandbox's environment carries an opaque placeholder, and the egress proxy substitutes the real bearer onto the wire only as a request leaves. Rotation is a write to Vault, Vault stays the single system of record, and inside the sandbox, before egress, there is nothing to exfiltrate.
Then I found two things that changed how I thought about sandboxes.
The first was the default policy. A fresh sandbox from the community base image already carried network groups for every common agent CLI, the package index, and the vendor's own inference endpoint, before I applied anything. This was not a deny-all by default.
The second was the subagent. The demo has a parent agent and a read-only agent it delegates to, and what I needed to enforce is the subagent to run in its own sandbox under a stricter policy: two read-only gateway ports, a read-only filesystem, nothing else. That policy file fine it was correct. But the subagent of the agent harness, invoked through its task tool, and the task tool does not start a new container. It runs the subagent in the same process, in the same sandbox, under the parent's network policy. During a normal run the policy was never applied to anything. What was really enforcing the subagent was the harness's tool allowlist and the hard-cap deny on its identity at token exchange, not the sandbox. Which is exactly why you want a token exchange (rfc8693) that includes INTENT (RAR rfc9396) with an applied enforceable policy, like we do with IBM Agent Identity. Adhering to standards WILL SAVE YOU. There is a reason for 8693 and 9396. To enforce and base a policy on intent of the agent gives you a true scoped OBO. Not a made up OBO with only adhering to partial 8693, like you will find in other IdP's.
The fix was easy, tool on the mcp, delegate_research, that spawns a separate sandbox per delegated task, with the enforced policy and only the read-only credential. To the parent its just another tool call. It now runs in a different container, under a different network policy, as a different identity, and enforced policy with proper AAA. Authentication, Authorization, and Accounting.
Both findings point to the same separation. Isolation determines where the agent process can run and how far a breakout can spread. Authorization determines whether this identity may use this tool for this action at this moment. To a sandbox, a harmless read and a destructive write to the same permitted host can look like the same allowed traffic. It cannot judge intent or business impact. Authorization handles that decision, but it does nothing to stop a kernel exploit or contain a compromised process. You need both, and each has to be verified. The statement “it runs in a sandbox” stopped before the authorization layer was even tested.
None of these layers inspect prompts, so nothing here detects prompt injection. The protection is downstream of the attempt: an injected instruction still has to pass through an identity whose grant only covers certain actions. This is mitigation, not detection, and the distinction matters.
So the stack ends up with five places where policy lives: the sandbox's network and file policy, the gateway that enforces per call, the identity service that decides at token exchange, the vault that issues secrets against the token, and the signals that revoke all of it. Five surfaces, four languages, and in most shops, four teams. That is the problem the rest of this post is about.
Researchers at the University of Oxford and the UK AI Security Institute published a sandbox-escape benchmark in March 2026. The test gave frontier models shell access inside a container and asked whether they could reach a flag on the host.
The findings:
Takeaway: this was not evidence that models can defeat every sandbox. It showed them exploiting familiar container-security weaknesses. Give a model enough room to keep trying, and those configuration mistakes become opportunities.
On the identities behind the agents: the Cloud Security Alliance and Aembit surveyed 228 IT and security professionals in January 2026, and a second CSA survey with Zenity covered 445 more.
The identity findings reveal another gap:
My takeaway: when agents share an account, their permissions and activity become harder to separate. A dedicated identity gives you a clearer basis for defining what each agent may do and holding it accountable for what it actually does.
Gartner put a forecast on where that leads in April 2026, and tied it explicitly to agentic AI built on MCP.
| Measure | 2025 | Forecast | Year |
|---|---|---|---|
| Five or more minor incidents a year | 9% | 25% | 2028 |
| One or more major incidents a year | 3% | 15% | 2029 |
Two risks in the OWASP Top 10 for Agentic Applications, published in December 2025, map directly to the controls in this post:
Takeaway: a sandbox alone does not address either risk. The controls below check whether the identity's grant covers each requested tool and its tags. That constrains what the agent can do, but it should not be confused with preventing every misuse of an otherwise permitted action.
The first mistake I see large enterprises make is treating the agent's policy as a single document with a single owner. There are three layers, and each already has a natural home in the organization.
Identity scope is what an agent may do, on behalf of whom, under what conditions. That is IBM Agent Identity: the Agent Registry record the agent lives in, the Authorization Details Type that carries the Rich Authorization Request payload, and the access policy Agent Identity evaluates at token exchange.
Secret scope is what a given agent identity can pull from Vault, along which paths, for how long. That is infrastructure, owned by platform or security engineering, and it looks like every other Vault policy they already manage.
Once Agent Identity completes the policy checks based on the RAR, two checks remain at the gateway: whether the requested tool is registered and tagged, and whether each delegation remains within its parent's permissions. A small OPA package enforces those checks because Agent Identity cannot make them on its own in this design. Security governance owns this layer and the tag vocabulary, providing an independent guardrail against either of the other policy layers quietly expanding an agent’s access.
Once the layers are separate, the ownership question answers itself. Nobody new gets hired. The people who own access decisions for applications own them for agents.
What is glaringly missing is a place where those three owners could see and manage all three layers at once.
Policy Studio grew out of my work building and managing policies across these layers. It is a workbench behind single sign-on that brings the policies into one place for review, while keeping the repository as the source of record.
The policy library includes:
A reviewer can:
A human via the policy studio kicks off the job, merges the pull request, CI validates it again, and a named operator step pushes the change to the tenant and the gateways. Drafts stay in the browser until the reviewer chooses to send them. It is a private prototype of mine, not an IBM product, and the hosted copy runs on a Worker that gates every request behind IBM Verify sign-in and a container that clones the policy repository fresh and sleeps when idle.
Here is why I built it: Agents were getting tools faster than policy will be created. The rules were spread across the IBM Agent Identity, Vault, and OPA files on a host, written in different languages and in terms of individual tool names. A change in one layer left no trace in the others, and nobody could answer "what does this agent get to do today" from one screen.
The flow below is the Studio's own animated diagram of itself. The reviewer never holds a GitHub token, the container never holds a Verify secret, and GitHub is the system of record for all three enforcement points.
The OPA (OPAH) community learned this a few years ago and it transfers directly: never write policy against enumerated names. A rule that lists tool names by hand is for sure not the way to do it. So every tool in the registry carries exactly five tags, and every policy at every layer keys on those five values and nothing else.
A rule set is an ordered list of rules over tags, and a generator compiles each file into one CELx custom attribute per rule plus one access policy. This is the parent agent's whole rule set:
Two rules; Confidential or restricted data never leaves through an egress tool, and every write or execute needs a push approval. A rule's when may only name the five tags; the validator rejects a tool name outright. Notice the INTENT is applied.
I use the gateway instance in the demo and put the tool's five tags into the RAR it sends, and Agent Identity echoes them back in the OBO token. Decoded from a live exchange, claims only:
With the generated policies bound, the decisions came back the way the rules read: a plain read allowed, an egress of confidential data refused with access_denied, and a write triggering the step-up. The legacy, name-keyed attributes were deleted the same afternoon, after a snapshot of every live object was written to disk and read back.
Back to the question I opened with. When audit asks for the controls around the agents, the answer in this build is a commit hash and three outputs.
The commit hash is the repository at a point in time, and CI at that commit is green: the tag vocabulary on every tool, the Verify objects against their schemas, the OPA bundle rebuilt and compared, the Rego test suite, Vault policy formatting, the grant file's shape, a replay of sample decision logs against the committed bundle, the deny-only proof, and the tag rules compiled and compared. A policy change that breaks any of them does not merge.
The first output is the plan. A script reads the live tenant and reports, per object, whether it matches the repository, has drifted, is missing, or exists in the tenant with no file behind it. The Tenant view in the Studio is that plan on a screen. The second is the decision log, which is also the input to right-sizing. The right-size script reads thirty days of decisions and prints, per agent, what was granted against what was used:
The third output is the revocation path, because a control you cannot turn off is not a control. Suspending the agent's record in the Agent Registry disables its linked OAuth client immediately; a fresh mint while suspended comes back CSIAQ5293E Unable to match an active agent identity, and restoring the record lets the mint succeed again. What I added since the first draft is the other half: a poller that forwards the suspension to Vault. In the rehearsal on 29 September, the record was suspended at 17:52:20, Vault's registration for that agent was deleted and its entity disabled at 17:53:12, fifty-two seconds later, and the restore took twenty-six. The parent agent was untouched throughout and its reads kept returning 200. Agent Identity already refused the suspended agent at token exchange; this makes Vault's own copy of the agent's status agree with Agent Identity's, which is the defense in depth I keep asking for.
Key rotation got the same treatment. The subagent presents a SPIFFE JWT as its actor token, and Agent Identity validates it against Vault's public keys. A cached copy of those keys went stale once and broke delegation. Vault now serves its own keys through a path rule that exposes exactly one URL and nothing else; a forced rotation produced a new signing key, and the subagent's exchange succeeded with it thirteen seconds later.
The newest view in the Studio is the one I was most unsure about. You paste an MCP server's tools/list answer, name the agent that will use it, type the owner and the tenant, choose a model, and the Studio asks the model for a tags file per tool, the agent's Agent Identity rule set, a Vault policy, and sometimes a deny-only OPA rule.
The rules I held to make it safe to put a model in the loop are the same rules a human edit lives under. Owner, tenant and the target agent are typed by a person, never guessed. Each pasted tool is registered as a manifest exactly as served. Every draft runs through the same validators as a hand edit, and the OPA that validates model-written Rego runs with a capabilities file that removes http.send and the network functions, so a draft cannot call out. A draft that fails validation goes back to the model once with the error; one that still fails stays in the list with its error, and the pull request is blocked until it is fixed. Nothing is saved or applied. The drafts leave as one draft pull request that a person reviews.
What leaves the Studio for the provider is the pasted manifests, the tag vocabulary, a few example tag files, the agent's current rule set, an example Vault policy, and the gateway instance names. Tenant exports, secrets and session data never go. Each run writes one audit row, who, when, which model, a hash of the prompt and the token counts, and each user gets twenty builds an hour. I wired three providers; the validators treat every draft the same way.
The honest cost of this design shows up in Agent Identity. Every agent has a registry record bound to an Agent Identity app, and the agents that do token exchange each have their own Token Exchange app, whose policy pointer names that agent's access policy, whose rules read that agent's attributes. OPA already scales, because the grant file is data keyed by SPIFFE id. Vault is one file per role. Agent Identity grows by one app, one policy and a handful of attributes per agent, and at a thousand agents that is a console nobody can read.
The next model; Tools carry tags and grow with integrations. Profiles are a handful of shapes, read-only, write-with-approval, delegate-only, and grow only with business decisions. Agents are records: identity, owner, tenant, profile. Thousands of agents is fine because they are data. OPA resolves agent to profile to grant with the same engine and one more lookup. Agent Identity keeps the registry record and the Agent Identity app per agent, where suspension, rotation and audit live, and shares one Token Exchange app and one access policy per profile. Vault uses one templated policy per profile, with the profile carried as an identity group.
Suspension today works through whichever app the agent's actor token comes from. An agent whose gateways still present a SPIFFE actor relies on its bound Token Exchange app for that. Before any Token Exchange app is shared across a profile, every agent has to move to the Agent Identity actor mint, so that suspension stays per agent when the app no longer is.
I built this against IBM Agent Identity, IBM (HashiCorp) Vault and OPA because that is mostly what I have been asked to demo and talk about. The shape does not depend on them. To sit under one management plane, a policy engine or identity provider has to offer five things, and I would ask these of Okta, Ping, Entra, Cedar or OpenFGA before I believed a single-pane slide.
The sandbox is one layer. The gateway is another. Identity decides, Vault issues, signals revoke. Each of those has a policy. Really no different than today with your IdP and your api gateway or your oauth rs or your secrets manager in AWS or Azure or Delinea..I brought it all together for a single view and enforcement of Agentic Agents.
Policy for agents is written by the same people who write it for applications, in terms of what a tool is rather than what it is called, stored and reviewed the way infrastructure code is, generated where it can be so the copies cannot disagree, compared against the live system on a screen anyone can open, and right-sized from the decisions the agent actually made. A model can draft it. A person merges it. Automation keeps it honest.
Who writes the rules? The same people who always did. Now they can see all of them at once.