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.

In each repository, and on each machine
# 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.json then 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.

Questions people ask.

What are shadow AI agents?

AI assistants connected to a team’s tools or data without the team having agreed to them: OAuth grants people approved themselves, MCP servers added to repositories or laptops, and API keys or personal tokens used in scripts. They are rarely malicious; they are usually someone trying to get work done faster.

How do I find AI apps people have connected to Google Workspace or Microsoft 365?

In Google Workspace, use the Admin console API controls, Manage App Access, and look at Accessed apps, then check OAuth log events for when each grant started. In Microsoft Entra, look at enterprise applications and each app’s Permissions page, where the User consent tab shows what individuals granted.

Is revoking an OAuth grant enough?

Not always. Microsoft notes that revoking permissions does not stop users consenting again, so tighten the consent setting as well, or block the app in Google Workspace. And revoke keys found in repositories rather than just deleting them, because they remain in the history.

Should people be disciplined for connecting unapproved AI assistants?

Not on the first sweep. Treat it as an amnesty, register or move what you find, and fix the reason people went around the process, which is usually that asking took too long. Blame makes the next connection invisible.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.