Plugin signs itself out: concurrent refreshes trip the reuse guard #6

Open
opened 2026-09-14 18:45:58 +01:00 by cruelacid · 1 comment
Owner

Root cause (14 Sep 2026, production data): with the settings pane open, several loaders 401 together when the access token expires, each calls refreshCloudSession() with the same refresh token, and identity treats the second as reuse and revokes the session. Fix: single-flight refresh, callers pass the token they were refused with, own-row by session id, sign-in/out/refresh log lines, forced sign-out keeps folder mappings; identity logs reuse with seconds since rotation. Checkpoint: unit + identity tests + e2e (three concurrent recoverIdentitySession calls stay signed in), mutation checks, identity + plugin deployed, both vaults left open past ten minutes without a sign-out.

Root cause (14 Sep 2026, production data): with the settings pane open, several loaders 401 together when the access token expires, each calls refreshCloudSession() with the same refresh token, and identity treats the second as reuse and revokes the session. Fix: single-flight refresh, callers pass the token they were refused with, own-row by session id, sign-in/out/refresh log lines, forced sign-out keeps folder mappings; identity logs reuse with seconds since rotation. Checkpoint: unit + identity tests + e2e (three concurrent recoverIdentitySession calls stay signed in), mutation checks, identity + plugin deployed, both vaults left open past ten minutes without a sign-out.
Author
Owner

Checkpoint, 14 Sep 2026 — ca0e097 (plugin + identity), guard f7f6e28. Root cause proven from production device_sessions: refreshed and revoked in the same second, no supersession, no external revoke; two concurrent refreshes from the settings loaders presented one token and identity read the second as reuse. Fix: SingleFlight refresh, callers pass the token they were refused with, own row by session id, sign-in/out/refresh log lines, forced sign-out keeps folder mappings; identity logs 'Refresh token reuse; session revoked' with secondsSinceRotation. Unit 6+2+2 new, identity test, e2e (three concurrent recoverIdentitySession calls stay signed in; with the gate removed the real identity service revoked the session and the test failed). Mutations caught: no gate, no token comparison, throw on 401, wipe mappings, sub for sid, identity fields dropped. Deployed: identity fd10cd8 (revocationsOk true), plugin installed in both vaults. Left for the user: leave both vaults' settings open past ten minutes and see no sign-out.

Checkpoint, 14 Sep 2026 — ca0e097 (plugin + identity), guard f7f6e28. Root cause proven from production device_sessions: refreshed and revoked in the same second, no supersession, no external revoke; two concurrent refreshes from the settings loaders presented one token and identity read the second as reuse. Fix: SingleFlight refresh, callers pass the token they were refused with, own row by session id, sign-in/out/refresh log lines, forced sign-out keeps folder mappings; identity logs 'Refresh token reuse; session revoked' with secondsSinceRotation. Unit 6+2+2 new, identity test, e2e (three concurrent recoverIdentitySession calls stay signed in; with the gate removed the real identity service revoked the session and the test failed). Mutations caught: no gate, no token comparison, throw on 401, wipe mappings, sub for sid, identity fields dropped. Deployed: identity fd10cd8 (revocationsOk true), plugin installed in both vaults. Left for the user: leave both vaults' settings open past ten minutes and see no sign-out.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Nectenda/nectenda#6
No description provided.