Revoke OAuth tokens, grants, and personal access tokens on password reset/changes · Issue #246 · authify/authify · GitHub
Skip to content

Revoke OAuth tokens, grants, and personal access tokens on password reset/changes #246

Open

Description

@jgnagy

Description

The session-only revocation introduced by #247 (for #148) revokes Guardian
session tokens by bumping a per-user session_version claim
(lib/authify/guardian.ex, lib/authify/accounts.ex). It does not touch the
other credential types a user may hold, so those remain valid after an admin
forces a reset or after the user changes their password:

  • OAuth 2.0 access tokens (oauth_access_tokens) — validated in
    Authify.OAuth.get_access_token/1; only a set revoked_at invalidates them.
  • OAuth 2.0 refresh tokens (oauth_refresh_tokens) — a holder can keep
    minting new access tokens through the refresh_token grant after the reset.
  • Personal access tokens (personal_access_tokens, authify_pat_ prefix)
    used for the Management API — only is_active == false (or deletion)
    invalidates them
    (Authify.PersonalAccessTokens.authenticate_personal_access_token/1).
  • OAuth user grants (consent, oauth_user_grants) are likewise untouched.

SAML SSO sessions (tracked via Authify.SAML) are a related consideration.

Rationale

A forced password reset is usually triggered because an account may be
compromised. Revoking only session tokens leaves bearer credentials issued to
the account (or obtained by an attacker) usable until they expire — up to the
token TTL, and personal access tokens default to one year — which defeats much
of the point of the reset. Standard IdPs revoke refresh tokens, access tokens,
and grants when a password is changed or reset.

Suggested approach

  • Add context functions such as
    Authify.OAuth.revoke_all_tokens_for_user/1 (revoke the user's access tokens
    and refresh tokens, and optionally user grants, reusing
    revoke_access_token/1, revoke_refresh_token/1, and revoke_user_grant/1)
    and Authify.PersonalAccessTokens.revoke_all_for_user/1 (set
    is_active: false or delete).
  • Call them alongside the session-version bump in
    Accounts.force_password_reset/1 and on password changes (mirroring the
    current session-revocation behavior).
  • Decide the semantics: revoke on any password change, and/or only on an
    admin-forced reset, and consider an explicit admin "revoke all sessions and
    tokens" action.

Related

Effort

M

Files

  • lib/authify/accounts.ex (force_password_reset/1, update_user_password/2)
  • lib/authify/o_auth.ex
  • lib/authify/personal_access_tokens.ex
  • lib/authify_web/controllers/profile_controller.ex

Activity

  1. added
    enhancementNew feature or request
    securitySecurity-related issues and improvements
    on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsecuritySecurity-related issues and improvements

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions