Skip to content

Serialize refresh-token exchange per identity#240

Closed
markus-lassfolk wants to merge 1 commit into
mainfrom
fix/refresh-token-lock
Closed

Serialize refresh-token exchange per identity#240
markus-lassfolk wants to merge 1 commit into
mainfrom
fix/refresh-token-lock

Conversation

@markus-lassfolk

Copy link
Copy Markdown
Owner

Summary

  • Add per-identity exclusive lock (.refresh-{identity}.lock) around EWS/Graph refresh-token exchange so concurrent CLI processes cannot race Entra RT rotation.
  • After acquiring the lock, re-load the token cache and short-circuit if another process already wrote a valid access token.
  • Document the failure mode briefly in CHANGELOG + skill agent tips.

Context

Observed on Doris (OpenClaw): cron + agent + whoami Graph→EWS fallback can both redeem the same refresh token; the loser persists a stale RT / divergent .env vs cache. Atomic writes alone do not prevent this.

Test plan

  • bun test src/lib/refresh-token-lock.test.ts src/test/auth.test.ts src/test/graph-auth.test.ts (31 pass)
  • Manual: two parallel m365-agent-cli whoami / verify-token with a near-expired access token should serialize refresh without invalid_grant from racing the same RT

Graph and EWS share one refresh token; concurrent CLI processes could
race Entra rotation and persist a stale RT. Take an exclusive
.refresh-{identity}.lock around reload+refresh+persist, and reuse a
fresh access token if another process already refreshed.

Copy link
Copy Markdown
Owner Author

Per request, this PR's fix (refresh-token exchange serialization) has been combined with the fix for #239 into a single joint PR: #241 — same commit as this branch, plus a Biome formatting fixup (this PR's "Quality gate" check was failing purely on formatting drift in auth.ts/graph-auth.ts/refresh-token-lock.test.ts, not on logic) and the #239 fix.

Closing this in favor of #241 to keep the two fixes in one PR. No content is lost — it's all in #241.


Generated by Claude Code

markus-lassfolk added a commit that referenced this pull request Jul 17, 2026
- Add per-identity exclusive lock around EWS/Graph refresh-token exchange so concurrent CLI processes cannot race Entra RT rotation (from #240).
- Ship a Node-runnable dist/ build (tsc + #!/usr/bin/env node shebang) so `npm install -g m365-agent-cli` works without a separately installed Bun runtime; also fixes two relative imports missing .js extensions and a hardcoded ../cli.ts subprocess path in the MCP server.
- Make two TZ-dependent bug-regression tests reliable across environments (spawn a child process with TZ set at birth instead of mutating it mid-process).
- Bump version to 2026.7.7.

Closes #239. Supersedes #240.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant