Shadow AI Agents: Finding the Assistants Your Team Already Connected
Your team has almost certainly connected AI assistants to work tools already, one sign-in at a time. Where to look for them, in the identity provider, the tools, the repositories and the key lists, and what to do next without making anyone regret telling you.
7 min read
Shadow AI agents are AI assistants connected to your team’s tools without anyone deciding that they should be: an assistant someone approved to read their mailbox, an MCP server added to a repository, a token pasted into a script on a laptop. You find them in four places. The identity provider lists every app people have granted access to. Each work tool lists the connections and tokens that reach it. Repositories hold MCP configuration files. And AI providers’ consoles hold the keys people created. Then you sort what you find into keep, move and revoke, and you do it without blame, because the person who connected an assistant was usually trying to get work done, and you want them to tell you about the next one.
What counts as a shadow agent
Anything that lets an AI act on team data or systems and is not on the list of what the team has agreed to. In practice that is three kinds of thing:
- OAuth grants. Someone clicked “Allow” when an assistant asked to read their calendar, files or email. The assistant now holds a token for that account.
- MCP servers. A server in a project configuration, a user configuration, or run locally from a package someone found. OWASP’s MCP Top 10 (opens in a new tab), still in beta, lists these as “Shadow MCP Servers” (MCP09:2025): deployments outside formal security governance, often with permissive settings or default credentials.
- Keys and tokens. An API key for a model provider, or a personal access token for a code host or a board, sitting in a script, a scheduled job or an environment file.
None of these needs an administrator. That is the point of them: connecting is designed to be easy. It is also why a list kept from memory is always short.
Look in the identity provider first
If your team signs in with Google Workspace or Microsoft, the identity provider already knows which apps people have granted access to. This is the quickest, most complete list you will get.
In Google Workspace, the Admin console’s API controls include Manage App Access (opens in a new tab). Its Accessed apps list shows each third-party app, how many users are using it, and which Google services it requested, such as Gmail, Calendar or Drive. From there an app can be set to Trusted, Limited, Specific Google data or Blocked, and you can decide what happens for apps nobody has configured.
For the history rather than the current state, Google’s OAuth log events (opens in a new tab), under Reporting, Audit and investigation, record each time a third-party app is authorised to access account data, searchable by app name, scope and user. That tells you when each grant started, which matters when you ask what an assistant could have read.
In Microsoft Entra, apps people consent to appear as enterprise applications. Microsoft’s guide to reviewing permissions granted to enterprise applications (opens in a new tab) shows each app’s Permissions page with two tabs: Admin consent, for permissions granted for the whole organisation, and User consent, for permissions individual people granted. Note its warning: revoking a permission does not stop people consenting to it again.
That warning matters because of the default. According to Microsoft’s page on configuring user consent (opens in a new tab), by default all users may consent to apps for permissions that do not require an administrator, and changing the setting affects only future consents; existing grants stay until you revoke them.
Then the tools themselves
Tools your team signs in to separately keep their own lists. Go through each shared tool and find where it lists connected apps and tokens. On GitHub, organisation owners can review and revoke fine-grained personal access tokens (opens in a new tab) that have access to the organisation, under Settings, Personal access tokens, Active tokens. The same page notes the limit: owners cannot see classic tokens there, and unless the organisation restricts them, a classic token can reach organisation resources until it expires.
Also check each AI provider’s console for API keys, and note who created them and when they were last used, where the console shows it.
Then the repositories
MCP servers shared by a project live in files in the repository, so they can be found with a search. Claude Code keeps project servers in .mcp.json, VS Code in .vscode/mcp.json, and Cursor in .cursor/mcp.json. Personal servers live in each person’s home directory instead, in ~/.claude.json for Claude Code and ~/.cursor/mcp.json for Cursor, so those need people to look for themselves.
# Project MCP configuration committed to the repository git ls-files | grep -E '(^|/)(\.mcp\.json|\.vscode/mcp\.json|\.cursor/mcp\.json)$' # What Claude Code on this machine connects to here: run it inside each project folder claude mcp list
While you are there, look for keys committed by mistake in environment files and configuration. A key found in a repository should be revoked and reissued, not just deleted from the file, because it stays in the history.
Ask, as well as search
Searches miss things: a browser assistant with its own sign-in, a script on a home machine, a trial of something new. So ask everyone the same three questions, in writing, with no consequences attached: which AI assistants do you use for work; what have you connected them to; and is anything running on a schedule. Put the answers next to what the searches found. Where the two disagree is where the real list is.
Keep, move or revoke
For every connection you find, make one of three decisions, and write it down with the person who owns it.
- Keep. It is useful and its access is proportionate. Add it to the approved list with an owner and a purpose.
- Move. The job is fine but the route is not: a shared key where each person should sign in, a write scope on something that only reads, a server run from an unpinned package. Set it up the approved way, then remove the old one.
- Revoke. Nobody uses it, nobody owns it, or it reaches data it should not. In Google, block the app; in Entra, revoke the permissions and tighten consent so it cannot simply be granted again.
Doing it without blame
The first sweep decides whether the second one works. If the first person who admits to connecting an assistant gets told off, nobody admits to the next one, and the list goes back underground. Treat the first sweep as an amnesty: everything found is registered or moved, nobody is named in a meeting, and the lesson is about the route, not the person. If people connected assistants without asking, the usual reason is that asking was slower than not asking. Fix that by giving them a short, quick way to get something approved, which is the “approved tools” clause in a one-page AI agent policy.
Keeping them from coming back
- Tighten the defaults you found: user consent in Entra, unconfigured-app access in Google Workspace.
- Put MCP configuration under code review. A server added to
.mcp.jsonthen arrives as a change someone reads. - Give every connection an owner and a purpose, and revoke on a trigger: the owner leaves, it goes unused for a month, the job is done.
- Repeat the sweep monthly as part of auditing your AI agents, so the list is checked against what the tools report rather than against memory.
What a board shows you
On fenbs, the connection list is part of the product rather than something to reconstruct. Your connections lists every AI assistant connected to your account by name, with its scopes and when it was last used, and shows every board an assistant acting as you could reach. Settings, “Connect an AI assistant”, lists each token with its name, scopes and optional expiry, and revoking one stops it at once without signing you out; revoked tokens stay listed, so the record of what was connected survives. An assistant that signs in through the browser gets an hour-long access token that is renewed with a refresh token, and revoking the connection ends both. Each connection works on the one board chosen when it was approved, and every change it makes is recorded in History as “Claude via” the person it acts for.
Related
How roles and scopes limit what an assistant can do: assistant tokens and scopes. Giving the ones you keep the least access that works: how to give an AI agent access to your project board. The risks unapproved servers bring: MCP security risks.