← iamidentity.ai/blog
Claude-Powered Agent IBM Verify Token Exchange · RAR SPIFFE / SPIRE HashiCorp Vault MCP Server SSF / CAEP

IBM Identity Agent:
Securing a Claude-Powered Agent
with IBM Verify

A Claude-powered agent running on my infrastructure. An MCP server enforcing every call. An identity fabric in the middle that decides, per tool call, whether the agent is allowed to do the thing it is about to do. This is the next chapter of the agentic AI security series, and it is the one I have been waiting to write.

Robert Graham Global Product Architect, IBM Verify · April 2026

00 The Agent That Isn't Yours

In the previous posts of this series we talked about agentic AI like it lives in your data center. A LangChain agent on EC2. A Vault client on the same host. SPIFFE attesting the workload. You owned the agent, the platform and the servers...

That assumption is breaking. Anthropic just launched Claude Managed Agents. OpenAI has assistants. Google has Vertex agents. The model vendors are racing to host the runtime, not just the model. You send a prompt, they run the loop, they stream back an answer, and the whole thing happens inside infrastructure you cannot SSH into.

Which leaves a very pointed question sitting on the table. If you do not own the model, how do you own the security?

The Prompt

A security architect at RSAC asked me this directly. "My developers want agents, managed agents hitting our SaaS tenants. How do I enforce identity when the model runs outside of our infrastructure and all I control is the tools?"

This post is the answer. A working answer. Running code. Deployed today.

01 Meet the IBM Identity Agent

I built something called the IBM Identity Agent. IIA for short. It is a Claude-powered agent whose entire job is to administer IBM Security Verify. Onboard a user. Move someone into a group. Look up an application config. Access policies and controls. The agent does all of that through tools, and every one of those tools is a protected call into the IBM Verify admin API.

The meta story writes itself. IBM Verify is securing a Claude agent that administers IBM Verify. The agent reaches into the very identity system that governs it. If the identity fabric fails for even one tool call, the agent gets to do whatever it wants inside the thing that runs the company. That pressure is the point. It forces every layer of the security model to be real.

The model runs on Anthropic's infrastructure.
The secrets live in your Vault.
The authorization decision happens in IBM Verify.

Three different operators. Zero shared trust. One continuous security decision.

That is the whole architecture in three lines. The rest of this post is the explanation of how those three lines fit together, and why none of them can cheat.

02 The Trust Boundary

The interesting question in a hosted agent deployment is not "how do I secure my workload." It is "where is the line between their workload and mine." Draw the line wrong and the whole story collapses. Draw it right and the security model becomes obvious.

The line sits at the edge of my infrastructure. Everything outside it is somebody else's. Anthropic runs the model. The user sits at a browser I do not control. Everything inside the boundary is mine. The first thing inside that boundary is the server-side chat endpoint where the agent loop runs. That endpoint calls the Claude Messages API with the tool definitions, receives tool_use blocks back, forwards each tool call to the MCP server on localhost, feeds the result back to Claude as a tool_result, and keeps looping until Claude returns a final text answer. The MCP server never talks to Claude. The browser never talks to Claude. The browser never talks to the MCP server. Everything fans through the chat endpoint on my box.

This matters. Claude Managed Agents can run the loop for you. I chose not to let it. I trust Anthropic to run the model. I do not trust Anthropic to run the loop. The loop is the place where I decide what to send next, what to hide, what to refuse. Running it in my trust zone is a feature, not a limitation.

// System Architecture Overview
External · User Device + Anthropic SaaS
User BrowserHTTPS + session cookie
Claude (Anthropic)model only · Messages API
↓  TRUST BOUNDARY · Cloudflare Tunnel  ↓
Your Infrastructure (EC2)
IIA UIagent loop host · server-side tool_use loop
MCP Servertrust boundary · token exchange
SPIRE AgentJWT SVID · workload identity
HashiCorp VaultIBM Verify secrets engine
AntennaSSF / CAEP transmitter
↓  Token Exchange · RAR  ↓
IBM Verify SaaS
OIDC ProviderauthCode · PKCE · passkey
Token ExchangeRFC 8693 · act-on-behalf-of
Admin API (SCIM)users · groups · apps · policies

The three zones each have something the others cannot get. Anthropic has the model. EC2 has the Vault credential material and the SPIFFE identity. IBM Verify has the policy. No single zone can unilaterally decide what the agent is allowed to do. That is the property I want from a hosted agent security model, and it is the property that falls out of this architecture by construction.

03 Secretless, Still. SPIFFE Carries Over.

If you read Secretless by Design you already know how the MCP server authenticates to Vault. Nothing changed. The trust boundary moved, the agent moved to a hosted runtime, the surface area got bigger, and the secretless posture of the first post carries over intact. This matters more than anything else in this architecture because the industry default for "agent on hosted platform" is to scatter long-lived API keys like confetti. We refuse to do that. Not one static secret. Not in the code, not in the .env, not on disk, not in a secrets manager we pre-seeded, not anywhere.

What is NOT in Config

No IBM Verify client secret. No IBM Verify admin API key. No Vault token. No AWS access key. No long-lived OAuth client credential of any kind. No "agent identity" secret that outlives a single request. The user's access token is passed through per request and never stored. The .env holds client IDs, endpoint URLs, and port numbers. Everything that could be stolen has a TTL measured in minutes and is minted at runtime through a chain of cryptographic attestations.

Every time the agent calls an action, the MCP server asks the local SPIRE Workload API for a fresh JWT SVID with the Vault audience. It posts that SVID to Vault's JWT auth endpoint and gets back a short lived client token. It uses that token to read a rotated IBM Verify client secret from the Vault secrets engine. Only then does it call IBM Verify. Every step on that chain is either a cryptographic attestation or a just-in-time fetch. Nothing sits still.

The value the SPIFFE step provides here is the same value it always provided. The host can be stolen, the process can be inspected, the disk can be imaged, and there is nothing at rest that lets anybody impersonate the agent. The identity is cryptographic, it is attested at the kernel level by SPIRE, and it rotates on the order of minutes. A copied .env gets you nothing. A dumped process memory gets you a credential that expires before you can use it.

What Changed Since The Last Post

In the security panel of the IIA UI you can now watch SPIFFE work in real time, every turn. When the Vault token is still warm, the MCP server emits a passive spiffe:svid_cached event with the age of the SVID and the time remaining on the token. The secretless story is not something you claim once in a diagram. It is something the UI proves to you, over and over, for the life of the session.

04 Token Exchange. Every. Single. Tool. Call.

This is the part of the architecture where people either get it immediately or they want to argue about it for an hour. There is no middle ground. So I will just say it plainly.

The agent never uses the user's access token to call IBM Verify. It cannot. The agent does not even see the user's access token. The MCP server takes the user's token, combines it with the agent's SPIFFE identity, and performs an OAuth 2.0 Token Exchange (RFC 8693) against IBM Verify. The result is a brand new, scope limited, short lived OBO token minted specifically for this one tool call.

The exchange request carries a Rich Authorization Request (RFC 9396) describing exactly what the agent is about to do. Which action. Which target. Which tier. Which user it is acting on behalf of. IBM Verify evaluates a policy against that RAR object and decides at issuance whether the token should even exist. If the policy says no, the request dies at the identity layer and the agent never reaches the Verify API.

Why IBM Verify is the Differentiator

Token Exchange is a ten year old RFC. Rich Authorization Requests is a more recent one. Both are open standards and anybody can read them. But there is a large and unpleasant gap between a standard on paper and a commercial identity provider that actually implements the whole chain as a first class capability. IBM Verify is one of the few that does, and it does all of it together.

Verify accepts the user's access token as the subject_token. It accepts the agent's SPIFFE SVID as the actor_token. It honors the may_act constraint on the user app so only the declared actor can delegate on the user's behalf. It accepts structured authorization_details on the token endpoint and passes them into the access policy for evaluation. It lets the policy deny at issuance based on the RAR, which is how Tier 4 operations get blocked before any admin API is touched. It issues scoped OBO tokens with minute-scale TTLs and embeds the act claim so the downstream audit trail is unambiguous. And it ships the Vault secrets engine plugin that closes the loop on the one remaining static credential the MCP server needs to authenticate to Verify itself, rotating that secret on every read.

Pick any one of those features in isolation and you can probably find it somewhere else. Ask for all of them in one product, wired together, with a policy engine that understands authorization_details, and the list of vendors who can implement the pattern I just described drops to one. That is why IBM Verify is in the middle of this story. Not as sponsorship. As the thing that actually makes the pattern possible for anyone who wants to build it.

01

User sends a message

The UI forwards the message to the chat route along with the user's access token and id token in secure cookies.

02

The chat route calls Claude, Claude picks a tool

The chat route sends the conversation to the Claude Messages API. Claude returns a tool_use block, say, list_users. The chat route forwards that call to the MCP server on localhost, passing the user's token in a secure header. Claude never talks to the MCP server directly. The chat route is always in between.

03

MCP server fetches workload identity

SPIRE hands over a JWT SVID. Vault auths the SVID. Vault returns a rotated IBM Verify client secret with minutes of TTL.

04

Human in the loop (Tier 2 and Tier 3 only)

If the action is a Tier 2 write, the MCP server checks whether the user has already approved writes in this session. First write of the session: emit agent:hitl_required, wait for the user to tap approve, cache the consent for thirty minutes. Subsequent Tier 2 writes: emit agent:hitl_cached and continue. If the action is Tier 3 sensitive, the server requires a fresh approval every single time. No caching. The human stays in the loop.

05

Token exchange with RAR

The MCP server calls /token on IBM Verify. Subject token is the user's access token. Actor token is the SPIFFE SVID. The request includes an authorization_details object describing the operation, tier, target, and RAR type.

06

IBM Verify evaluates policy

The access policy bound to the Token Exchange app looks at who the user is, who the actor is, and what the RAR says. It issues a scoped OBO token. Or it refuses and returns a policy error.

07

MCP server calls the Verify admin API

The OBO token carries the exact entitlements for this single operation. The SCIM call returns. The MCP server emits a CAEP event to Antenna and returns the result to the chat route. The chat route feeds it back to Claude as a tool_result. If Claude needs another tool call, the loop repeats. If Claude is done, the final answer streams to the browser over SSE.

Notice what is not in that flow. No static client secret. No long lived admin API key. No "agent identity" that outlives the request. No trust placed in the Anthropic hosted environment beyond "you delivered the user's token to my endpoint." Every decision is reevaluated from scratch.

05 Four Tiers of Policy. One of Them Always Loses.

The IBM Verify token exchange policy does not just decide yes or no. It decides how. Every tool in the MCP server maps to a tier, and each tier exercises a different part of the Verify policy engine. You want a demo that shows policy, you want a policy that shows off. So I built in a tool at every tier, including one tier that is wired to fail.

TierBehaviorExample Actions
Tier 1 · Read Token exchange with RAR, standard read scopes. No human approval. Fast path. list_users, get_user, list_applications
Tier 2 · Write Token exchange with RAR, plus a human-in-the-loop step-up. The user taps approve on their phone once, and that approval covers every write in the session for the next thirty minutes. Second write in the session fires agent:hitl_cached and flies through. create_user, add_user_to_group
Tier 3 · Sensitive Token exchange with RAR, plus a push authentication step to the user on every single call. No caching, no per-session shortcut. Deactivating a user or revoking sessions is dangerous enough that the human stays in the loop for each one. deactivate_user, revoke_user_sessions
Tier 4 · Blocked Token exchange is denied by policy. The RAR hits the access rule, Verify returns access_denied, and the agent action never happens. There is nothing to approve because there is nothing to authorize. delete_user, grant_admin_role

The tier two and tier three split is the one practitioners usually ask about. Why not prompt the user on every write? Because nobody wants to tap approve fifteen times to onboard a team. Why not cache tier three too? Because "deactivate a user" is the kind of thing that should cost a deliberate, friction-bearing approval each time. Tier two is where we optimize for the flow state of the person using the agent. Tier three is where we optimize for the safety of the person the agent is acting on.

The tier four case is the one auditors ask about. When somebody says "what happens if the agent is compromised and tries to call the dangerous thing," the answer cannot be "we trust the code not to call it." The answer has to be "the identity layer refuses to mint a token for it." Tier four proves that. You can watch it happen in the event panel, in red, with the policy reason attached.

06 What The Auditor Sees

A security architecture that cannot be audited is a security architecture that does not exist. Every interesting decision in the IIA flow emits a CAEP event to Antenna, our Shared Signals Framework transmitter. The same events also stream into a live panel in the UI, in real time, over SSE.

Each event carries the user (by email, not sub), the tool, the tier, the outcome, the RAR summary, the duration, and a one line reason. Token exchange success. Token exchange denied. SPIFFE SVID fetched. SPIFFE SVID cached. Vault rotation retry. Push auth pending. Session killed. The events tell a story that a human can read top to bottom and understand the whole security posture of the last ten minutes without touching a log aggregator.

CAEP · iia.security.events// Real event emitted on every tool call
{
  "type": "agent:token_exchange_success",
  "userEmail": "robert@securemytechnology.com",
  "toolName": "list_users",
  "tier": 1,
  "rarType": "verify_read_users",
  "rarSummary": "Read SCIM users, limit=50",
  "durationMs": 312,
  "outcome": "success",
  "actorTokenType": "urn:ietf:params:oauth:token-type:jwt",
  "spiffeId": "spiffe://your-domain.com/agentic-workload",
  "oboTokenExpiresIn": 900
}

When the session crosses an anomaly threshold, Antenna transmits a signal and the user session is killed cross system. Not the agent. The user. The same access token that was being used to justify the agent's actions stops working, everywhere. The agent tries the next tool call and it gets back 401. That is what continuous evaluation looks like in practice. Authentication was a point in time. Authorization is still in flight.

Small Thing, Big Deal

The audit log used to show the user's sub claim, which is a UUID nobody can read. Now it shows the email. It used to show duration on some events and not others. Now it shows duration on every tool call, defaulting to zero for cache hits. It used to be hard to tell "which of these events belong to me." Now there is a toggle. These are not architectural changes. They are the difference between an event stream and an audit trail.

07 Why This Changes The Hosted Agent Story

Every organization I talk to is about to have this problem. The model vendors are racing to host the agents. Anthropic has managed agents. OpenAI has assistants. Google has Vertex agents. The economics are obvious. Hosting is cheap. The model is the value. If the vendor will run the agent for you, most teams will take that deal.

The security story that has to come with that is brand new. You cannot install an agent on the vendor's box. You cannot run a sidecar inside their tool loop. You cannot wrap their runtime in a network proxy. The only thing you can do is make sure the thing they call out to, your MCP server, enforces enough identity to make the agent irrelevant as a trust anchor.

That is what the IBM Identity Agent demonstrates. Hosting and identity can live with different operators. The hosted agent does not need to be trusted, because the identity fabric does not trust it. It needs to be observed, through the events it triggers, and it needs to be constrained, through the tokens it can obtain. IBM Verify does both, with a first class implementation of Token Exchange, RAR, may_act, authorization_details policy evaluation, and the Vault secrets engine plugin that keeps the whole thing secretless end to end. SPIFFE and Vault make the MCP server itself trustworthy. CAEP puts the audit story on rails.

None of the other pieces are the hard part. SPIFFE is production grade. Vault is everywhere. CAEP is a published standard. The hard part is the identity provider in the middle that speaks all three flavors of delegation (subject, actor, RAR) and enforces policy at the token endpoint before an OBO token is ever minted. Without that, you are writing application code that tries to decide if the agent should be allowed, which is exactly the place you do not want that decision to live. IBM Verify moves the decision out of the code and into the identity layer, and it does it with standards anyone can reach for.

You do not have to own the runtime
to own the authorization.

That is the future of agentic AI security. And it is already running.

If the agent can be somebody else's, the identity has to be yours. That is the shift. Once you internalize it, the architecture writes itself, and the tools already exist to build it. Token Exchange is a decade old RFC. RAR is a standard. SPIFFE is production grade. Vault is everywhere. IBM Verify ties them together into one policy decision point that sits outside the model vendor's blast radius.

The model runs on Anthropic's infrastructure. The secrets live in your Vault. The authorization decision happens in IBM Verify. Three operators, zero shared trust, one continuous security decision, on every tool call, for the life of the session. That is the whole pattern. Build it once and it applies to every hosted agent that shows up next.


Previous In This Series
Secretless by Design: Zero-Trust Agentic AI on AWS EC2
The architecture that this post builds on. SPIFFE workload attestation, the IBM Verify Vault secrets engine, CAEP continuous evaluation, and Token Exchange with RAR for an agent that runs on your own EC2. Start here if you want the foundations.
Field Notes
So You Have a Dashboard? RSAC 2026 Field Notes
What the rest of the industry was showing at RSAC 2026, and what was missing. Context for why a working implementation matters more than a polished screen.
The Problem Statement
The Weakest Link: Agentic AI Agents
Why agentic AI agents are the new weakest link, and what a zero trust agent architecture actually has to do.