Identity governance

Your IGA can already govern AI agents. It just doesn't know it yet.

Agents do employees' work. Enroll them the way you enroll employees: a sponsor, a role, a lifecycle. The IGA you already run does the rest.

Companies are rolling out AI agents right now, and it has never been easier: buy an enterprise license, push the agent to employee workstations, and your developers have a coding agent in their terminal the same afternoon.

That same afternoon, every one of those agents is one prompt away from reading the entire disk or acting as the user in GitHub, Jira, and every other core system that user is logged into. And the controls most teams rely on don't hold:

  • The agent already has the access. It runs with a human's credentials on machines that matter, and when something goes wrong the log says a person did it.
  • Prompt filters don't see the action. Firewalls and scanners on the model wire read the conversation, not the tool call. Nothing stands at the action itself.
  • What exists is hardcoded. Where a control exists at all, it's an allowlist in a config file on one machine, written once at setup and never reviewed.

Picture the case this post will keep returning to. A developer asks the coding agent in their terminal to fix a flaky test and open a pull request. For that job the agent needs a shell, the repository, and Jira; all reasonable. But it runs as the developer, so it also holds everything else the developer holds: the production console, the deploy pipeline, the customer database. The intention is a pull request; the reach is the developer's entire world. That is the agent this post will enroll, as java-developer-agent.

The ephemeral trap

The root of the problem is how we think about agents. Almost everyone treats them as ephemeral: a process spins up, does something, disappears. Building a governance model on top of that fails, and the reasons are familiar:

  • The audit trail points at nothing. Which agent dropped that database? A process that no longer exists, with no owner.
  • Access reviews are impossible. You cannot recertify access for something that has no identity.
  • There is no accountability chain. No owner, no position, no lifecycle.

Identity governance, IGA to the people who run it, has spent more than twenty years solving these problems for humans. Joiner/mover/leaver, roles, sponsorship, recertification, audit. It works.

So why don't we treat AI agents as employees? Agents do employees' work.

An ephemeral process with no owner, enrolled into a governed identity record with a sponsor, a position, a role, a lifecycle, and an audit trail. EPHEMERAL PROCESS pid 48213 spawned 14:02 · gone 14:07 owner: none audit: points at nothing review: nothing to review enroll GOVERNED IDENTITY · WHAT YOUR IGA SEES java-developer-agent sponsor position role lifecycle audit a named human java developer tools + guardrails joiner → mover → leaver every action, attributed
FIG 1 · The reframe. Enroll the process and it becomes an account your IGA already knows how to manage.

A name tag is not an identity

Take the reframe seriously and two prerequisites follow:

  1. Every agent needs a stable, verifiable identity.
  2. An agent must not be able to modify its own identity or its guardrails.

Agents reach their tools through MCP, the Model Context Protocol. Some platforms attach an identity header to every MCP call and call it done. That's a name tag, not an identity. Anything the agent, or a prompt-injected agent, can rewrite is not identity.

For authentication there is nothing to invent. Agents log in through the OIDC provider you already run (a device-code login, the same dance as any CLI) and are provisioned over SCIM 2.0 from your IGA, the same way any other account is. Enrolling one more agent is minutes in Straza's console, not a connector project. Assigning a sponsor, the human accountable for the agent, is a native IGA concept; Microsoft Entra Agent ID uses the same word, and in midPoint it is a single extension attribute.

With this, agents get permanent identities tied to positions: java-developer-agent, accounting-agent. The same model as people.

The agent acts as itself, never as its operator. Its session carries the agent's identity and the agent's role, so the agent cannot borrow your permissions, and you cannot hide behind the agent's. What an agent may do is its role's entitlement, reviewed in your campaigns like any other role. A gated call's record names both humans in the loop: the sponsor accountable for the agent, and the person who decided.

The control plane is just another target system

Your IGA cannot talk to a terminal agent directly. In between sits a control plane: it distributes guardrails and policy snapshots to agents and gates their access to tools. That control plane is what I built Straza to be.

From the IGA's perspective, that control plane is just another target system: accounts and group memberships over SCIM 2.0, with a plain REST API and an OpenAPI description for the rest. Whether you run midPoint, SailPoint, or anything else, you manage AI agents the way you manage every other identity. No parallel governance stack, no second source of truth.

Agents reach every MCP server through Straza's one governed /mcp endpoint, where policy, approval, and audit sit; the IGA manages Straza over SCIM 2.0 like any other target system. Claude Code Codex Gemini CLI straza exec · any other STRAZA policy approval audit default deny 0 tools until a role binds /mcp github-mcp db-mcp deploy-mcp + any MCP server YOUR IGA midPoint · SailPoint · any IGA SCIM 2.0 · REST accounts in · roles out to your IGA: just another target system
FIG 2 · One governed path. Agents reach every MCP server through Straza; your IGA manages Straza like any other target system.

What an agent sees, and what a human approves

Identity alone is not enough. If your MCP servers touch production, a role model on paper won't save you. Two controls belong at the tool level.

Visibility: an agent sees only the tools its role binds

An agent only sees the MCP tools bound to its role. The accounting agent never learns that deploy_production exists. A smaller catalog also means a smaller context window and better tool selection.

Human in the loop: gated tools hold for an approver

Critical tools get an approval gate. When the agent calls deploy_production, the call holds and the sponsor's phone buzzes: approve or deny.

One gated call: the agent calls deploy_production, Straza holds it by policy, the sponsor, a human, decides approve or deny on their phone, and an approval releases the call to deploy-mcp, a deny or a timeout ends it, and the audit chain seals the call, the hold, the decision, and the outcome, in order. deploy_production java-developer-agent STRAZA held by policy APPROVAL REQUEST deploy_production java-developer-agent deny approve the sponsor a human, from your IGA released deploy-mcp denied a timeout is a deny the call the hold the decision the outcome the audit chain · every step seals into it, in order
FIG 3 · One gated call. Policy holds it, a human signs the decision, the chain records it. Silence is a deny.

Decisions run against a signed policy snapshot the agent cannot alter. Every uncertain state resolves the same way: unknown policy, an approval nobody answers, Straza unreachable, all deny, never a silent allow. Upstream credentials are injected gateway-side, so a prompt-injected model cannot leak a credential it never saw. The price: the decision takes under a hundred microseconds; the gateway adds single-digit milliseconds.

Approvals fit real workflows in two dimensions:

  • Who decides: the sponsor, an approver role, or nobody. A rule that names no approver falls to the sponsor; no usable decider is an immediate deny, with the reason.
  • How it blocks: a hold, where the call waits a couple of minutes (tunable) for a human, deny on timeout; or a ticket, which never blocks: an immediate deny carrying a ticket reference, and the agent moves on.

Either way an approval binds that exact call, the tool and its arguments, and it is spent on use: one later run passes, within a window you set, then it is gone. Different arguments, new request.

Straza in practice

Here is the model end to end, on the agent from the opening.

Your IGA provisions java-developer-agent into Straza like any other account, human approvers alongside it. You onboard your MCP servers into Straza; agents reach them through one governed endpoint. Default deny: the new agent sees nothing until a role binds it. Roles bundle tool access and terminal guardrails (what it may run, touch, and reach in its shell); they live in Straza, your IGA imports them and manages who holds them, so the grant is an ordinary role assignment, one your IGA has done a million times. The role binds the repository and Jira tools the job needs, and deploy_production, gated.

The agent passes through Straza by hooks in the harnesses you already use (Claude Code, Codex, Gemini CLI), or by straza exec, the same policied shell for agents with no harness integration. Sidestepping both does not produce an ungoverned agent; it produces an agent with no governed tools, because the MCP endpoint requires the agent's identity and the upstream credentials never touch the machine.

When the deploy call comes, it holds; the sponsor decides; and the decision, both humans named, seals into a hash chain you can re-verify yourself and stream to your SIEM. No AI runs inside Straza: enforcement is deterministic policy evaluation, always against the data your IGA sends, never a config file. And the lifecycle is real: disable the identity in your IGA and the agent's sessions die within seconds of the disable reaching Straza; an approval can only be used from a live session of the same identity.

If the identity system you already run can create and kill an account over SCIM 2.0 or REST, it can run this. SSO alone cannot; provisioning is the half that matters here.

Treat agents as employees

AI agent governance is not a new problem. It is the oldest problem in identity, wearing a new interface. Treat agents as employees, and the tooling you already own does most of the heavy lifting. And the next time something goes wrong, the log will not say a person did it. It will name the agent, its sponsor, and the human who signed the decision.

Straza launches September 2026 as open source: AGPL-3.0 core, Apache-2.0 SDKs and spec. If you want in before then: hello@straza.ai.