Skip to content

feat(db): delete passkey wraps when a password reset rotates kB - #21128

Open
vpomerleau wants to merge 2 commits into
mainfrom
FXA-14421
Open

feat(db): delete passkey wraps when a password reset rotates kB#21128
vpomerleau wants to merge 2 commits into
mainfrom
FXA-14421

Conversation

@vpomerleau

@vpomerleau vpomerleau commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Because

  • A passkey wrap seals kB to the generation recorded in keysChangedAt. A password reset without a recovery key advances it, so every wrap on the account is permanently undecryptable.
  • Left in place, the next Sync sign-in asks for a password only after a failed unwrap rather than up front.

This pull request

  • Adds resetAccount_20 (patch-197-198), deleting passkeyWraps inside the existing IF keysHaveChangedArg = 1 block alongside recoveryKeys.
  • Leaves the passkeys rows in place, so the credential stays usable for re-enrolment.
  • Points Proc.ResetAccount at the new procedure.
  • Covers both branches of the guard in packages/fxa-auth-server/test/remote/db.in.spec.ts.
  • Adds passkeys and passkeyWraps fixtures to the fxa-shared auth test schema and moves the fixture procedure to resetAccount_20.
  • Corrects the DB migration command in CLAUDE.md. Unrelated to the ticket — the documented nx target does not exist.

Issue that this pull request solves

Closes: FXA-14421

Checklist

Put an x in the boxes that apply

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.
  • I have added necessary documentation (if appropriate).
  • I have verified that my changes render correctly in RTL (if appropriate).
  • I have manually reviewed all AI generated code.

How to review (Optional)

  • Key files/areas to focus on: patch-197-198.sql — the procedure is resetAccount_19 verbatim plus one DELETE, so the diff against patch-159-160.sql is the useful comparison.
  • Suggested review order: the patch, then base-auth.ts, then the tests.
  • Risky or complex parts: repointing Proc.ResetAccount moves every db.resetAccount caller to the new procedure at once.

Screenshots (Optional)

Please attach the screenshots of the changes made in case of change in user interface.

Other information (Optional)

  • No security event is emitted. account.passkey.wrap_invalidated stays registered but unused: account.reset is the parent event, and other rows a reset drops don't raise their own.
  • The Recorded Future force-reset (scripts/recorded-future/check-and-reset.ts) was checked per the ticket comment and deliberately left unchanged. It randomizes wrapWrapKb but leaves keysChangedAt untouched, so it does not rotate kB — rotation happens at the user's follow-up reset, which this procedure covers.

Because:

* A wrap seals kB to the generation in `keysChangedAt`, so a reset that
  rotates kB leaves rows that can never open again.
* Asking for the password up front beats asking after a failed unwrap.

This commit:

* Adds `resetAccount_20`, deleting `passkeyWraps` alongside `recoveryKeys`
  in the existing `keysHaveChangedArg` block. The passkeys survive, so the
  credentials stay usable for re-enrolment.
* Covers both branches of that guard in `test/remote/db.in.spec.ts`.
* Adds `passkeys` and `passkeyWraps` fixtures to fxa-shared and moves the
  fixture proc to `resetAccount_20`.

Closes FXA-14421
Because:

* `nx run db-migrations:migrate` does not exist; the package defines only
  lint, test-unit and test-integration.
* The old text also omitted bumping `target-patch.json`, without which the
  patcher is a no-op.

This commit:

* Points at the patcher, notes `yarn start` already runs it, and refers to
  the databases README rather than restating it.
@vpomerleau
vpomerleau requested review from nshirley and a balanced review from Copilot September 1, 2026 18:16

Copilot AI left a comment

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.

Pull request overview

Deletes obsolete passkey wraps whenever password reset rotates kB, while preserving passkey credentials for re-enrolment.

Changes:

  • Adds and adopts resetAccount_20.
  • Adds fixtures and integration coverage for both key-change branches.
  • Updates migration instructions.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/fxa-shared/test/db/models/auth/sp_resetAccount.sql Updates the fixture procedure and wrap deletion.
packages/fxa-shared/test/db/models/auth/passkeys.sql Adds the passkeys test table.
packages/fxa-shared/test/db/models/auth/passkey-wraps.sql Adds the wraps test table.
packages/fxa-shared/test/db/models/auth/helpers.ts Loads the new fixtures.
packages/fxa-shared/db/models/auth/base-auth.ts Selects resetAccount_20.
packages/fxa-auth-server/test/remote/db.in.spec.ts Tests wrap deletion and preservation.
packages/db-migrations/databases/fxa/target-patch.json Advances schema level to 198.
packages/db-migrations/databases/fxa/patches/patch-198-197.sql Adds the commented rollback.
packages/db-migrations/databases/fxa/patches/patch-197-198.sql Creates the updated reset procedure.
CLAUDE.md Corrects migration instructions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@vpomerleau
vpomerleau marked this pull request as ready for review September 1, 2026 18:20
@vpomerleau
vpomerleau requested a review from a team as a code owner September 1, 2026 18:20
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.

3 participants