Skip to content

task(db): Add passkeyWraps table - #20958

Open
nshirley wants to merge 1 commit into
mainfrom
FXA-13138
Open

task(db): Add passkeyWraps table#20958
nshirley wants to merge 1 commit into
mainfrom
FXA-13138

Conversation

@nshirley

@nshirley nshirley commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Because

  • Passkey-based sync sign-in needs somewhere to persist the PRF-wrapped recovery
    keypair and the HPKE-sealed kB, one envelope per passkey. This is the storage
    model from the technical spec §2.2.5.
  • The rest of the P2 key-wrapping work (data model, endpoints, HPKE utilities)
    builds on this table, so the schema needs to land first.

This pull request

  • Adds packages/db-migrations/databases/fxa/patches/patch-194-195.sql, creating
    passkeyWraps keyed on (uid, credentialId). Every payload column is
    fixed-length and sized from the v1 ciphersuite
    (DHKEM(P-521, HKDF-SHA512) / HKDF-SHA512 / AES-256-GCM).
  • Uses a composite ON DELETE CASCADE foreign key to passkeys(uid, credentialId),
    so deleting a passkey drops its envelope. Account deletion needs no procedure
    change: deleteAccount_24 already deletes from passkeys before accounts, and
    wraps cascade with that delete.
  • Adds the patch-195-194.sql rollback and bumps target-patch.json to 195.

Issue that this pull request solves

Closes: FXA-13138

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-194-195.sql — specifically that uid,
    credentialId, and the timestamp types match passkeys exactly, since the
    composite FK cannot be created otherwise.
  • Suggested review order: forward patch, then the rollback, then the target-patch bump.
  • Risky or complex parts: the cascade behaviour is the load-bearing part. It is what
    lets this land without touching deleteAccount_24.

Screenshots (Optional)

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

Other information (Optional)

Verified against a local DB. packages/db-migrations has no automated schema
assertions, so these checks are manual:

  • Forward migration applies at level 194 and lands the schema above; reverse drops the
    table and returns the level to 194; forward then re-applies cleanly.
  • Deleting one of two passkeys removed exactly that passkey's wrap, leaving the sibling
    wrap intact.
  • CALL deleteAccount_24(uid, reason) succeeded with a wrap present — account,
    passkeys, and wraps all removed, deletionReason recorded — with no change to the
    procedure.

Purely additive, and no application code reads the table yet, so this must deploy ahead
of the data model that consumes it.

@nshirley
nshirley marked this pull request as ready for review August 3, 2026 17:36
@nshirley
nshirley requested a review from a team as a code owner August 3, 2026 17:36
Copilot AI review requested due to automatic review settings August 3, 2026 17:36

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

Adds a new FxA DB migration level (195) introducing a passkeys_wraps table intended to store per-passkey key-wrapping “envelopes” (PRF-wrapped recovery keypair material and HPKE-sealed kB) and wiring it to passkeys via a composite ON DELETE CASCADE FK so passkey deletion also deletes its wrap.

Changes:

  • Add forward migration patch-194-195.sql to create passkeys_wraps with (uid, credentialId) primary key and a composite cascading FK to passkeys(uid, credentialId).
  • Add rollback migration patch-195-194.sql (commented-out rollback steps, consistent with existing rollback patch style).
  • Bump DB schema target level from 194 → 195.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/db-migrations/databases/fxa/patches/patch-194-195.sql Creates the new wraps table and advances schema patch level to 195.
packages/db-migrations/databases/fxa/patches/patch-195-194.sql Provides the rollback patch steps (commented), returning schema patch level to 194.
packages/db-migrations/databases/fxa/target-patch.json Updates the target schema patch level to 195.

Comment thread packages/db-migrations/databases/fxa/patches/patch-194-195.sql Outdated
Comment thread packages/db-migrations/databases/fxa/patches/patch-195-194.sql Outdated
Comment on lines +12 to +16
pkR VARBINARY(512) NOT NULL, -- v1: 133B, uncompressed P-521 point
prfWrappedSkR VARBINARY(512) NOT NULL, -- v1: 257B, AES-256-GCM(pkcs8 skR) + tag
keyWrapIv BINARY(12) NOT NULL, -- AES-GCM nonce
hpkeEncapsulatedSecret VARBINARY(512) NOT NULL, -- v1: 133B, RFC 9180 Nenc for DHKEM(P-521)
hpkeSealedKb VARBINARY(512) NOT NULL, -- v1: 48B, 32B kB + tag

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.

My thinking was that we give a little bit of wiggle room so we're less likely to hit issues where the write is rejected because the size changes, but I'm unsure if that's even possible for the size to change. If it's not, or it shouldn't change, than I can make it more strict

@dschom dschom Aug 4, 2026

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.

IUC, those sizes are fixed and based on the crypto libraries. If this is infact true, and we potentially have a bunch of records here, we should make them the exact size. Also use binary instead of varbinary. This is consistent with how columns that hold wrapped kbs work.

Because:

* Passkey-based sync sign-in needs somewhere to store the PRF-wrapped
  recovery keypair and the HPKE-sealed kB, one envelope per passkey.

This commit:

* Adds patch-194-195.sql creating passkeyWraps, keyed on
  (uid, credentialId) with an ON DELETE CASCADE FK to passkeys so wraps
  are removed with their passkey. deleteAccount_24 needs no change.
* Adds the patch-195-194.sql rollback and bumps target-patch to 195.
@nshirley nshirley changed the title task(db): Add passkeys_wraps table task(db): Add passkeyWraps table Aug 3, 2026
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