Skip to content

[PM-42103] feat: Add opt-in toggle for keeping vault unlocked until timeout - #3004

Draft
fedemkr wants to merge 1 commit into
PM-23301/share-user-session-key-extensionsfrom
PM-42103/add-opt-in-user-session-key
Draft

[PM-42103] feat: Add opt-in toggle for keeping vault unlocked until timeout#3004
fedemkr wants to merge 1 commit into
PM-23301/share-user-session-key-extensionsfrom
PM-42103/add-opt-in-user-session-key

Conversation

@fedemkr

@fedemkr fedemkr commented Aug 28, 2026

Copy link
Copy Markdown
Member

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-42103

📔 Objective

Adds a user-facing, opt-in toggle ("Keep vault unlocked until timeout") in Account Security settings that lets a user choose to share their session key across the app and its extensions (e.g. autofill), so the vault stays unlocked until session timeout even after the app is closed.

This is stacked on top of #2661 (PM-23301, feature-flagged session key sharing), and adds the opt-in surface on top of that mechanism:

  • AuthRepository: isUserSessionKeySharingEnabled(userId:) / setUserSessionKeySharingEnabled(_:userId:), which immediately captures or purges the .userSessionKey Keychain item to match the preference.
  • KeychainRepository: new .userSessionKeySharingEnabled(userId:) key.
  • AccountSecurityView/Processor/State/Effect: new toggle, gated behind the existing session-key-sharing feature flag, with a "Learn more" link (placeholder help URL, see inline TODO).

📸 Screenshots

@fedemkr fedemkr added the ai-review Request a Claude code review label Aug 28, 2026
@github-actions github-actions Bot added app:password-manager Bitwarden Password Manager app context app:authenticator Bitwarden Authenticator app context t:feature labels Aug 28, 2026
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

Reviewed the opt-in "Keep vault unlocked until timeout" toggle stacked on the feature-flagged session key sharing work: the new .userSessionKeySharingEnabled keychain item, the AuthRepository get/set pair with the extracted captureUserSessionKeyIfAllowed gate, and the flag-gated Account Security toggle. The capture gate correctly ANDs the server flag, the user preference, and the timeout value, disabling purges .userSessionKey, and the added unit tests cover the on/off/error paths plus the new keychain item's protection class and access-control flags. Two findings below relate to how the persisted preference lines up with the vault timeout value and with logout; neither blocks merge.

Code Review Details
  • ⚠️ : Toggle is offered for timeout values (.immediately, .onAppRestart, .never) where the session key is never captured, so the setting persists as on with no effect and no feedback
    • BitwardenShared/UI/Platform/Settings/Settings/AccountSecurity/AccountSecurityView.swift:199
  • ❓ : The new opt-in preference is not in KeychainRepository.deleteItems(for:), so it outlives logout and reinstall and silently re-enables sharing at the next login
    • BitwardenShared/Core/Auth/Repositories/AuthRepository.swift:1179
  • ❓ : The simulator-only BGTaskScheduler opt-out is unrelated to PM-42103 and has no ticket for revisiting; worth confirming it is meant to ship with this PR
    • Bitwarden/Application/AppDelegate.swift:44

PR Metadata Assessment

  • QUESTION: The Screenshots section is still an empty placeholder for a change that adds a new settings toggle.

)
.disabled(store.state.isSessionTimeoutActionDisabled)
}
if store.state.isSessionKeySharingFeatureEnabled {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ IMPORTANT: Toggle is offered for timeout values that can never share the session key.

Details and fix

Visibility is gated only on isSessionKeySharingFeatureEnabled, but the capture path is additionally gated on the timeout: captureUserSessionKeyIfAllowed returns early unless timeoutValue.allowsUserSessionKeySharing, which is false for .immediately, .onAppRestart, and .never.

So a user on "Immediately" or "On app restart" can switch this on, setUserSessionKeySharingEnabled persists "true", no key is ever captured, and the UI shows an enabled setting with no effect and no feedback. The same mismatch happens in reverse: changing the timeout to one of those values deletes .userSessionKey (AuthRepository.setVaultTimeout) while the toggle stays on.

Options:

  • Gate the section on store.state.sessionTimeoutValue.allowsUserSessionKeySharing too (hide, or .disabled(...) with explanatory footer text), and/or
  • Re-run captureUserSessionKeyIfAllowed from setVaultTimeout when the preference is on so switching back to a timed value takes effect immediately rather than at the next unlock.

func setUserSessionKeySharingEnabled(_ isEnabled: Bool, userId: String?) async throws {
let id = try await userIdOrActive(userId)
try await keychainService.setUserAuthKey(
for: .userSessionKeySharingEnabled(userId: id),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QUESTION: Should .userSessionKeySharingEnabled be cleared on logout?

Details

KeychainRepository.deleteItems(for:) removes .userSessionKey but does not include this new preference item, and that list documents its deliberate exclusions (e.g. vaultTimeout, deviceKey).

As written, the opt-in outlives logout — and, since keychain items survive app deletion, a reinstall — so the next login for that userId re-captures the session key at unlock without the user opting in again. If that persistence is intended (mirroring vaultTimeout), adding the item to that list's comments would make it explicit.

@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 39.68%. Comparing base (51e0682) to head (cb69c14).

Additional details and impacted files
@@                             Coverage Diff                             @@
##           PM-23301/share-user-session-key-extensions    #3004   +/-   ##
===========================================================================
  Coverage                                       39.68%   39.68%           
===========================================================================
  Files                                             362      362           
  Lines                                           16987    16987           
===========================================================================
  Hits                                             6741     6741           
  Misses                                          10246    10246           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Request a Claude code review app:authenticator Bitwarden Authenticator app context app:password-manager Bitwarden Password Manager app context t:feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant