Skip to content

feat(keyring-controller): persist vault when keyring state changes during unlock#8415

Merged
danroc merged 7 commits intomainfrom
dr/keyring-migrations
Apr 10, 2026
Merged

feat(keyring-controller): persist vault when keyring state changes during unlock#8415
danroc merged 7 commits intomainfrom
dr/keyring-migrations

Conversation

@danroc
Copy link
Copy Markdown
Contributor

@danroc danroc commented Apr 9, 2026

Explanation

Currently, if a keyring runs a migration inside deserialize() during unlock, the updated in-memory state is never written back to the vault. On the next unlock the migration silently re-runs against the same stale data.

This PR fixes that by comparing each keyring's re-serialized state against the original data after #restoreKeyring. If any keyring's state differs — whether due to a migration or missing metadata — hasChanged is propagated up through #restoreSerializedKeyrings and #unlockKeyrings, and the existing vault upgrade path in submitPassword/submitEncryptionKey re-persists the vault.

As part of this change, a hasStateChanged helper function is introduced and reused in #persistOrRollback, removing the dependency on lodash isEqual for that comparison.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Touches the unlock/vault-update path to trigger re-encryption/persistence based on detected keyring state changes, which could affect login performance and vault write frequency if the change detection is wrong.

Overview
During submitPassword/submitEncryptionKey, the controller now tracks whether any keyring’s serialized data changes during restore (including missing metadata) and, if so, re-runs the existing vault update flow to persist the upgraded state.

Change detection is implemented in #restoreKeyring by comparing pre- and post-deserialization serialized payloads and is propagated via #restoreSerializedKeyrings/#unlockKeyrings as hasChanged; #persistOrRollback also switches from lodash isEqual to a JSON-string comparison for session-state diffs. Adds a regression test for an in-place migrating keyring and updates the changelog.

Reviewed by Cursor Bugbot for commit 6e75026. Bugbot is set up for automated code reviews on this repo. Configure here.

…ring unlock

Introduces `hasStateChanged` helper and uses it to detect when a
keyring's serialized state differs from what was stored in the vault.
If any keyring changed during deserialization (e.g. ran a migration,
or was missing metadata), the vault is re-persisted via the existing
upgrade path in `submitPassword`/`submitEncryptionKey`.

Also removes the now-redundant `isEqual` import from lodash.
@danroc danroc requested review from a team as code owners April 9, 2026 13:06
danroc added 5 commits April 9, 2026 15:06
…low serialize()

Eagerly stringify session state before the operation so that subsequent
mutations to keyring-internal arrays (e.g. MockShallowKeyring) cannot
retroactively change the snapshot used for comparison. Also removes the
now-unnecessary `hasStateChanged` helper.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 010a2d8. Configure here.

Comment thread packages/keyring-controller/src/KeyringController.ts Outdated
Comment thread packages/keyring-controller/src/KeyringController.test.ts
Comment thread tsconfig.packages.json Outdated
Copy link
Copy Markdown
Contributor

@ccharly ccharly left a comment

Choose a reason for hiding this comment

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

LGTM!

@danroc danroc added this pull request to the merge queue Apr 10, 2026
Merged via the queue into main with commit 93b8bc4 Apr 10, 2026
341 checks passed
@danroc danroc deleted the dr/keyring-migrations branch April 10, 2026 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants