Reauthentication

Release 0.2.1 · Reviewed 2026-09-07

Ask a signed-in person to verify again before a sensitive action, then check that proof when your app saves the change.

Enable reauthentication

Start with the RubyGems installation. From your Rails app, run:

Shell
bin/rails generate add_auth:step_up
bin/rails db:migrate

This installs the session and email-link prerequisites. Configure mail delivery and the shared cache as described in the deployment checklist. Install passkeys too if a purpose requires passkey verification.

Declare a purpose

A purpose names the action the proof authorizes. This example assumes your app has an account settings page at /account/security:

Rubyconfig/initializers/add_auth.rb
AddAuth.configure do |config|
  config.step_up.purposes = {
    manage_profile: {
      methods: [:password, :email_link],
      label: "update your profile",
      return_to: "/account/security"
    }
  }
end

return_to must be a fixed local GET page where the person can review and submit the action. Successful verification returns there; it does not replay a previous form submission. Restart the app and run bin/rails add_auth:doctor.

Check proof at the write

The navigation guard takes the person to verification when needed. The mutation helper checks current proof inside the account transaction. This example assumes your User model has a validated display_name field and your app defines account_security_path:

Rubyapp/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
  require_elevated_session purpose: :manage_profile, only: :update

  def update
    attributes = params.require(:account).permit(:display_name)
    result = with_elevated_session(purpose: :manage_profile) do |account|
      account.update!(attributes)
    end

    if result.success?
      redirect_to account_security_path, status: :see_other
    else
      head :forbidden
    end
  end
end

Add your normal validation-error response. For writes to other resources, check ownership, permissions and the current target version inside the block. Let this helper own the transaction; do not wrap it in an outer transaction or make network calls inside it.

Verify, review, then saveA protected action asks for fresh verification. After verification the user returns to a review page and submits again. The app rechecks proof and resource authorization before committing the change.
Verify, review, then saveA protected action asks for fresh verification. After verification the user returns to a review page and submits again. The app rechecks proof and resource authorization before committing the change.AppUserAppUseralt[Checks pass][Proof expired or authorizationdenied]Submit sensitive actionRequest fresh verificationComplete allowed verificationReturn to review pageConfirm action againRecheck proof and resource authorizationSave and show resultRefuse the change
Verify, review, then saveA protected action asks for fresh verification. After verification the user returns to a review page and submits again. The app rechecks proof and resource authorization before committing the change.AppUserAppUseralt[Checks pass][Proof expired or authorizationdenied]Submit sensitive actionRequest fresh verificationComplete allowed verificationReturn to review pageConfirm action againRecheck proof and resource authorizationSave and show resultRefuse the change

Scroll sideways on a small screen to read the full diagram.

View diagram source
Mermaidstep-up-action.mmd
sequenceDiagram
    accTitle: Verify, review, then save
    accDescr: A protected action asks for fresh verification. After verification the user returns to a review page and submits again. The app rechecks proof and resource authorization before committing the change.
    participant User
    participant App
    User->>App: Submit sensitive action
    App-->>User: Request fresh verification
    User->>App: Complete allowed verification
    App-->>User: Return to review page
    User->>App: Confirm action again
    App->>App: Recheck proof and resource authorization
    alt Checks pass
        App-->>User: Save and show result
    else Proof expired or authorization denied
        App-->>User: Refuse the change
    end

A proof is tied to the account, session and purpose. It is reusable within its configured freshness window; your app owns one-time business confirmation and request idempotency. A revoked or changed session cannot reuse an old proof to save the action.

Choose permitted methods

MethodBehavior
:passwordChecks the current account password. Strict accounts cannot use it.
:email_linkUses a five-minute link bound to the initiating account, session, browser and purpose. Ordinary sign-in links cannot elevate a session.
:passkeyRequires the passkey feature and verified user verification. Password or email proof cannot satisfy a passkey-only purpose.

General proof freshness defaults to ten minutes; passkey proof freshness defaults to five minutes. See the configuration reference. An unknown purpose or unavailable required method denies the action.

Try the complete action

  1. Sign in and submit the protected action. Confirm that fresh verification is requested.
  2. Complete verification and check that the app returns to the review page without changing the resource.
  3. Submit the action again and confirm the intended change.
  4. Try an expired proof or revoke that session from another browser. The protected write must be refused.
  5. Repeat the permitted password/email path with JavaScript disabled.

If verification repeats unexpectedly, check the purpose spelling, allowed methods, freshness window and session expiry. Next, configure recovery and strict policy.

Something unclear? Suggest a correction Release status

Search documentation

Type to find a guide.

Use Tab to move through results. Escape closes search.