feat: current password enforcement (auth) and docs (#43324)

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Feature and docs. 


## What is the new feature?

Adds a toggle to enforce current password checks for updating a user's
password (auth)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added configurable option to require the current password when
changing passwords.
* Added configurable option to require recent reauthentication before
allowing password changes.

* **Documentation**
* Added "Password security" guide sections documenting current-password
verification and reauthentication safeguards, with usage examples.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-04-03 08:09:04 +00:00
1 parent 3b7052b5a9
commit d970327ef7
6 files changed
+48 -1

No files matched your search

@@ -32,6 +32,35 @@ Leaked password protection is available on the Pro Plan and above.
</Admonition>
## Require reauthentication when changing password
Users will need to be recently logged in to change their password without requiring reauthentication. (A user is considered recently logged in if the session was created within the last 24 hours.) If disabled, a user can change their password at any time.
When enabled, a `nonce` will be sent to the user and this nonce must be validated before the a password change can occur. This can be triggered with the [reauthenticate()](/docs/reference/javascript/auth-reauthentication) API call.
```
const { error } = await supabase.auth.reauthenticate()
...
// send the nonce provided by the user with the password change
const { data, error } = await supabase.auth.updateUser({
email: 'user@email.com',
nonce: `${nonce}`,
password: "new_super_strong_password"
})
```
## Require current password when changing password
Enforce that users supply their current password when trying to change the password. When enabled, the password change request will validate that the current password is correct before updating the user's password.
```
const { data, error } = await supabase.auth.updateUser({
email: 'user@email.com',
current_password: "correct_current_password",
password: "new_super_strong_password"
})
```
## Additional recommendations
In addition to choosing suitable password strength settings and preventing the use of leaked passwords, consider asking your users to:
@@ -33,6 +33,12 @@ const PROVIDER_EMAIL = {
If disabled, a user can change their password at any time.`,
type: 'boolean',
},
SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD: {
title: 'Require current password when updating',
description: `Requires that the user supplies their current password when changing their password. [Learn more](${DOCS_URL}/guides/auth/password-security#require-current-password-when-changing).`,
type: 'boolean',
isPaid: false,
},
PASSWORD_HIBP_ENABLED: {
title: 'Prevent use of leaked passwords',
description: `Rejects the use of known or easy to guess passwords on sign up or password change. Powered by the HaveIBeenPwned.org Pwned Passwords API. [Learn more](${DOCS_URL}/guides/auth/password-security#password-strength-and-leaked-password-protection)`,
@@ -70,7 +76,6 @@ const PROVIDER_EMAIL = {
},
],
},
MAILER_OTP_EXP: {
title: 'Email OTP expiration',
type: 'number',
@@ -2493,6 +2493,7 @@ export interface components {
security_manual_linking_enabled: boolean | null
security_refresh_token_reuse_interval: number | null
security_update_password_require_reauthentication: boolean | null
security_update_password_require_current_password: boolean | null
sessions_inactivity_timeout: number | null
sessions_single_per_user: boolean | null
sessions_tags: string | null
@@ -2591,6 +2592,7 @@ export interface components {
| null
security_manual_linking_enabled?: boolean | null
security_update_password_require_reauthentication?: boolean | null
security_update_password_require_current_password?: boolean | null
security_refresh_token_reuse_interval?: number | null
mailer_otp_exp?: number
mailer_otp_length?: number | null
@@ -14,6 +14,7 @@ export const authFieldLabels: Record<
mailer_autoconfirm: 'Confirm Email',
mailer_secure_email_change_enabled: 'Secure Email Change',
security_update_password_require_reauthentication: 'Secure Password Change',
security_update_password_require_current_password: 'Require Password Change',
password_hibp_enabled: 'Prevent Leaked Passwords',
password_min_length: 'Minimum Password Length',
password_required_characters: {
@@ -112,6 +113,12 @@ export const authEmailProviderSchema = z
.describe(
'Users will need to be recently logged in to change their password without requiring reauthentication. (A user is considered recently logged in if the session was created within the last 24 hours.) If disabled, a user can change their password at any time.'
),
security_update_password_require_current_password: z
.boolean()
.optional()
.describe(
'Users will need to provide their current password in order to change their password. Works alongside security_update_password_require_reauthentication and both can be enabled at the same time.'
),
password_hibp_enabled: z
.boolean()
.optional()
+2
View File
@@ -2317,6 +2317,7 @@ export interface components {
security_refresh_token_reuse_interval: number | null
security_sb_forwarded_for_enabled: boolean | null
security_update_password_require_reauthentication: boolean | null
security_update_password_require_current_password: boolean | null
sessions_inactivity_timeout: number | null
sessions_single_per_user: boolean | null
sessions_tags: string | null
@@ -4063,6 +4064,7 @@ export interface components {
security_refresh_token_reuse_interval?: number | null
security_sb_forwarded_for_enabled?: boolean | null
security_update_password_require_reauthentication?: boolean | null
security_update_password_require_current_password?: boolean | null
sessions_inactivity_timeout?: number | null
sessions_single_per_user?: boolean | null
sessions_tags?: string | null
+2
View File
@@ -6985,6 +6985,7 @@ export interface components {
SECURITY_REFRESH_TOKEN_REUSE_INTERVAL: number
SECURITY_SB_FORWARDED_FOR_ENABLED: boolean
SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION: boolean
SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD: boolean
SESSIONS_INACTIVITY_TIMEOUT: number
SESSIONS_SINGLE_PER_USER: boolean
SESSIONS_TAGS: string
@@ -10158,6 +10159,7 @@ export interface components {
SECURITY_REFRESH_TOKEN_REUSE_INTERVAL?: number | null
SECURITY_SB_FORWARDED_FOR_ENABLED?: boolean | null
SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION?: boolean | null
SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD?: boolean | null
SESSIONS_INACTIVITY_TIMEOUT?: number | null
SESSIONS_SINGLE_PER_USER?: boolean | null
SESSIONS_TAGS?: string | null