Skip to content

[PM-37877] feat: Implement SDK KM state bridge - #2940

Open
matt-livefront wants to merge 1 commit into
mainfrom
matt/PM-37877-km-state-bridge
Open

[PM-37877] feat: Implement SDK KM state bridge#2940
matt-livefront wants to merge 1 commit into
mainfrom
matt/PM-37877-km-state-bridge

Conversation

@matt-livefront

@matt-livefront matt-livefront commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

🎟️ Tracking

PM-37877

📔 Objective

Implements the SDK's StateBridgeForeignImpl interface on iOS and wires it to real mobile state, so the SDK can read/write the user key, PIN envelopes, encrypted PIN, V2 upgrade token, account cryptographic state, and master password unlock data without mobile passing it explicitly on every call.

  • Adds SdkStateBridge, a per-user type conforming to StateBridgeForeignImpl, registered via client.kmStateBridge().registerBridgeImpl(bridgeImpl:) in DefaultClientService.configureNewClient(_:for:) for every user-scoped Client (covers the main app + AutoFill/Action/Share extensions + watchOS, which all share this one path).
  • Adds a kmStateBridge() passthrough to BitwardenSdkClient/Client, matching the existing auth()/crypto()/platform() pattern.
  • Adds a new SdkStateBridgeStateService protocol (mirroring AutofillStateService/ServerCommunicationConfigStateService) that narrows SdkStateBridge's dependency down from the full StateService to just what it needs: accountCryptographicState, v2UpgradeToken, encryptedPin, persistentPinEnvelope/ephemeralPinEnvelope (the latter backed by the existing in-memory accountVolatileData slot), setAccountMasterPasswordUnlock/getAccountMasterPasswordUnlock, and clearAccountMasterPasswordUnlockData.
  • Adds v2UpgradeToken(userId:)/setV2UpgradeToken(_:userId:) storage to AppSettingsStore.
  • The raw userKey slot is in-memory only on the bridge instance and is never persisted (Keychain-only guardrail for unwrapped key material).

@matt-livefront
matt-livefront requested a review from quexten August 6, 2026 20:51
@matt-livefront matt-livefront added the ai-review Request a Claude code review label Aug 6, 2026
@matt-livefront
matt-livefront requested a review from a team as a code owner August 6, 2026 20:51
@github-actions github-actions Bot added the app:password-manager Bitwarden Password Manager app context label Aug 6, 2026
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 39.58%. Comparing base (dbbf6f2) to head (d8ac12b).

❗ There is a different number of reports uploaded between BASE (dbbf6f2) and HEAD (d8ac12b). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (dbbf6f2) HEAD (d8ac12b)
2 1
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2940       +/-   ##
===========================================
- Coverage   79.46%   39.58%   -39.88%     
===========================================
  Files        1172      363      -809     
  Lines       75057    17106    -57951     
===========================================
- Hits        59643     6772    -52871     
+ Misses      15414    10334     -5080     

☔ 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.


// MARK: SdkStateBridgeStateService

extension DefaultStateService: SdkStateBridgeStateService {

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.

Disclaimer: I don't know the standards for swift. Question (non-blocking): Is there a reason we have another layer of indirection here rather than making the SdkStateBridge impl directly perform these?

func clearAccountMasterPasswordUnlockData(userId: String) async {
do {
try updateAccountProfile(userId: userId) { profile in
profile.userDecryptionOptions?.masterPasswordUnlock = nil

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.

Non-blocking: User decryption options should really be separate from synced unlock options. At least, they are on clients.

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:password-manager Bitwarden Password Manager app context t:feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants