Skip to content

Store acquired OAuth tokens in the secret store; stop stale-snapshot clients from clobbering oauth.json #2481

Description

@BobDickinson

1. Acquired OAuth tokens are stored in plaintext in oauth.json

The secret store (OS keychain, with secrets.json/memory fallbacks, #1356/#1950) protects OAuth client secrets, the enterprise IdP client secret, and stdio env: values — but the most sensitive values the Inspector holds never went there. Access, refresh, and ID tokens acquired by completing an OAuth flow, IdP session tokens (EMA), and dynamically registered (DCR) client secrets are all written in plaintext to ~/.mcp-inspector/storage/oauth.json.

Proposal: split oauth.json at the persistence choke point. The file keeps only non-secret state (flow bookkeeping, discovered metadata, public client ids) and acts as the index; token material lives in the secret store, joined back on read. A pre-existing plaintext oauth.json is migrated lazily on first read when the store is durable (under the memory store the file stays authoritative — it is the only durable copy). A new MCP_INSPECTOR_PERSIST_TOKENS=all|access|none variable controls which acquired tokens are persisted at all (access drops refresh tokens; none means re-auth every run; registration client secrets persist regardless).

2. Concurrent clients clobber each other's oauth.json state

Every mutation flushes the client's entire in-memory snapshot over the shared file. A long-lived client holding a stale snapshot (web page, TUI) erases entries other processes wrote since it loaded — e.g. an IdP login completed in the CLI is destroyed by any subsequent web-client auth write (observed in practice).

Proposal: mutation-scoped writes — each mutation names the sections (server entries / IdP sessions) it touched, and the persist layer overlays only those over a fresh locked read of the file. A stale client can no longer destroy entries it didn't touch.

Read-side staleness (a long-lived client not seeing other clients' writes) is a separate, smaller problem and is deliberately out of scope here; it will be addressed after the daemon-cli work merges.

Docs: docs/secret-storage.md, docs/environment-variables.md, README/Docker/CLI-README security wording.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature requestv2Issues and PRs for v2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions