Skip to content

[PM-46627] fix: Don't force Key Connector users promoted to admin to set a master password - #7594

Open
acul021 wants to merge 1 commit into
bitwarden:mainfrom
acul021:fix/key-connector-admin-master-password
Open

acul021 wants to merge 1 commit into
bitwarden:mainfrom
acul021:fix/key-connector-admin-master-password

Conversation

@acul021

@acul021 acul021 commented Nov 9, 2026

Copy link
Copy Markdown

🎟️ Tracking

Reported against a Vaultwarden build with Key Connector support: acul021/vaultwarden#1

Nothing in the client logic is Vaultwarden-specific. A Bitwarden server should hit the same path when a Key Connector user is promoted to owner or admin after migration. I have not reproduced it against a Bitwarden server.

📔 Objective

A Key Connector user who is promoted to owner or admin after migrating to Key Connector cannot log in on Android anymore. The web vault and iOS handle the same account fine.

Steps to reproduce

  1. Set up an organization with SSO and Key Connector.
  2. Log in as a regular member. The account is migrated to Key Connector and has no master password.
  3. Promote the member to admin or owner.
  4. Log in again on Android, or let the app sync.

Expected: The vault unlocks through Key Connector, as it does on web and iOS.
Actual: The app goes to the set password screen. The vault is still locked and the user has no master password, so they can't continue.

Cause

Bitwarden requires TDE users with the "manage account recovery" permission (owners, admins, custom roles with that permission) to set a master password. Android applied this rule to Key Connector users as well, in UserStateJsonExtensions.kt:

  • toUserState computed needsMasterPassword = true for a user without a master password when trustedDevice != null || keyConnectorOptions != null and the user had the permission. RootNavViewModel then routes to RootNavState.SetPassword.
  • getForcePasswordResetReason set TDE_USER_WITHOUT_PASSWORD_HAS_PASSWORD_RESET_PERMISSION on sync for any user without a master password who had the permission, without checking for TDE. The stored reason survives later syncs through previousForcePasswordResetReason.

The other clients only apply this rule to TDE:

  • Web, libs/common/src/platform/sync/default-sync.service.ts: checks userDecryptionOptions.trustedDeviceOption !== undefined.
  • Web, libs/auth/src/common/login-strategies/sso-login.strategy.ts: reads trustedDeviceOption?.hasManageResetPasswordPermission.
  • iOS, SyncService.checkTdeUserNeedsToSetPassword: requires trustedDeviceOption != nil.
  • Android's own login path (GetTokenResponseExtensions.toForcePasswordResetReason) already scopes this to trustedDeviceUserDecryptionOptions. Only the sync and user state paths were missing the check.

Changes

  • needsMasterPassword: a TDE user needs a password only with the reset password permission, a Key Connector user never does, and any other user without a password still does.
  • getForcePasswordResetReason: only sets the TDE reason when trustedDeviceUserDecryptionOptions is present. A previously stored TDE reason on a non-TDE account is cleared on sync, so devices that already ran into this recover without logging out.
  • The Key Connector migration exclusion for owners and admins (removePassword, shouldShowRemovePassword) is unchanged. It matches web.

Tests

New cases in UserStateJsonExtensionsTest:

  • Key Connector user with admin role: needsMasterPassword is false.
  • Key Connector user promoted to admin, then sync: no force password reset reason.
  • Key Connector user with a stale TDE reason, then sync: reason is cleared.

Existing TDE tests are unchanged and pass.

📸 Screenshots

No UI changes.

@acul021
acul021 requested review from a team and david-livefront as code owners November 9, 2026 14:11
Copilot AI balanced review requested due to automatic review settings November 9, 2026 14:11
@CLAassistant

CLAassistant commented Nov 9, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@bitwarden-bot

Copy link
Copy Markdown
Collaborator

Thank you for your contribution! We've added this to our internal tracking system for review.
ID: PM-46627
Link: https://bitwarden.atlassian.net/browse/PM-46627

Details on our contribution process can be found here: https://contributing.bitwarden.com/contributing/pull-requests/community-pr-process.

@bitwarden-bot bitwarden-bot changed the title fix: Don't force Key Connector users promoted to admin to set a master password [PM-46627] fix: Don't force Key Connector users promoted to admin to set a master password Nov 9, 2026
// Clear a reason that was previously stored for a non-TDE user.
it == ForcePasswordResetReason
.TDE_USER_WITHOUT_PASSWORD_HAS_PASSWORD_RESET_PERMISSION &&
!isTdeUser

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we need this?

I would expect users to either have added the password or logged out by the time this code gets to them.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This only saves affected users one step. If a Key Connector user was promoted to admin and synced on an older build, the TDE reason is already stored on their device, and previousForcePasswordResetReason keeps it through every sync. After updating, they'd unlock through Key Connector and then land on ResetPassword, so they'd have to log out and back in once. The cleanup clears that reason on the next sync.
The fix itself doesn't depend on it. New logins and promotions on the new version never store the reason. Happy to drop it if you'd rather keep the change minimal.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could we drop it, I prefer to keep this code as simple as possible and there is a work-around for that edge-case scenario. Plus, once this fix merges, the issue should never happen again.

…r password

A Key Connector user who is promoted to owner or admin after migrating
gets stuck on the set password screen. The vault is still locked at
that point and the user has no master password, so there is no way
forward.

The admin rule comes from Trusted Device Encryption. Android applied
it to Key Connector users too, in two places:

- toUserState set needsMasterPassword for Key Connector users with the
  reset password permission.
- getForcePasswordResetReason set the TDE reset reason for any user
  without a master password, without checking for TDE.

Web (default-sync.service.ts, sso-login.strategy.ts) and iOS
(SyncService.checkTdeUserNeedsToSetPassword) only apply this rule when
trustedDeviceOption is present. Android now does the same. A stored
TDE reason on a non-TDE account is cleared on the next sync, so
devices that already hit the bug recover.
@acul021
acul021 force-pushed the fix/key-connector-admin-master-password branch from b28e9f0 to a810bb3 Compare November 10, 2026 15:54

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants