
AGENT SECURITY
The Rise of Shadow Agents
A shadow agent is an ordinary one nobody registered. Where each entry route is logged, why disabling beats deleting, and the queries that find them while the audit trail still exists.
TL;DR
A shadow agent isn't a rogue one. It's an ordinary agent nobody registered, and the reason you can't find it is almost never that it's hiding. It's that the grant it runs on is a first-class object in your identity provider that nobody reads.
Both major platforms allow this by default. Microsoft states plainly that "by default, all users are allowed to consent to applications for permissions that don't require administrator consent", and IBM's 2025 breach study found one in five organizations reported a breach involving shadow AI, adding roughly USD 670,000 to average breach cost.
The instinct is to ban agents. We think that's the worse of the two available mistakes. Prohibition doesn't remove the demand that created the agent; it moves the next one somewhere with no audit trail at all.
We are also not claiming discovery is easy or complete. Agents holding a static API key leave no consent record anywhere, and Microsoft's own portal shows admin consent grants for only the last 90 days.
Start with the enumeration, not the ban. Export every OAuth grant in the tenant, sort on AllPrincipals,
read the scope strings, and when you find one you can't account for, disable the application rather than
deleting it.
Overview
Shadow IT has been a known problem for years. A marketing team signs up for an analytics tool on a corporate card, a finance analyst writes a macro that quietly becomes load-bearing, and none of it was malicious. It outpaced the people responsible for governing it. Agents are producing the same pattern under a new name, and the difference in stakes is easy to underestimate. A forgotten SaaS subscription wastes a subscription fee. A forgotten agent holds a live credential and can use it.
This is a discovery problem first, which is covered from the incident-response angle in Why Enterprises Need Agent Discovery. What this post adds is the taxonomy and the mechanics: which doors an agent comes through, which object each door creates, how long the record of it survives, and what the two platform vendors will and will not do for you once you find one.
The issue was never experimentation. An agent that helps someone do their job is not a problem. An agent that helps while holding untracked credentials to systems nobody knew it could reach is a different matter, and the two get confused constantly.
What Is a Shadow Agent?
A shadow agent is an AI agent operating inside an organization without visibility, approval, ownership, or governance attached to it. It runs with real access, and nobody in security, IT, or compliance can point to it on a list.
The definition has to be behavioural rather than technical, because the underlying object is completely
ordinary. In Entra it is an oAuth2PermissionGrant or an app role assignment on a service principal. In
Google Workspace it is a token a user issued to a third-party app. Neither object is suspicious. The only
thing that makes one a shadow agent is that the enterprise cannot answer three questions about it: who owns
it, what it can reach, and what it is allowed to do.
OWASP's Top 10 for Agentic Applications 2026, published on 9 December 2025, gives two of the resulting failure modes names worth borrowing. ASI03 covers identity and privilege abuse, where an agent operates beyond its intended scope on inherited credentials. ASI10 covers rogue agents, which OWASP characterises through misalignment, concealment and self-directed action. A shadow agent is not yet either of those. It is the precondition for both, because neither one is detectable in a system with no record of what the agent was supposed to be doing.
Not the Same Problem as Shadow IT
The analogy is useful for explaining the shape to an executive and misleading if you take it into the remediation plan.
| Shadow SaaS | Shadow agent | |
|---|---|---|
| What it holds | A subscription and a login | A standing OAuth grant with named scopes |
| Worst case if forgotten | Recurring spend, data at rest in a tool nobody audits | Reads and writes against production systems, continuously, unattended |
| Where it is recorded | An expense line, maybe a DNS or proxy log | A first-class object in the identity provider, enumerable by API |
| How you find it | Spend analysis, network egress | GET /oauth2PermissionGrants, or tokens.list per user |
| What offboarding requires | Cancel the contract | Delete the grant or revoke the token, at the provider |
| Why it persists | Nobody reviews the renewal | An OAuth grant has no renewal date to review |
Table 1 — The recording column is the good news. Shadow agents are more enumerable than shadow SaaS ever was. Almost nobody runs the query.
That last row is the one we would put in front of a skeptical audience. A subscription forces an annual decision whether you want one or not. A grant forces nothing. It survives the employee, the project, and the vendor relationship, and the only event that ends it is somebody deciding to end it.
Four Doors, and Where Each One Is Logged
Shadow agents enter through a small number of routes, and none of them look suspicious at the time.
| Entry route | What gets created | Earliest signal | Where the history lives |
|---|---|---|---|
| An employee wires up an agent and consents for themselves | A delegated grant with consentType of Principal | The consent event, at the click | Entra audit log, category ApplicationManagement, activity "Consent to application" |
| An admin enables an "AI assistant" toggle in a tool the company already pays for | A delegated grant with consentType of AllPrincipals, no principal attached | The same event, with IsAdminContent true | Same, plus the app appearing under Enterprise applications |
| A SaaS product embeds an agent that asks for scopes at install | A token per consenting user, or a tenant-wide grant | Consent event, or Google's Token log authorize event | Google OAuth Token log, six months |
| An internal prototype drifts into production | Usually a service account or an API key, sometimes an app registration | Often nothing at all | Gateway and egress logs, if you keep them |
Table 2 — Three of the four doors create an object you can query today. The fourth is the one that should worry you.
The retention numbers behind that last column decide whether the history question is even answerable. Microsoft Entra ID keeps audit logs for seven days on the free tier and 30 days on P1 or P2, and states that retention changes "aren't retroactive" and expired data "can't be recovered unless it was previously archived". Google's OAuth Token log runs six months, with a lag of "A couple of hours" before an event is searchable. Microsoft's own app-consent investigation playbook adds two constraints that matter more than either number: the Azure portal "only allows you to see Admin Consent Grants for the last 90 days", and a new audit entry can take "from 30 minutes up to 24 hours" to appear in search.
Why They Appear, and Why the Count Keeps Rising
Shadow agents almost always show up for understandable reasons. Teams want to move faster than an approval queue allows. Employees want to offload repetitive work. Business units want AI productivity without filing a ticket and waiting two weeks.
The instinct to automate is healthy, and we would rather treat a shadow agent as a signal than a violation. Usually it means someone found genuine value before governance was ready to meet them there.
Expect the population to grow rather than stabilise, for two structural reasons. The barrier to creating an agent keeps falling, so what used to need an engineering team now takes a business user an afternoon. And SaaS products are shipping agentic features that activate with one toggle, frequently requesting broad scopes up front. The rate at which agents appear is accelerating. The rate at which they are reviewed is not.
The Risks
A shadow agent may be connected to sensitive documents, customer records, email, calendars, source repositories, internal chat, or production infrastructure. It may carry broad permissions, use credentials nobody centrally tracks, and act on a user's behalf without clear boundaries. That combination produces four distinct risks, and they do not show up the same way.
Data exposure happens when an unapproved agent reads information it was never meant to touch. An HR
assistant connected to a shared drive to "summarize policy questions" now has a path to compensation bands
sitting in the same folder. Microsoft's incident response team has published which permissions this actually
runs on: attackers use a combination of Mail.*, Contacts.*, MailboxSettings.*, People.*, Files.* and
Notes.* in, by their count, 99% of consent phishing attacks. Nobody thinks of delegated Files.Read as
high-risk. It is on that list because it works.
Action risk is different in kind, because agents do not only read. One built to help reconcile invoices, and also permitted to post journal entries, can move from convenience to control failure inside a single run.
Accountability risk surfaces once something goes wrong and nobody can answer for it. If a sales agent
emails a mispriced quote to a prospect, the investigation stalls on a question more basic than what happened:
who deployed this, and who approved its access. An agent that consented as its user produces
aact:audit-granularity/none-distinguishable in the
Agent Access Control Taxonomy, where
agent actions "appear in logs indistinguishable from human or other service activity". Microsoft's
playbook puts the hard version of this in one sentence. "If auditing wasn't enabled before the possible attack, you won't be able to investigate because
auditing data isn't available."
Lifecycle risk is the slowest and easiest to miss. Shadow agents are rarely offboarded. The person who built it leaves and the agent keeps its API token. The project it supported gets cancelled and the agent keeps its database scope.
Figure 1 — However a shadow agent enters, it lands in the same unowned state and produces the same four risks.
It Already Happened to Microsoft
The strongest argument against treating this as hypothetical is a published incident at a company with better identity telemetry than almost anyone reading this.
In January 2024 Microsoft disclosed that the actor it calls Midnight Blizzard "compromised a legacy test OAuth
application that had elevated access to the Microsoft corporate environment", and used it to grant itself the
Office 365 Exchange Online full_access_as_app role, which allows access to mailboxes. The initial foothold
was a legacy non-production test tenant account without multifactor authentication, reached by password spray.
Read the adjectives. Legacy. Test. An application nobody was using, nobody owned, and nobody had removed. That is a shadow agent in every respect except that it was built in-house, and it turned into the pivot for a nation-state intrusion.
The market-level figures are thinner, and worth quoting precisely rather than rounding up. IBM's 2025 Cost of a Data Breach Report, the first edition to study AI governance and access controls, reports that one in five organizations suffered a breach due to shadow AI, that a high level of shadow AI added an average of USD 670,000 to breach cost, and that 63% of organizations studied "have no AI governance policies in place". Among organizations that had an AI-related security incident, 97% reported not having AI access controls. IBM counts unapproved AI tools rather than unregistered agents, so this is adjacent evidence rather than a measurement of the thing. It is the best primary number available and it points the same direction.
Every one of those findings describes a missing record rather than a missing control. You cannot scope a breach around an application whose purpose nobody documented, and no amount of detection tooling reconstructs intent after the fact.
In Practice
Take a legal-operations team that adopts a contract-review agent through a SaaS add-on. Setup takes minutes: an admin grants the integration access to the contract repository so it can flag risky clauses.
From the security team's perspective, nothing happened. No change request, no identity provisioned. But the agent now holds a credential with read access to every executed agreement in the company, and the governance record looks like this:
agent: contract-review-assistant (SaaS add-on)
owner: unknown
identity: shared service token
scopes: documents:read:all, comments:write
approved: no
reviewed: never
offboard: no processEvery field governance depends on is blank, and the identity line is the taxonomy's
aact:identity-model/shared-service-account, whose blast radius covers every consumer of the account.
This is a made-up example, but not an unusual one.
Finding it does not require asking teams to self-report, which fails on its own terms: a team that built a
shortcut to skip the approval queue has no incentive to volunteer it. It requires reading the identity
provider. Microsoft's playbook ships a script, Get-AzureADPSPermissions.ps1, that exports every OAuth grant
and OAuth app for every user in the tenant to CSV, and tells you exactly which column to sort on.
Connect-MgGraph -Scopes "Application.Read.All", "User.Read.All"
./Get-AzureADPSPermissions.ps1 | Export-Csv -Path .\permissions.csv -NoTypeInformation
Disconnect-MgGraphThen filter ConsentType for AllPrincipals, because that value "allows the client application to access
everyone's content in the tenancy". Native Microsoft applications need it. Per the playbook, "every
non-Microsoft application with this permission should be reviewed carefully". On the Google side the equivalent
sweep is per user:
GET /admin/directory/v1/users/{userKey}/tokens HTTP/1.1
Host: admin.googleapis.com
Authorization: Bearer {admin access token}Figure 2 — The lifecycle has one branch point, and it is whether anything reads the grant list before the traffic does.
The Right Response
Banning agents outright is the wrong instinct. Prohibition does not remove demand; it pushes usage somewhere with less telemetry. Teams getting real value from an agent will keep it and stop mentioning it.
The better response is making the governed path the path of least resistance, and it has four concrete parts.
First, narrow future consent without pretending it fixes the past. Microsoft's built-in
microsoft-user-default-low option allows user consent only for apps from verified publishers and only for
permissions an admin has classified as low impact. Risk-based step-up consent, which escalates a risky request
to admin consent and logs it with a status reason of "Risky application detected", is on by default wherever
end-user consent is enabled. But changing the setting "only affects future consent operations", and existing
grants "remain unchanged".
Second, run the enumeration on a schedule set by your retention window, not your quarter.
Third, know what your platform does when you restrict something. Google Workspace lets an admin mark each app trusted, limited or blocked, and when you restrict a service, "any previously installed apps that you haven't trusted stop working, and tokens are revoked". Entra does not work that way, so the grant deletion is a separate act.
Fourth, disable rather than delete. This is the least intuitive item on the list and comes straight from Microsoft: "If you only delete the application, it might return later if another user grants consent. Instead, disable the application to ensure it can't come back later." A deleted app registration with a live user base is a shadow agent with a scheduled re-entry.
When the approved path is faster than the workaround, the workaround stops getting used. That is the whole mechanism, and none of it requires punishing the teams that found value first.
Where Fabriq Fits
For agents that run through Agentic Fabriq, the fields in that blank record are filled in by construction. Credentials sit in a vault per user and are attached server-side at the moment of the call, so the agent never handles the secret. Every call carries two identities, the agent and the acting user, and lands an audit record. An agent's effective tool list is the intersection of the user's scopes and the agent's own, which means the "what can it reach" question has an answer that does not depend on anyone maintaining a spreadsheet.
What it does not do is find agents that never went through it. The contract-review add-on above consented directly in the tenant, and the sweeps above are still how you would catch it. Clearing a vault copy of a credential is also not the same act as invalidating a grant upstream, so that call stays yours to make.
Frequently Asked Questions
What is a shadow agent? An AI agent running inside an organization with real access but no owner, no registration, and no review. The technical object is an ordinary OAuth grant or service credential. What makes it a shadow agent is the absence of a record, not anything about how it was built.
How is a shadow agent different from shadow IT? Shadow IT mostly costs money and creates data at rest. A shadow agent holds a standing grant and acts on it, unattended, against systems you care about. The useful difference in the other direction is that a grant is enumerable by API, which a rogue SaaS subscription generally is not.
How do I find shadow agents in Microsoft 365? Export every OAuth grant with
Get-AzureADPSPermissions.ps1, or query GET /oauth2PermissionGrants directly, then sort on ConsentType for
AllPrincipals and read the scope strings. Cross-check the Entra audit log under ApplicationManagement for
"Consent to application" events while they are still inside retention.
How do I find third-party agents with access to Google Workspace? Iterate users and call
GET /admin/directory/v1/users/{userKey}/tokens, which returns the tokens each user issued to third-party
apps, then compare against the Token log's authorize events for history.
Should I ban unapproved AI agents? We would not. Prohibition moves the behaviour to tooling with no audit trail. Narrow default consent to verified publishers and low-impact permissions, then make registration fast enough that nobody routes around it.
Does revoking a token stop the agent? It stops that token. If the underlying grant survives, the app can mint a new one. Delete the grant on Entra; on Google, restricting the service revokes tokens for apps you have not trusted.
Why disable an app instead of deleting it? Because deletion is not durable. Microsoft's guidance is that a deleted application "might return later if another user grants consent", whereas a disabled one cannot obtain new tokens and cannot be consented to again.
Can I find an agent that uses an API key rather than OAuth? Not through consent logs, since no consent object exists. Those turn up in gateway logs, egress telemetry and secret scanning, and that is a genuinely weaker signal. It is the honest limit of this approach.
Conclusion
Shadow agents are not a sign that employees are reckless. They are a sign that employees see real value in automation and that governance has not caught up to where they already work.
The goal is not to stamp out that initiative. It is to bring it somewhere access is scoped, ownership is clear, and behaviour is observable. The encouraging part, and the reason we are more optimistic about this than about fifteen years of shadow IT, is that the objects are already sitting in an API you can call this afternoon.
Agent discovery is what turns hidden adoption into governed adoption. The agents are already there, in a grant list nobody reads. The only real question is whether you read it before something else forces you to.
Sources
All URLs read 2026-09-29.
- App consent grant investigation playbook, Microsoft — illicit consent grants, the six permissions used in 99% of consent phishing attacks, the 90-day portal limit, the 30-minute to 24-hour audit lag,
Get-AzureADPSPermissions.ps1, and why to disable rather than delete. - Midnight Blizzard: Guidance for responders on nation-state attack, Microsoft — the legacy test OAuth application with elevated access and the
full_access_as_approle. - Configure how users consent to applications, Microsoft Entra ID — the default allowing user consent, the
microsoft-user-default-lowoption, and the fact that setting changes leave existing grants unchanged. - View activity logs of application permissions, Microsoft Entra ID — the
ApplicationManagementaudit activities for consent and permission grants. - Microsoft Entra data retention — seven days on Free, 30 days on P1 and P2, and non-retroactive retention.
- List oAuth2PermissionGrants, Microsoft Graph — the grant object,
consentType, and the replication-delay caveat. - Method: tokens.list, Google Admin SDK Directory API — the per-user endpoint returning tokens issued to third-party apps.
- Method: tokens.delete, Google Admin SDK Directory API — revoking all access tokens a user issued to one application.
- OAuth Token audit activity events, Google Workspace — the
authorizeandrevokeevents and their parameters. - Data retention and lag times, Google Workspace Admin — six-month Token log retention and the couple-of-hours lag.
- Control which third-party and internal apps access Google Workspace data — trusted, limited and blocked states, and token revocation on restriction.
- 2025 Cost of a Data Breach Report: Navigating the AI rush, IBM — the USD 670,000 shadow-AI delta, 63% with no AI governance policies, and the AI access-control finding.
- IBM report on AI-related breaches and access controls, IBM Newsroom — the one-in-five shadow AI figure, published 30 July 2025.
- OWASP Top 10 for Agentic Applications 2026, OWASP GenAI Security Project — ASI03 Identity and Privilege Abuse and ASI10 Rogue Agents, published 9 December 2025.
- NIST AI RMF Playbook, GOVERN function — GOVERN 1.6 on AI system inventories and the attributes they should carry.
- Agent Access Control Taxonomy — the audit granularity and identity model dimensions, and the questions they ask: what is recorded and who actions are attributed to, and what the agent is as far as the target system is concerned.
- Agent access control taxonomy, audit-granularity.yaml —
aact:audit-granularity/none-distinguishablethroughsession-level,per-actionandper-action-with-principal-chain. </content>