Agent identity is not a security problem
In many companies that already run an agent in production, something fairly simple is going on: the agent authenticates with a shared service account and an API key that never expires.
The same account other processes use. An account created years ago, probably by someone who no longer even works at the company, and which never had a clear owner.
And no, nobody necessarily did anything wrong.
When you are running a pilot and you need the agent to read the CRM, requesting a new identity can easily turn into three weeks of tickets, approvals and meetings. If you have a credential that already works, the temptation is fairly obvious.
And it works.
That is precisely the problem.
Why this stops being anecdotal
Gartner projects that 40% of enterprise applications will have agents built in by the end of this year, up from less than 5% last year. IBM, for its part, has found that security incidents related to shadow AI have more than doubled in a year, reaching 43%, while two thirds of organisations have no process for detecting it.
A borrowed credential for a pilot is a shortcut anyone can understand.
The problem shows up when that shortcut becomes the usual way of connecting a significant share of the company’s applications, without anyone really having made that decision.
How far the identity provider reaches
An identity provider does two things very well: check who is making a call, and check whether they have permission to access a given resource.
With an agent, the important question is slightly different:
This specific action, at this moment and in this context, is it one of the actions the business has delegated to this agent?
The identity provider cannot answer that.
And it probably shouldn’t have to.
It isn’t a matter of the identity product being more or less sophisticated. The answer depends on business rules that live somewhere else in the system.
That is where the difference lies.
The two mental models we drag along
When we talk about permissions we usually think in two models.
We give a person relatively broad access because we expect them to have the judgement to use it. And if they do something absurd, we can ask them to explain themselves.
A traditional application works differently. It has a defined flow, it executes specific operations and, in general, we can read the code to know what it is going to do.
An agent doesn’t fit particularly well into either model.
It decides at runtime which calls it needs to make, and the sequence can change from one run to the next.
That is why defining its permissions solely in terms of the endpoints it can call does not necessarily limit what it can end up doing.
A simple example.
An agent has permission to read customers and permission to write invoices. Separately, both seem reasonable. It is even possible that both were approved separately.
But together they allow something nobody had anticipated: issuing an invoice to a customer who was never meant to be invoiced.
Nobody authorised that specific operation.
But nobody forbade it either.
The problem is that the permission was granted looking at each endpoint in isolation, while the risk appears when we combine several capabilities.
What a permission should really name
“Can read customers” describes a technical surface.
“Can check whether an invoice is reconciled” describes a complete business action.
It looks like a difference in wording, but it is really a difference in architecture.
In the first case, the scope is defined at the identity provider. In the second, the capability is defined in the integration layer.
And that layer is the one that knows the context needed to carry out the operation.
It knows, for example, that checking a reconciliation means querying four different things across three systems and then applying a business rule that may not even be documented anywhere.
That is the point where you can genuinely apply the brake.
It is, at bottom, the same idea behind using capabilities named after the business instead of exposing technical operations directly. I arrived at this conclusion thinking initially about the agent’s usability: if you hand it thirty operations named after tables and endpoints, the agent has more options, but not necessarily better judgement.
Over time I realised that that design decision was also a governance decision.
The audit trail has to answer three questions
Recording that a token called an endpoint isn’t much use when an audit arrives.
It is exactly what we already record today.
And in many cases, that record explains absolutely nothing.
Consider a realistic case:
Marta (accounts payable)
│
│ asks: "check this vendor's invoices"
▼
Assistant agent
│
│ delegates: check_reconciliation(vendor=X)
▼
Invoice agent
│
│ invokes the capability
▼
Integration layer ──── decided and logged here
│
┌───┴─────┬─────────────┐
▼ ▼ ▼
ERP Bank Accounting
The one that ends up calling the ERP is the invoice agent.
But the one who started the request was Marta, two steps further up.
If all we keep is the call to the ERP, we have lost exactly the information that explains why that call was allowed.
The trail should make it possible to answer at least three questions.
Which agent.
Not which service account.
The agent should have its own identity, distinguishable from other agents that may be using the same credential today.
On whose behalf.
This is probably the question that gets lost most easily.
An agent rarely acts entirely on its own initiative. It is usually executing something someone asked it to do, or that another agent delegated to it.
Under what criterion.
Which capability was invoked, with which parameters, and which rule allowed it.
The difference between the two kinds of record is fairly large.
Today we might have something like this:
11:04:19 svc_integration GET /api/v2/invoices?vendor=X 200
And for an audit we would need something closer to this:
11:04:19
actor invoice-agent-03
on behalf of assistant-agent-01 → marta.ruiz@company.com
capability check_reconciliation
parameters vendor=X, period=2026-08
rule accounts-payable/read-reconciliation
That information should also end up in a record the agent itself cannot modify.
Because if a system writes the record wherever it likes and we then use that same record to audit it, we aren’t really auditing much.
API governance with a new consumer
The identity provider issues the token.
The integration layer decides how far it can reach.
The controls that genuinely bound an agent sit where the capability is defined: which operations exist, which parameters they accept, what gets recorded, and which operations need human confirmation.
And this isn’t something completely new. We have been doing API governance for many years.
What has changed is the consumer.
We no longer have an application in front of us that always follows the same flow. We have a system that decides what to do as it goes.
I say this with the caution of someone looking at the problem mainly from the integration side, but I have the feeling we are putting this whole matter into the “security” drawer.
And an important part of it could be left unresolved there.
Security can give you a dedicated identity for each agent. It can give you short-lived tokens, credential rotation and access controls.
All of that is necessary.
But none of those things answers, on its own, the most important question:
What exactly can this agent do?
The agent that needs none of this
A bit of common sense is also in order.
If you have an agent that only reads public information and cannot compromise data or take actions affecting third parties, you probably don’t need to set up this whole governance apparatus from day one.
The cost of doing it may be greater than the risk.
And if you are still trying to work out whether a use case makes sense, use fake data. You don’t need to settle the definitive identity of an agent that may never reach production.
What doesn’t work is repeating the usual pattern: running a pilot that touches real systems with borrowed credentials and leaving the governance part for “later”.
Because quite often that “later” ends up becoming production.
Where to start
First, give the agent its own identity.
Neither shared nor inherited.
This alone already makes it possible to know what each agent did, which with a shared service account can be impossible.
Next, make the permissions expire. Short lifetime and scope limited to the task wherever possible.
An eternal token with broad permissions offers little more control than a password written on a sticky note.
The delegation has to be recorded too.
Not just the call.
Who asked what of whom.
And above all, start thinking of the capability as the unit of governance.
If you cannot draw up a list and say “this agent can do these ten things”, you probably haven’t really decided yet what it can do.
In a few months somebody from compliance may ask something very simple:
What exactly can your agent do against the company’s systems?
The answer cannot be:
“It depends on what it decides”.
It has to be a list.
The full pattern for exposing those capabilities, and for having a system distil them as it learns, is in MCP-Led: semantic integration for enterprise systems.
Written by José Miguel Azcona Padín · Málaga, Spain · more articles
The views expressed in this article are the author's own and do not represent the position of any employer, current or former. The content is original work and contains no confidential company or client information.