How do I discover AI agents, including shadow AI?

Chances are, AI agents are running undetected in your corporate infrastructure. In a January 2026 survey by the Cloud Security Alliance, 82% admitted to discovering unknown agents in their infrastructure.
Agents are entities that use identities (human or non-human credentials). There are often no installation footprints. Many agents authenticate as individuals, without announcing themselves as agents, using their creators' tokens. And then there's the preinstalled software like Copilot Studio, added to the corporate software stack with a patch.
Discovery, then, should be behavioral. Agents might authenticate as humans, but they don't behave like them.
But first, let's start with something even simpler: what is an agent?
Decide what counts as one agent
An agent ecosystem consists of three things:
- The entity’s environment, including files, memory, and who can access it
- The tools it can access (via identities)
- A runtime where it executes its actions
The best combination for detection, then, is an entity+runtime pair. Detect the same code running with two different identities, and you'll get different risk profiles which you'll need to account for. Detect the same entity within two different runtimes, and you have a security finding.
The one exception is an agent with delegated tokens, as they let the agent wield that user's identities. Here, we need to go down one level of abstraction and record a single entry for the client, with the delegating users as an attribute, since that's the agent's real reach.
Define a complete record before you pull data
The list of what you'd want to know about an agent is long. Most likely, you'll need to join multiple sources to get that information:
How to run the sweep
OAuth and consent grants
It's not the most important source of data, but it's the easiest to get relevant information from, because the data has already been collected. It's also the one source where you'll find most agents self-provisioned by non-builders via consent screens:
- Google Workspace third-party app access and Marketplace installs.
- Entra enterprise applications with both their delegated and application consent grants.
- Installed Slack apps.
- Connected apps in Salesforce, Atlassian, and Zoom. Salesforce doesn't allow new connected apps since Spring '26, pointing customers to external client apps instead, so check both objects.
The powder keg combination is offline_access with broad read scopes. That's how an app can work without the user present. Also, look for redirect URIs on model-vendor or unfamiliar domains, publishers without a verified domain, a grant one user approved that now shows activity across the tenant, and Microsoft Graph permissions like Mail.ReadWrite or Files.Read.All attached to something described as a meeting assistant.
If you let users consent to the use of their data, you're likely to see a long list here, which is absolutely fine. If only admins can grant consent, the list is bound to be much shorter, but that doesn't mean you don't have shadow AI; it's just obscured by personal accounts, browser extensions, and copy-paste commands.
The identity provider
Your IdP is a trove of behavioral data, not just a list of accounts and tokens. Analyze non-interactive sign-ins to find those that occur at machine cadence, or originate from cloud provider IP ranges. Also, check for accounts that are constantly active with no enrolled devices.
Disregard naming conventions. Reusing an existing service account is faster than provisioning one, so people will do it.
Cloud IAM
In AWS, pull IAM users and roles, the last accessed information on each principal's Last Accessed tab, Identity Center assignments, and Bedrock model invocation logs. Read that last-accessed data as a record of attempts rather than successes, and go to CloudTrail when you need to know which ones worked.
In Google Cloud, pull service accounts and their user-managed keys, along with usage, on the Gemini Enterprise Agent Platform.
In Azure, pull managed identities, application registrations, and the connections behind Microsoft Foundry and Copilot Studio.
Roles whose only recent activity is model invocation are agents. Access keys older than the project that uses them are borrowed identities.
Since what you want people to use are managed identities and workload identity federation, and these leave no keys to find, reading role assignments will detect the more professional AI agentic deployments, whereas just hunting secrets is over-biased towards amateur agent setups.
The agent builders inside your SaaS
Copilot Studio, Salesforce Agentforce, ServiceNow AI Agent Studio, Glean, Notion, Gong, and Zoom are just some of the builders that ship to ordinary users. Each vendor keeps its own inventory. Moreover, the identity they run as differs by vendor too. And sometimes, like in Copilot Studio, the maker can pick for each tool.
Unless you know what's happening, assume the worst: the maker's credentials are now a public interface.
MCP servers and tool surfaces
Pull configuration files from endpoints and repositories: .mcp.json for Claude Code, claude_desktop_config.json for Claude Desktop, .cursor/mcp.json, .vscode/mcp.json. Pull remote MCP endpoints from gateway logs. If an internal registry exists, reconcile it against both.
Don't just grep for JSON, as packaged desktop extensions install servers without any of those files.
Record what each server exposes. The permission model at this layer are the tool definitions. Found shell access? Everything is exposed.
As for MCP servers, the local ones usually execute using the dev's access, without any audit trail.
Code, repositories, and pipelines
Search dependency manifests and SBOMs for openai, anthropic, langchain, llama-index, and crewai.
Search the Microsoft lineage under all three of its names, since AutoGen went into maintenance mode and Semantic Kernel was folded into Microsoft Agent Framework: autogen-agentchat, autogen-core, semantic-kernel, and agent-framework. Found a superseded package in a manifest? You might have an agent nobody has touched in a year.
Enumerate GitHub and GitLab Apps, personal access tokens, and workflows holding model credentials.
Query secret scanning for provider key formats: OpenAI keys carry an sk- prefix and Anthropic keys sk-ant-, both stable. Google complicates matters a bit, as alongside the familiar AIza standard keys, they now issue authorization keys bound to a service account, and have said the Gemini API will reject standard keys from September 2026. And as things are very dynamic in this industry, validate your rules by checking them against newly minted keys.
Developer and user endpoints
Querying endpoints might feel like surveillance, so don't treat it lightly!
If you do decide to do it, query EDR and MDM inventories for Claude Code, Cursor, Devin Desktop (renamed from Windsurf in June 2026, so search for both), Cline, Ollama, LM Studio, agent CLIs, and browser extensions requesting broad host permissions. On machines running coding agents, check for ~/.aws/credentials, .env files, and cloud CLI sessions, because a coding agent inherits everything on that disk.
Egress
Pull proxy, secure web gateway, and DNS records for model provider hostnames. Then, separate interactive traffic from API traffic by path and user agent. Do you see API-shaped calls from server subnets and CI runners?
For self-hosted models, it's not the model-related traffic that makes network noise, but the runtime. Even when running a model entirely on the machine, Ollama and LM Studio check for updates and pull model weights.
Spend
Provider billing consoles, cloud marketplace charges, corporate cards, expense claims, and procurement tickets find agents that cost money, together with whoever paid for them.
Getting from a token to a person
You can't act on discovery without ownership. Or, more precisely, acting on discovery without ownership will likely harm productivity.
Self-declaration is the easiest solution. Ask people to declare their agents, promising help to make them compliant.
For discovery, the most reliable ownership indicator will be creation and first-use events in the logs. Then there are the billing attributes. Key names and comments will describe the intent that can lead to an owner. Searching the ticket system and the corporate messenger for the application name can also help locate the owner.
If all else fails, revoke the license during a low-impact window and wait for the complaint.
Telling agents apart from humans and service accounts
Robotic process automation and older ETL jobs might trip some of these wires. The discriminator is a novel action sequence combined with model-provider egress.
Discovery can’t lag too much behind creation
Agents get created faster than you can review access, so a one-time sweep or even a scheduled discovery sprint won't help you much.
Attach discovery to events: a new OAuth grant, a new service principal with credentials, a first model invocation from a role that never made one, a provider key appearing in a repository, an MCP configuration committed, a charge from an AI vendor nobody recognizes.
Scale demands dedicated solutions
The method above scales to a few hundred agents. Then, it degrades without a dedicated solution.
You can't manually join the fragments of data held in different repositories at this scale. And while every source reports what was granted, they rarely report usage, so you don't know what will break when access is removed.
Moreover, delegated identities stay invisible, and ownership decays. People change teams, but their agents keep their tokens and their access. And if that's not enough, the basic question of coverage remains unmeasurable. You simply don't know what share of your agents you have found.


