AntFleet

Disagreement · b7190c33-anthropic-2

Main-agent OAuth fallback copies credentials without acquiring the auth store file lock

mismatch
repo 5149da9d·PR #2·reviewed 2 days ago

Primary finding

Main-agent OAuth fallback copies credentials without acquiring the auth store file lock

mediumconcurrencyhigh
  • src/agents/auth-profiles/oauth.ts:207-226
Everywhere else in oauth.ts the auth store is read and written under `withFileLock` (e.g. refreshOAuthTokenWithLock). This fallback path reads main store via ensureAuthProfileStore(undefined) and writes the secondary agent's store via saveAuthProfileStore without any lock. A concurrent refresh on the secondary agent could overwrite the just-written value, or vice versa, causing torn/lost credentials. This is a data-integrity hazard on the same file used by other code paths that do lock.

Recommendation

Perform the copy inside `withFileLock(authPath, AUTH_STORE_LOCK_OPTIONS, ...)` so the secondary agent's store update is atomic with respect to other writers.

Counterpart finding

Inconsistent config compatibility: tryResolveOAuthProfile rejects token credentials when config.mode is "oauth", but resolveApiKeyForProfile allows it

mediumbughigh
  • src/agents/auth-profiles/oauth.ts:106-112
  • src/agents/auth-profiles/oauth.ts:151-156
  • src/agents/auth-profiles/oauth.ts:219-224
resolveApiKeyForProfile explicitly treats config.mode "oauth" as compatible with stored token-based credentials, but tryResolveOAuthProfile strictly enforces mode equality. In fallback flows, resolveApiKeyForProfile delegates to tryResolveOAuthProfile, which will then reject otherwise compatible token credentials, causing unnecessary failures.

Recommendation

Align tryResolveOAuthProfile with the compatibility rule used in resolveApiKeyForProfile; allow config.mode "oauth" to accept stored token credentials. Alternatively, bypass tryResolveOAuthProfile in the fallback when the stored credential is a token and handle it similarly to resolveApiKeyForProfile.

Why this didn't post

This finding didn't meet AntFleet's unanimous agreement threshold. Both frontier models review every PR independently; only findings they both flag with the same severity and category are posted to the PR. This one fell through.

read the methodology →