Browsers and password managers (such as Google Password Manager) have a "Change password" button, and they need to know where your change password form lives. The well-known change-password URL answers that. This article documents the steps to add it to a Rails app,


The rules

  1. The path is fixed: /.well-known/change-password at the root of your origin.

  2. Respond with a temporary redirect (302, 303, or 307) to the real page. Do not serve the page at the well-known URL itself.

    Reference: https://w3c.github.io/webappsec-change-password-url/#semantics

    GET /.well-known/change-password HTTP/1.1
    Host: example.com
    
    HTTP/1.1 303 See Other
    Location: https://example.com/profile/edit#change-password
    
  3. Unknown well-known paths must not return a success status. If a 2xx returns (after following redirects), your server is treated as unreliable.


The implementation

  1. Add a routing-level redirect with an explicit status:

    # config/routes.rb
    Rails.application.routes.draw do
      get "/.well-known/change-password",
          to: redirect("/profile/edit#change-password", status: 303)
    end
    
  2. (Optional) For a password manager that performs automatic password change, add a autocomplete hint to the password field.

    <div id="change-password">
    	...
        <%= form_with model: @user, url: profile_path, method: :patch do |form| %>
        <%= form.password_field :current_password, autocomplete: "current-password" %>
        <%= form.password_field :password, autocomplete: "new-password" %>
        <%= form.password_field :password_confirmation, autocomplete: "new-password" %>
        <%= form.submit "Update Password" %>
      <% end %>
    </div>
    

    Reference: https://developer.chrome.com/docs/identity/automated-password-change


Notes

Signed-out users should land on your login page. This is expected.