ccswitch stores Claude Code OAuth sessions — an access token and a refresh
token per saved account. A refresh token is enough to obtain new access tokens,
so treat one exactly as you would the password to the account.
| Platform | Store |
|---|---|
| macOS | login Keychain, service ccswitch |
| Linux, Windows | ~/.ccswitch/secrets/, files mode 0600 |
This mirrors where Claude Code itself keeps credentials on each platform. The
profile metadata written to ~/.ccswitch/profiles/ contains no token: it holds
the account email, plan, organisation and the last usage snapshot only.
Writing a Keychain item shells out to Apple's security tool and passes the
secret as a command-line argument:
security add-generic-password -U -s <service> -a <account> -w <secret>
Process arguments are visible to other users on the same machine through ps
for the duration of the call — a few milliseconds.
This is not a preference. security accepts a secret two ways: on the command
line, or from its interactive prompt when -w is passed last. The prompt
truncates input at 128 characters, and an OAuth token is far longer, so the
prompt cannot be used. The alternative is linking Security.framework through
cgo, which removes the exposure but ties the Keychain access control list to the
compiled binary, so every user would have to re-approve access after every
upgrade.
The exposure matters on a shared machine and does not on a single-user laptop.
If you are on a shared macOS machine, set CCSWITCH_CREDENTIALS_BACKEND=file
to keep this tool away from the Keychain.
- It never contacts Anthropic or any other network service. Every number it shows is read from files Claude Code already wrote.
- It never sends telemetry.
- It reads and writes only
~/.claude.json, Claude Code's credential store, and its own directory.
Open a security issue at https://github.com/edglz/ccswitch/security/advisories/new — please do not file a public issue for a vulnerability.