Skip to content

feat(tests): add key rotation and sync tests - #1459

Draft
quexten wants to merge 2 commits into
km/integration-model-serverfrom
km-rotation-and-sync-integration-test
Draft

feat(tests): add key rotation and sync tests#1459
quexten wants to merge 2 commits into
km/integration-model-serverfrom
km-rotation-and-sync-integration-test

Conversation

@quexten

@quexten quexten commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Adds integration tests for key rotation and sync.

Comment on lines +1 to +6
import {
SecureNoteType,
isDecryptError,
type CipherViewType,
type PasswordManagerClient,
} from "@bitwarden/sdk-internal";
import type { ClientEmulator } from "../../client-emulator/client-emulator";
import { testHarness, type TestHarness } from "../../test-harness";
import { MASTER_PASSWORD_ACCOUNT } from "../../vectors/accounts";
import { rejection, TEST_EMAIL, TEST_PASSWORD } from "../utils";
});
}

/** An item to carry across the rotation, which re-encrypts the vault under the new key. */

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will be replaced by vectors

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

🔍 SDK Breaking Change Detection

SDK Version: km-rotation-and-sync-integration-test (7e69d33)

⚠️ If breaking changes are detected, a corresponding pull request addressing them must be ready for merge in the affected client repository.

Client Status Details
typescript ✅ No breaking changes detected Compilation passed with new SDK version - View Details
android ✅ No breaking changes detected Compilation passed with new SDK version - View Details

Breaking change detection uses the build of the SDK from this branch, including any incompatibities pre-existing on or merged into this branch. Check the workflow logs to confirm.
Results update as workflows complete.

@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.23%. Comparing base (a64a237) to head (5405ca0).

Additional details and impacted files
@@                     Coverage Diff                      @@
##           km/integration-model-server    #1459   +/-   ##
============================================================
  Coverage                        86.23%   86.23%           
============================================================
  Files                              555      555           
  Lines                            80085    80085           
============================================================
  Hits                             69060    69060           
  Misses                           11025    11025           

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@quexten
quexten force-pushed the km-rotation-and-sync-integration-test branch from 7e69d33 to 6dda325 Compare September 11, 2026 11:48
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

This PR is test infrastructure only — no production Rust or binding code changes. It moves the client emulator's sync() onto a real GET /sync fetch, adds userDecryption and profile.accountKeys to the emulated sync response, models the three key-management rotation endpoints on the API server, and adds rotation and sync-downgrade integration tests. Wire shapes were checked against the SDK's own models (CryptoSyncData, MasterPasswordUnlockData, V2UpgradeToken, WrappedAccountCryptographicState) and line up, including the snake_case upgrade-token fields. Two unused imports in rotate-user-keys.test.ts are already flagged in open bot threads and will need clearing for lint.

Code Review Details
  • ♻️ : Rotation endpoint writes ciphers and folders without the ownership check every other write in the file applies, and mutates account keys before validating the referenced items
    • crates/bitwarden-wasm-internal/integration-tests/server-emulator/api-server.ts:238

Comment on lines +238 to +242
for (const cipher of posted.accountData.ciphers ?? []) {
const stored = this.db.ciphers.get(cipher.id);
if (stored === undefined) {
return error(HTTP_NOT_FOUND, `no cipher ${cipher.id} to re-encrypt`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ DEBT: The rotation's cipher and folder writes skip the ownership check every other write in this file applies.

Details and fix

rotateUserKeys resolves items with this.db.ciphers.get(...) and this.db.folders.get(...), while updateCipher goes through reachableCipher and updateFolder compares stored.userId !== user.userId. So a rotation payload that carries an organization cipher — which crates/bitwarden-user-crypto-management/src/key_rotation/data.rs documents must never happen ("Ciphers must be filtered to just contain the user's ciphers, not organization ciphers") — is accepted here and rewrites the org-owned entity under the new user key. The real server refuses that, so a regression in the SDK's filter would still pass this suite.

Suggested fix: resolve each posted cipher with this.reachableCipher(user, cipher.id) and reject one whose userId !== user.userId; apply the same userId check to folders.

While in there: the key, unlock and upgrade-token writes above happen before these lookups, so a 404 on a posted item leaves the account rotated with a partially re-encrypted vault. Validating every referenced item first keeps a rejected rotation from mutating anything.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant