Inspect token families

Access tokens and refresh tokens have different lives. Record which device owns each refresh token and what family it belongs to. After a reset, try refreshing from every device and using an existing access token for a sensitive API call. If access tokens remain briefly valid, describe that window honestly and decide which actions must check revocation at once. Test a stolen refresh token reused after legitimate rotation as a separate case.

Test cases and proof

Use test accounts and test data
CaseExpected resultProof to keep
Logout phone AEnd A session under policyRefresh attempt
Password reset with all-session ruleEnd A, B, and browser sessionsToken reuse results
Revoked refresh token reusedReject and record eventAuth log

Synthetic example

Sign in on phone A, phone B, and a browser. Reset the password on B with an all-session sign-out option. Attempt a refresh from A and browser after the reset, not just an API call using a short-lived access token.

Evidence to keep

Keep a device map with session IDs, refresh-token family IDs, and the time each revocation action occurs. Test refresh and privileged API access separately. If the design allows a short access-token window, measure it in staging and make the product copy match. A support lock should have a clear end state across every device.

A mobile app may clear local tokens while the server still accepts them. Test with a direct API request using the old refresh token after the app says logout succeeded. That call reveals the server decision. Capture the result without placing the full token in a report.

Pick revocation scope before writing copy

“Sign out this phone” and “sign out everywhere” are different server actions. Map each to the token families it revokes. An old access token may remain valid for a short set life unless privileged APIs check revocation on each call. If a reset promises immediate account lock, add that server check. Test refresh and transfer calls from every device after the action. The app’s local deletion is only a user interface change unless the server rejects the old credential.

Related reading

Why these checks matter

OWASP’s session guide covers session lifecycle and logout. NIST treats session secrets as proof of ongoing authenticated state. Clearing a phone’s local token copy does not prove that the server ended that state. The direct refresh attempt in this guide checks the server decision.

Race refresh against revocation

Synthetic device D1 holds refresh family F1. D2 holds F2. Pause D1’s refresh after it reads F1 but before issuing a replacement. Revoke F1 from D2, then resume. The new token must not escape the revoked family under the promised rule. Use a version or atomic state check at issuance. Otherwise a refresh that started before logout can create a still-live descendant afterward.

Then revoke all device families and try each old refresh token plus a privileged transfer API. If stateless access tokens remain valid for up to five minutes in this test design, measure that window and name it. Sensitive APIs can use a current account/session gate for faster shutdown. Do not claim that revoking a refresh token necessarily invalidates every already-issued access token.

Keep app sessions separate from the identity provider

If sign-in is federated, ending the app session does not always end the identity provider’s session. After app logout, a new sign-in may complete through the provider without entering a password. Decide whether that is expected for “this device” and “everywhere,” then test both. Do not report silent SSO as reuse of the revoked app token.

Run a control with F2 unchanged after revoking only F1; D2 should still work. Offline copies cannot be erased by a server decision, so record what D1 can still display offline separately from new server access. Keep session IDs, family IDs, issuance and revocation times, refresh outcome, and money-action outcome. OAuth token revocation describes token invalidation scope and propagation; the app defines its user-facing promise.

Source