[PR #6433] Make JWT token refresh optional #3743

Open
opened 2026-02-05 05:42:47 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/dani-garcia/vaultwarden/pull/6433
Author: @Momi-V
Created: 11/3/2025
Status: 🔄 Open

Base: mainHead: auth-renew


📝 Commits (10+)

  • f902632 Add option to disable refresh token renewal
  • f28316b Add logic to make token renew optional
  • c359c8b Add Clone trait to TokenWrapper enum
  • 85cbfba Reuse original claims struct for refresh token renewal
  • f77109b pass original refresh_claim into renewal function
  • 16df972 Pass correct type
  • eea7d1e Add optional parameter existing_refresh_claims to AuthTokens
  • 8c83948 Add optional parameter existing_refresh_claims to AuthTokens
  • 8b82ead Add Clone trait to RefreshJwtClaims struct
  • 0acc952 Clone refresh_claims.sub

📊 Changes

4 files changed (+20 additions, -9 deletions)

View changed files

📝 src/api/identity.rs (+1 -1)
📝 src/auth.rs (+13 -6)
📝 src/config.rs (+4 -0)
📝 src/sso.rs (+2 -2)

📄 Description

This implements a config option disable_refresh_token_renewal, that doesn't do refresh token renewal unless a full auth is performed.

Goal:
Only renew the JWT token that allows PIN unlock, bypassing 2FA, etc. if a "full authentication" is performed. This makes things like "require 2FA once every 30/90 days" possible

Rationale:
Currently it's only possible to require periodic reauthentication by setting clients to log-out instead of lock. This is inconvenient since it breaks PIN, offline functionality and requires full reauthentication for every unlock. The current lock behavior on the other hand only requires reauth if a client hasn't connected in 30/90 days, since the token is renewed even on a reduced login that used that same token. This means it effectively never expires, if the client just uses it's existing token more than once a month.

Logic:
If the new option is false the old logic is used (always renew the token). If a normal Password/SSO login is performed the old logic is used.
If the option is true the JWT isn't renewed in the _refresh_login code path, leaving it to expire and force a full auth after 30/90 days

Code:
Having refresh_claims.sub.clone() and Some(&refresh_claims) in the same call isn't amazing, but seems like the simplest way to implement this logic without a refactor to overload AuthToken::new into 2 separate, yet almost identical functions.

Progress:
Compiled and running, but not yet tested to actually behave as expected (currently ongoing).

Feedback welcome


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/dani-garcia/vaultwarden/pull/6433 **Author:** [@Momi-V](https://github.com/Momi-V) **Created:** 11/3/2025 **Status:** 🔄 Open **Base:** `main` ← **Head:** `auth-renew` --- ### 📝 Commits (10+) - [`f902632`](https://github.com/dani-garcia/vaultwarden/commit/f902632ba5f5c14a908fac939519df2b4f6c1119) Add option to disable refresh token renewal - [`f28316b`](https://github.com/dani-garcia/vaultwarden/commit/f28316b4ed4c569aa4c8bd50709e997c2a7b4b3d) Add logic to make token renew optional - [`c359c8b`](https://github.com/dani-garcia/vaultwarden/commit/c359c8b6aea5482cb4437c1ad0643f0eb1fde07c) Add Clone trait to TokenWrapper enum - [`85cbfba`](https://github.com/dani-garcia/vaultwarden/commit/85cbfba318151845cbaf105af4985d0331db0687) Reuse original claims struct for refresh token renewal - [`f77109b`](https://github.com/dani-garcia/vaultwarden/commit/f77109b8e30f381a8ca6de9060354f9db9f6f006) pass original refresh_claim into renewal function - [`16df972`](https://github.com/dani-garcia/vaultwarden/commit/16df972fb6cbef1e77515e87643581f564458657) Pass correct type - [`eea7d1e`](https://github.com/dani-garcia/vaultwarden/commit/eea7d1e7c08784b1d160fd0f38fcf1000bcc5b48) Add optional parameter existing_refresh_claims to AuthTokens - [`8c83948`](https://github.com/dani-garcia/vaultwarden/commit/8c8394812e894185c70cf34e10f0e6dc5579dab0) Add optional parameter existing_refresh_claims to AuthTokens - [`8b82ead`](https://github.com/dani-garcia/vaultwarden/commit/8b82ead7ba469dd229fae07f4a6160df5b9b1193) Add Clone trait to RefreshJwtClaims struct - [`0acc952`](https://github.com/dani-garcia/vaultwarden/commit/0acc9522c77089c6b51b5580e2f2b6657313b425) Clone refresh_claims.sub ### 📊 Changes **4 files changed** (+20 additions, -9 deletions) <details> <summary>View changed files</summary> 📝 `src/api/identity.rs` (+1 -1) 📝 `src/auth.rs` (+13 -6) 📝 `src/config.rs` (+4 -0) 📝 `src/sso.rs` (+2 -2) </details> ### 📄 Description This implements a config option `disable_refresh_token_renewal`, that doesn't do refresh token renewal unless a full auth is performed. **Goal:** Only renew the JWT token that allows PIN unlock, bypassing 2FA, etc. if a "full authentication" is performed. This makes things like "require 2FA once every 30/90 days" possible **Rationale:** Currently it's only possible to require periodic reauthentication by setting clients to log-out instead of lock. This is inconvenient since it breaks PIN, offline functionality and requires full reauthentication for _every_ unlock. The current lock behavior on the other hand _only_ requires reauth if a client hasn't connected in 30/90 days, since the token is renewed even on a reduced login that used that same token. This means it effectively never expires, if the client just uses it's existing token more than once a month. **Logic:** If the new option is `false` the old logic is used (always renew the token). If a normal Password/SSO login is performed the old logic is used. If the option is `true` the JWT isn't renewed in the `_refresh_login` code path, leaving it to expire and force a full auth after 30/90 days **Code:** Having `refresh_claims.sub.clone()` and `Some(&refresh_claims)` in the same call isn't amazing, but seems like the simplest way to implement this logic without a refactor to overload `AuthToken::new` into 2 separate, yet almost identical functions. **Progress:** Compiled and running, but not yet tested to actually behave as expected (currently ongoing). Feedback welcome --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
OVERLORD added the pull-request label 2026-02-05 05:42:47 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/vaultwarden#3743