Back to posts
AINews

Logging out everywhere does not reach the credential your coding agent stored

A stolen session is not a stolen password, so changing the password evicts nobody. And on a developer machine the browser cookie is the smallest of the problem: one keychain query on this laptop returned seven credential entries written by four AI tools, none of which a claude.ai sign-out touches. The inventory command, what each revoke surface reaches, and the order that works.

There is one symptom worth knowing how to read: your usage limits look like they refilled and then drained while you were not using the tool. Anthropic used almost exactly that phrasing in an email it sent to affected Claude users late last week, telling them that infostealer malware on their own computers had taken active login sessions and spent their usage through them.

The reflex when an account is compromised is to change the password. In this case that step accomplishes nothing on its own, and understanding why is more durable than the incident that prompted it.

A session is not a password

Authentication produces a session token, and that token is a bearer credential. It carries the proof that authentication already happened, which is the whole reason you are not asked to log in again on every page load. Whoever holds it is logged in.

That property is what makes 2FA and SSO irrelevant here. Both are gates on the login. The theft occurs after the gate, on the far side, where there is no second factor left to demand because nothing is being authenticated any more. The same logic disposes of the password change: a new password governs the next login, and the attacker is not performing one.

What ends a bearer credential is revocation at the issuer. That is a different button from the one that changes your password, and on a developer machine it is several different buttons.

Run this before you decide what to rotate

On macOS, ask the login keychain which services have written a credential into it:

security dump-keychain | grep -o '"svce"<blob>="[^"]*"' | sort -u \
  | grep -iE 'claude|codex|cursor|copilot|windsurf|openai|anthropic'

That reads entry names only and does not prompt. (Adding -d is what asks the keychain to hand over secrets, one confirmation per item. You do not need it for an inventory, so leave it off.)

On the machine this post was written on, it returns seven entries from four different tools:

"Claude Code-credentials"
"Claude Safe Storage"
"Codex Safe Storage"
"Cursor Safe Storage"
"Windsurf Safe Storage"
"cursor-access-token"
"cursor-refresh-token"

None of those are cookies in a browser profile, and clicking Log Out in claude.ai settings does not reach any of them. Anthropic's help article on managing active sessions covers browser and device sessions and says nothing about API keys or CLI tokens, which is accurate for what that screen does and is also the gap: on a laptop that runs coding agents, the browser session is the smallest part of what is stored.

This matters more on macOS than the family names suggest. Of the malware Anthropic named, the Windows strains were Vidar, LummaC2, StealC, RedLine and Acreed; the macOS one was Atomic Stealer, whose specialty is the keychain. The surface it goes after is the one the list above enumerates.

What each revoke surface reaches

CredentialWhere it livesWhat ends it
claude.ai web sessionBrowser cookieSettings → Account → Active sessions, then ⋮ → Terminate; or the Log Out button for every device at once
Claude Code login (macOS)Encrypted login keychain, service Claude Code-credentials/logout in Claude Code
Claude Code login (Linux)~/.claude/.credentials.json, mode 0600/logout
Claude Code login (Windows)%USERPROFILE%\.claude\.credentials.json/logout
Long-lived CLI tokenWherever you pasted CLAUDE_CODE_OAUTH_TOKEN after running claude setup-tokenNothing local. The command prints the token and stores it nowhere, so only you know which CI secret store and shell profile hold copies
API keys.env files, CI secrets, ANTHROPIC_API_KEY in your shell profileRotation in the Claude Console. A revoked web session does not touch a key
Anthropic profile~/.config/anthropic on macOS and Linux, %APPDATA%\Anthropic on Windowsant auth logout, or delete the profile file under configs/

Two entries in that table are worth pausing on.

The macOS row has a fallback most people never see. When the keychain refuses the write, which happens when it is locked in an SSH session, Claude Code writes the same credential to ~/.claude/.credentials.json at mode 0600 instead. If you have ever logged in over SSH on a Mac, check for the file as well as the keychain entry. Setting CLAUDE_CONFIG_DIR moves that file elsewhere and keys the keychain entry to that directory too, so a fleet with a custom config dir has its credentials somewhere other than the default path.

The setup-token row is the one that outlives everything else. That token is valid for a year, it is designed to sit in CI where no browser login is possible, and it is the only credential in the table whose locations exist purely in your memory of where you pasted it. Revoking sessions in a web UI leaves every copy working.

The other tools in the keychain output each have their own sign-out, and they are not interchangeable. The point of the inventory is not that one command fixes them; it is that until you run it, you are estimating how many credentials that machine holds, and the estimate is usually low.

The order

  1. Remove the malware first. Anthropic was explicit that signing out does not remove it: "If it's still on your computer, your next login session could be stolen the same way." Every revocation you perform before the machine is clean produces a fresh credential on an infected host.
  2. Revoke the sessions, current and other, from Active sessions.
  3. Rotate what was sitting on disk — API keys in the Console, the setup-token copies, anything in a .env the malware could read as your user. Run /logout in each agent CLI.
  4. Log back in. Last, not first.

Steps 1 and 2 are frequently inverted, which is the version that fails.

Checking whether it happened to you

Do not use /usage for this. The plan breakdown it shows is computed from local session history on that machine, and Anthropic's own documentation states that usage from other devices and from claude.ai is not included. A session stolen and spent from somebody else's computer is precisely the case /usage cannot see. It is the wrong instrument here, and reading a clean screen as an all-clear is the failure mode.

The surfaces that do see it are the ones the account keeps rather than the ones your laptop keeps: Settings → Usage on claude.ai for consumption, and the Active sessions list for presence. Each session there shows the device and browser, an approximate location from the IP address, and when it was last used. You are looking for a row you cannot account for, and for consumption in hours you were not working.

For an organization on the Claude Console, the API keys are enumerable rather than eyeballed. GET /v1/organizations/api_keys lists them with expires_at and the principal each one acts as, and POST /v1/organizations/api_keys/{apikey_id} with {"status": "inactive"} disables one. Both need an Admin API key, and the Admin API is not available on individual accounts, so on a personal plan this stays a Console task.

Where this stops

Two earlier posts here cover what an agent is permitted to do: tool access as the attack surface and what a sandbox rule does not cover. This is the adjacent question and a separate one, about what is sitting at rest on the machine the agent runs on. A containment rule that perfectly governs Claude Code's behavior does nothing about a keychain entry read by a process that is not Claude Code at all, running as the same user with the same permissions.

Which is the part worth keeping if the incident fades: your account and your machine are two surfaces, they revoke separately, and the tools you installed to write code have been quietly writing credentials to the second one.

On the sourcing. Anthropic has published nothing about this on its newsroom, status page or support site. The email text reaches everyone through a single chain — an affected user posted it to Reddit, BleepingComputer reported it on August 30, and subsequent coverage traces back to the same text. Treat it as confirmed that the email exists and says what it says, not as a published investigation; Anthropic states its own is ongoing. The mechanics above hold regardless of how that investigation concludes, which is the reason to act on them rather than on the incident.

Get the next post when it ships

One email on Sunday with the new post and a short list of what shipped that week — new guides, tool updates, and a couple of links worth reading.