Which account was your coding agent using? Where to look on disk.
Shadow AI used to mean a browser tab. Now it also means a coding agent on a company laptop, reading the repository and running commands with the developer's permissions, signed in to an account the company has never seen.
Sometimes the agent itself was never approved. Sometimes the agent is fine and the account is the problem: a personal plan where the company expected a business one. Company SSO, admin controls and data terms may not apply to that account, and the vendor's admin console only lists accounts your organisation owns.
So when you need to know, the question is simple and the answer is awkward: which account was that agent signed in to?
A tool on the endpoint can tell you an agent ran. The account is a different question. The most useful local answer is often in files the agents wrote for their own use. This post lists where four of them keep it, and how far each one can be trusted. None of it needs anything installed in advance, which matters because the sensor I build cannot help with anything that happened before it was installed.
Before you touch anything
- These files sit beside live credentials. Pull out the one field you need. Do not paste a whole file into a ticket, and treat a triage collection that includes them as sensitive. OpenAI says the same about its own file: handle it like a password.
- Work from a copy where you can. Do not open the agent to have a look. Launching it can refresh the sign-in and overwrite the state you came to read.
- An email address is personal data. If the domain answers your question, keep only the domain, and check what your policy allows before looking at a named person's account.
- Check every user profile on the machine, not only the one you expect.
Cursor
Cursor keeps a SQLite database at the path below on Windows. The address is in the ItemTable table under cursorAuth/cachedEmail. The access token is in the same table under its own key, so query the one row and do not dump the table.
%APPDATA%\Cursor\User\globalStorage\state.vscdb SELECT value FROM ItemTable WHERE key = 'cursorAuth/cachedEmail';
What it tells you: the account Cursor had cached when the file was last written. It does not tie that account to any one request.
Claude Code
~/.claude.json, or the same file under CLAUDE_CONFIG_DIR if that is set, has an oauthAccount object. Look at emailAddress and organizationUuid.
What it tells you: the account last signed in on this machine. A machine now using an API key or another provider can still hold an older sign-in here, so check how Claude Code was configured before relying on it.
Codex
Codex has the most useful artifact of the four, because it is written per session. Each session file sits under ~/.codex/sessions/<yyyy>/<mm>/<dd>/ as rollout-*.jsonl, or under CODEX_HOME if that is set. Its first line is a session_meta record whose payload has creator_account_id and creator_user_id. Read only that first line, because the rest of the file is the session itself.
Those are opaque IDs, with no address in them. For a domain you need the sign-in file, auth.json in the same home. When auth_mode is chatgpt, the id_token carries an email claim. This prints the domain and nothing else:
import base64, json, os, pathlib
home = pathlib.Path(os.environ.get("CODEX_HOME", pathlib.Path.home() / ".codex"))
auth = json.loads((home / "auth.json").read_text())
part = auth["tokens"]["id_token"].split(".")[1]
claims = json.loads(base64.urlsafe_b64decode(part + "=" * (-len(part) % 4)))
print(claims.get("email", "").rpartition("@")[2])What it tells you: the session file names the account for that session. The sign-in file names whoever is signed in now, which can be a different account. The file may not exist at all: Codex can keep credentials in the operating system's store instead, and an API-key sign-in has no email to read.
Antigravity
On Windows, %APPDATA%\Antigravity\app_storage.json has the key jetski.onboarding.lastLoginUsername.
What it tells you: as the name says, the last login. It is not a record of who made any particular call.
How much weight this can carry
- None of this is verified identity. These are local files that anyone with access to the machine could edit. They are leads to confirm against something else.
- Most of it is a snapshot. Apart from the Codex session record, you are reading the latest sign-in, and it may have changed since the moment you care about.
- A signed-in account is not a person. Accounts get shared, and several people can use one domain.
- Personal is easier to spot than corporate. A public email provider is clear. A custom domain usually means a company, but it can be somebody's own.
- Nothing found is not a clean result. It can mean an API key, a keyring, a removed profile, or an agent whose account I have not found a safe place to read. Copilot and ZCode are in that last group.
Collecting it before you need it
Disk artifacts are what you have after the fact. Two vendors document a way to get the account as it happens. Cursor's hooks pass a user_email field when it is available. Claude Code's OpenTelemetry export carries user.email and organization.id when they are available. Its user.id is a random identifier, not an account, so do not build on that one.
This is also why I added an Identity page to Agentmetry, an open-source, local-first sensor for coding agents. It records the tool calls agents report through their hooks and does not forward prompts. Since 0.11.0 it also keeps the account each agent reported, as the domain unless you opt in to full email, shows it beside the detection you are investigating, and lists agents that report nothing as unknown. For Codex, the domain is opt-in, because it means reading that credential file. It has the same limits as everything above: these are reported claims, and it only knows what happened after it was installed.
uvx agentmetry demo
What I checked
I confirmed these locations on one Windows 11 machine on 8 November 2026, looking at key names only, with the versions installed that day. Most of them are undocumented internals, and any update can move them. I have not checked the macOS or Linux locations. The Claude Code and Codex paths are relative to the home folder, so they should carry over; Cursor and Antigravity keep their files in application folders that differ by platform.
If you know a location I have missed, or one of these has moved, open an issue and I will correct this page.