{"record":{"id":"0a8d160e86bdea8c","repo":"postalserver/postal","slug":"user-has-oidc-enabled-password-resets-are-not-sup","errorCode":null,"errorMessage":"User has OIDC enabled, password resets are not supported","messagePattern":"User has OIDC enabled, password resets are not supported","errorType":"exception","errorClass":"Postal::Error","httpStatus":500,"severity":"error","filePath":"app/models/concerns/has_authentication.rb","lineNumber":39,"sourceCode":"      user = find_by(email_address: email_address)\n      raise Postal::Errors::AuthenticationError, \"InvalidEmailAddress\" if user.nil?\n      raise Postal::Errors::AuthenticationError, \"InvalidPassword\" unless user.authenticate(password)\n\n      user\n    end\n  end\n\n  def authenticate_with_previous_password_first(unencrypted_password)\n    if password_digest_changed?\n      BCrypt::Password.new(password_digest_was).is_password?(unencrypted_password) && self\n    else\n      authenticate(unencrypted_password)\n    end\n  end\n\n  def begin_password_reset(return_to = nil)\n    if Postal::Config.oidc.enabled? && (oidc_uid.present? || password_digest.blank?)\n      raise Postal::Error, \"User has OIDC enabled, password resets are not supported\"\n    end\n\n    self.password_reset_token = SecureRandom.alphanumeric(24)\n    self.password_reset_token_valid_until = 1.day.from_now\n    save!\n    AppMailer.password_reset(self, return_to).deliver\n  end\n\n  private\n\n  def clear_password_reset_token_on_password_change\n    return unless password_digest_changed?\n\n    self.password_reset_token = nil\n    self.password_reset_token_valid_until = nil\n  end\n\n  def validate_password_presence","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/postalserver/postal/blob/d038eaa8c763d3cafa797ccd6f773d53470bd336/app/models/concerns/has_authentication.rb#L21-L57","documentation":"HasAuthentication#begin_password_reset (used by the forgot-password flow) refuses to mint a reset token when OIDC is enabled AND the user is OIDC-managed (oidc_uid present) or has no password at all (password_digest blank). For such accounts the identity provider owns authentication, so a Postal-issued password reset would be meaningless or would bypass the IdP.","triggerScenarios":"Someone submits the password reset request (login page 'forgotten password', or admin-triggered reset) for a user that was provisioned via OIDC (has oidc_uid), or for a passwordless account while Postal::Config.oidc.enabled? is true.","commonSituations":"SSO users clicking the local reset link out of habit; admins running bulk reset scripts against all users including OIDC ones; mixed installs where some users predate OIDC enablement and some do not; passwordless accounts created purely for OIDC.","solutions":["Reset the password at the OIDC/identity provider instead - that is authoritative for this user","If the user must become a local account, clear their oidc_uid (and set a password) first, then reset","Hide the 'forgotten password' link for OIDC-managed accounts in the UI and skip them in reset scripts","Guard callers with the same condition (oidc.enabled? && (oidc_uid.present? || password_digest.blank?)) before invoking begin_password_reset"],"exampleFix":"# before\nuser.begin_password_reset   # raises for OIDC-managed users\n\n# after\nif Postal::Config.oidc.enabled? && (user.oidc_uid.present? || user.password_digest.blank?)\n  redirect_to login_path, alert: \"This account is managed by single sign-on. Reset your password with your identity provider.\"\nelse\n  user.begin_password_reset\nend","handlingStrategy":"validation","validationCode":"# before triggering a reset\nif Postal::Config.oidc.enabled? && (user.oidc_uid.present? || user.password_digest.blank?)\n  raise ArgumentError, \"#{user.email} is managed by SSO - reset at the identity provider\"\nend","typeGuard":"def local_password_user?(user)\n  !(Postal::Config.oidc.enabled? && (user.oidc_uid.present? || user.password_digest.blank?))\nend","tryCatchPattern":"begin\n  user.begin_password_reset(return_to)\nrescue Postal::Error => e\n  # expected for SSO-managed accounts: inform the user, never fall back to creating a token\n  redirect_to login_path, alert: \"This account uses single sign-on. Reset your password with your identity provider.\"\nend","preventionTips":["Hide forgot-password links and skip reset emails for users with an oidc_uid","Exclude OIDC-managed users from any admin bulk-reset tooling","Decide deliberately (and record) whether a user is local or SSO before setting/clearing oidc_uid","Run a periodic audit for passwordless accounts while OIDC is enabled so they are not accidentally reset"],"tags":["postal","oidc","sso","password-reset","authentication"],"backgroundTag":"sso-password-reset-conflict","analyzedSha":"d038eaa8c763d3cafa797ccd6f773d53470bd336","analyzedAt":"2026-08-21T13:52:57.446Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}