Skip to content

Feat/TO-540: Add passkey controller#8422

Merged
tanguyenvn merged 46 commits intomainfrom
feat/TO-540-passkey-controller
Apr 27, 2026
Merged

Feat/TO-540: Add passkey controller#8422
tanguyenvn merged 46 commits intomainfrom
feat/TO-540-passkey-controller

Conversation

@tanguyenvn
Copy link
Copy Markdown
Contributor

@tanguyenvn tanguyenvn commented Apr 10, 2026

Description

Introduces @metamask/passkey-controller, a BaseController-backed package that orchestrates WebAuthn passkey enrollment and authentication for vault key protection: generating ceremony options, verifying authenticator responses, HKDF-based key derivation (PRF vs userHandle), AES-256-GCM wrapping of the vault encryption key, renewal flows for password change, and state/ceremony management (including concurrent ceremonies and lifecycle clears).

Also wires the package into the monorepo (workspace/tsconfig, CODEOWNERS, teams.json, root README, lockfile).

Notes for reviewers (SimpleWebAuthn)

Extension vs Core split

  • The browser extension UI can depend on @simplewebauthn/browser for client-side helpers that run where navigator.credentials is available.
  • The extension background / service worker cannot take a normal dependency on @simplewebauthn/server: that package targets Node-oriented verification APIs and assumptions that do not fit the constrained extension background environment the same way.

To keep verification logic aligned with SimpleWebAuthn while staying dependency-appropriate in Core, this package inlines / ports the relevant server-side verification behavior (registration and authentication response verification, signature verification, CBOR/WebAuthn parsing helpers) into packages/passkey-controller/src/webauthn/ rather than adding @simplewebauthn/server as a runtime dependency. When reviewing, please treat those modules as parity-sensitive: changes should stay consistent with upstream SimpleWebAuthn semantics where we intentionally mirror them (see recent commits around verification parity).

Changelog

  • packages/passkey-controller/CHANGELOG.md — follow monorepo changelog rules; ensure yarn validate:changelog passes before merge.

Related issues

Fixes:

Testing

  • yarn workspace @metamask/passkey-controller run test
  • (Optional) yarn workspace @metamask/passkey-controller run build

Manual testing (consumers)

N/A for Core in isolation; extension integration should exercise registration, unlock, change-password / vault key renewal, wallet reset, and edge cases called out in the extension PR.


Note

High Risk
High risk because it introduces new authentication/cryptography flows (WebAuthn verification, HKDF/AES-GCM key wrapping) and new persisted state that will gate vault unlock and key rotation behavior.

Overview
Introduces a new @metamask/passkey-controller package implementing passkey-based vault key protection: option generation for registration/authentication ceremonies, verification of WebAuthn responses, HKDF-derived AES-256-GCM wrap/unwrap of the vault key, and a renewal flow for updating the protected vault key.

Adds supporting utilities for ceremony state management (TTL/capacity, concurrency handling), key-derivation (PRF vs userHandle), encoding/crypto helpers, and an error model (PasskeyControllerError with stable code/cause/context).

Wires the new package into the monorepo via README.md entries and CODEOWNERS ownership for the new controller and its release files, and includes initial docs/changelog plus comprehensive unit tests.

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

@tanguyenvn tanguyenvn changed the title Feat/to 540 passkey controller Feat/TO-540: Add passkey controller Apr 10, 2026
@tanguyenvn tanguyenvn self-assigned this Apr 10, 2026
Comment thread packages/passkey-controller/src/encoding.ts Outdated
Comment thread packages/passkey-controller/src/crypto.ts Outdated
Comment thread packages/passkey-controller/src/PasskeyController.ts Outdated
Comment thread packages/passkey-controller/src/PasskeyController.ts Outdated
Comment thread packages/passkey-controller/src/PasskeyController.ts Outdated
@tanguyenvn tanguyenvn marked this pull request as ready for review April 16, 2026 11:25
Comment thread packages/passkey-controller/src/PasskeyController.ts
Comment thread packages/passkey-controller/src/PasskeyController.ts Outdated
Comment thread packages/passkey-controller/src/webauthn/verify-signature.ts
Comment thread packages/passkey-controller/src/key-derivation.ts
Comment thread packages/passkey-controller/src/webauthn/verify-authentication-response.ts Outdated
Comment thread packages/passkey-controller/src/key-derivation.ts Outdated
@tanguyenvn
Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@tanguyenvn
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@github-actions
Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.1.0-preview-4c0846313
@metamask-previews/accounts-controller@37.2.0-preview-4c0846313
@metamask-previews/address-book-controller@7.1.1-preview-4c0846313
@metamask-previews/ai-controllers@0.6.3-preview-4c0846313
@metamask-previews/analytics-controller@1.0.1-preview-4c0846313
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-4c0846313
@metamask-previews/announcement-controller@8.1.0-preview-4c0846313
@metamask-previews/app-metadata-controller@2.0.1-preview-4c0846313
@metamask-previews/approval-controller@9.0.1-preview-4c0846313
@metamask-previews/assets-controller@6.0.0-preview-4c0846313
@metamask-previews/assets-controllers@104.2.0-preview-4c0846313
@metamask-previews/authenticated-user-storage@1.0.0-preview-4c0846313
@metamask-previews/base-controller@9.1.0-preview-4c0846313
@metamask-previews/base-data-service@0.1.1-preview-4c0846313
@metamask-previews/bridge-controller@70.1.1-preview-4c0846313
@metamask-previews/bridge-status-controller@70.0.5-preview-4c0846313
@metamask-previews/build-utils@3.0.4-preview-4c0846313
@metamask-previews/chain-agnostic-permission@1.5.0-preview-4c0846313
@metamask-previews/chomp-api-service@1.0.0-preview-4c0846313
@metamask-previews/claims-controller@0.5.0-preview-4c0846313
@metamask-previews/client-controller@1.0.1-preview-4c0846313
@metamask-previews/compliance-controller@2.0.0-preview-4c0846313
@metamask-previews/composable-controller@12.0.1-preview-4c0846313
@metamask-previews/config-registry-controller@0.2.0-preview-4c0846313
@metamask-previews/connectivity-controller@0.2.0-preview-4c0846313
@metamask-previews/controller-utils@11.20.0-preview-4c0846313
@metamask-previews/core-backend@6.2.1-preview-4c0846313
@metamask-previews/delegation-controller@3.0.0-preview-4c0846313
@metamask-previews/earn-controller@12.0.0-preview-4c0846313
@metamask-previews/eip-5792-middleware@3.0.3-preview-4c0846313
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-4c0846313
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-4c0846313
@metamask-previews/ens-controller@19.1.1-preview-4c0846313
@metamask-previews/eth-block-tracker@15.0.1-preview-4c0846313
@metamask-previews/eth-json-rpc-middleware@23.1.1-preview-4c0846313
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-4c0846313
@metamask-previews/foundryup@1.0.1-preview-4c0846313
@metamask-previews/gas-fee-controller@26.1.1-preview-4c0846313
@metamask-previews/gator-permissions-controller@4.0.0-preview-4c0846313
@metamask-previews/geolocation-controller@0.1.2-preview-4c0846313
@metamask-previews/json-rpc-engine@10.2.4-preview-4c0846313
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-4c0846313
@metamask-previews/keyring-controller@25.2.0-preview-4c0846313
@metamask-previews/logging-controller@8.0.1-preview-4c0846313
@metamask-previews/message-manager@14.1.1-preview-4c0846313
@metamask-previews/messenger@1.1.1-preview-4c0846313
@metamask-previews/messenger-cli@0.2.0-preview-4c0846313
@metamask-previews/money-account-balance-service@0.2.0-preview-4c0846313
@metamask-previews/money-account-controller@0.1.0-preview-4c0846313
@metamask-previews/money-account-upgrade-controller@1.0.0-preview-4c0846313
@metamask-previews/multichain-account-service@8.0.1-preview-4c0846313
@metamask-previews/multichain-api-middleware@2.0.0-preview-4c0846313
@metamask-previews/multichain-network-controller@3.0.6-preview-4c0846313
@metamask-previews/multichain-transactions-controller@7.0.4-preview-4c0846313
@metamask-previews/name-controller@9.1.1-preview-4c0846313
@metamask-previews/network-controller@30.0.1-preview-4c0846313
@metamask-previews/network-enablement-controller@5.0.2-preview-4c0846313
@metamask-previews/notification-services-controller@23.1.0-preview-4c0846313
@metamask-previews/passkey-controller@0.0.0-preview-4c0846313
@metamask-previews/permission-controller@12.3.0-preview-4c0846313
@metamask-previews/permission-log-controller@5.1.0-preview-4c0846313
@metamask-previews/perps-controller@3.2.0-preview-4c0846313
@metamask-previews/phishing-controller@17.1.1-preview-4c0846313
@metamask-previews/polling-controller@16.0.4-preview-4c0846313
@metamask-previews/preferences-controller@23.1.0-preview-4c0846313
@metamask-previews/profile-metrics-controller@3.1.3-preview-4c0846313
@metamask-previews/profile-sync-controller@28.0.2-preview-4c0846313
@metamask-previews/ramps-controller@13.2.0-preview-4c0846313
@metamask-previews/rate-limit-controller@7.0.1-preview-4c0846313
@metamask-previews/react-data-query@0.2.0-preview-4c0846313
@metamask-previews/remote-feature-flag-controller@4.2.0-preview-4c0846313
@metamask-previews/sample-controllers@4.0.4-preview-4c0846313
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-4c0846313
@metamask-previews/selected-network-controller@26.1.0-preview-4c0846313
@metamask-previews/shield-controller@5.1.1-preview-4c0846313
@metamask-previews/signature-controller@39.2.0-preview-4c0846313
@metamask-previews/social-controllers@2.0.0-preview-4c0846313
@metamask-previews/storage-service@1.0.1-preview-4c0846313
@metamask-previews/subscription-controller@6.1.2-preview-4c0846313
@metamask-previews/transaction-controller@64.3.0-preview-4c0846313
@metamask-previews/transaction-pay-controller@19.2.1-preview-4c0846313
@metamask-previews/user-operation-controller@41.2.0-preview-4c0846313

Comment thread packages/passkey-controller/src/PasskeyController.ts Outdated
@tanguyenvn tanguyenvn force-pushed the feat/TO-540-passkey-controller branch from cb17b00 to 938fc5d Compare April 27, 2026 10:09
@tanguyenvn tanguyenvn requested a review from lwin-kyaw April 27, 2026 10:10
chaitanyapotti
chaitanyapotti previously approved these changes Apr 27, 2026
Copy link
Copy Markdown
Member

@chaitanyapotti chaitanyapotti left a comment

Choose a reason for hiding this comment

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

Approved from Business logic end

@tanguyenvn tanguyenvn requested a review from mcmire April 27, 2026 10:57
@tanguyenvn
Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@github-actions
Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.1.0-preview-938fc5d87
@metamask-previews/accounts-controller@37.2.0-preview-938fc5d87
@metamask-previews/address-book-controller@7.1.1-preview-938fc5d87
@metamask-previews/ai-controllers@0.6.3-preview-938fc5d87
@metamask-previews/analytics-controller@1.0.1-preview-938fc5d87
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-938fc5d87
@metamask-previews/announcement-controller@8.1.0-preview-938fc5d87
@metamask-previews/app-metadata-controller@2.0.1-preview-938fc5d87
@metamask-previews/approval-controller@9.0.1-preview-938fc5d87
@metamask-previews/assets-controller@6.0.0-preview-938fc5d87
@metamask-previews/assets-controllers@104.2.0-preview-938fc5d87
@metamask-previews/authenticated-user-storage@1.0.0-preview-938fc5d87
@metamask-previews/base-controller@9.1.0-preview-938fc5d87
@metamask-previews/base-data-service@0.1.1-preview-938fc5d87
@metamask-previews/bridge-controller@70.1.1-preview-938fc5d87
@metamask-previews/bridge-status-controller@70.0.5-preview-938fc5d87
@metamask-previews/build-utils@3.0.4-preview-938fc5d87
@metamask-previews/chain-agnostic-permission@1.5.0-preview-938fc5d87
@metamask-previews/chomp-api-service@1.0.0-preview-938fc5d87
@metamask-previews/claims-controller@0.5.0-preview-938fc5d87
@metamask-previews/client-controller@1.0.1-preview-938fc5d87
@metamask-previews/compliance-controller@2.0.0-preview-938fc5d87
@metamask-previews/composable-controller@12.0.1-preview-938fc5d87
@metamask-previews/config-registry-controller@0.2.0-preview-938fc5d87
@metamask-previews/connectivity-controller@0.2.0-preview-938fc5d87
@metamask-previews/controller-utils@11.20.0-preview-938fc5d87
@metamask-previews/core-backend@6.2.1-preview-938fc5d87
@metamask-previews/delegation-controller@3.0.0-preview-938fc5d87
@metamask-previews/earn-controller@12.0.0-preview-938fc5d87
@metamask-previews/eip-5792-middleware@3.0.3-preview-938fc5d87
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.0-preview-938fc5d87
@metamask-previews/eip1193-permission-middleware@1.0.3-preview-938fc5d87
@metamask-previews/ens-controller@19.1.1-preview-938fc5d87
@metamask-previews/eth-block-tracker@15.0.1-preview-938fc5d87
@metamask-previews/eth-json-rpc-middleware@23.1.1-preview-938fc5d87
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-938fc5d87
@metamask-previews/foundryup@1.0.1-preview-938fc5d87
@metamask-previews/gas-fee-controller@26.1.1-preview-938fc5d87
@metamask-previews/gator-permissions-controller@4.0.0-preview-938fc5d87
@metamask-previews/geolocation-controller@0.1.2-preview-938fc5d87
@metamask-previews/json-rpc-engine@10.2.4-preview-938fc5d87
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-938fc5d87
@metamask-previews/keyring-controller@25.2.0-preview-938fc5d87
@metamask-previews/logging-controller@8.0.1-preview-938fc5d87
@metamask-previews/message-manager@14.1.1-preview-938fc5d87
@metamask-previews/messenger@1.1.1-preview-938fc5d87
@metamask-previews/messenger-cli@0.2.0-preview-938fc5d87
@metamask-previews/money-account-balance-service@0.2.0-preview-938fc5d87
@metamask-previews/money-account-controller@0.1.0-preview-938fc5d87
@metamask-previews/money-account-upgrade-controller@1.0.0-preview-938fc5d87
@metamask-previews/multichain-account-service@8.0.1-preview-938fc5d87
@metamask-previews/multichain-api-middleware@2.0.0-preview-938fc5d87
@metamask-previews/multichain-network-controller@3.0.6-preview-938fc5d87
@metamask-previews/multichain-transactions-controller@7.0.4-preview-938fc5d87
@metamask-previews/name-controller@9.1.1-preview-938fc5d87
@metamask-previews/network-controller@30.0.1-preview-938fc5d87
@metamask-previews/network-enablement-controller@5.0.2-preview-938fc5d87
@metamask-previews/notification-services-controller@23.1.0-preview-938fc5d87
@metamask-previews/passkey-controller@0.0.0-preview-938fc5d87
@metamask-previews/permission-controller@12.3.0-preview-938fc5d87
@metamask-previews/permission-log-controller@5.1.0-preview-938fc5d87
@metamask-previews/perps-controller@3.2.0-preview-938fc5d87
@metamask-previews/phishing-controller@17.1.1-preview-938fc5d87
@metamask-previews/polling-controller@16.0.4-preview-938fc5d87
@metamask-previews/preferences-controller@23.1.0-preview-938fc5d87
@metamask-previews/profile-metrics-controller@3.1.3-preview-938fc5d87
@metamask-previews/profile-sync-controller@28.0.2-preview-938fc5d87
@metamask-previews/ramps-controller@13.2.0-preview-938fc5d87
@metamask-previews/rate-limit-controller@7.0.1-preview-938fc5d87
@metamask-previews/react-data-query@0.2.0-preview-938fc5d87
@metamask-previews/remote-feature-flag-controller@4.2.0-preview-938fc5d87
@metamask-previews/sample-controllers@4.0.4-preview-938fc5d87
@metamask-previews/seedless-onboarding-controller@9.1.0-preview-938fc5d87
@metamask-previews/selected-network-controller@26.1.0-preview-938fc5d87
@metamask-previews/shield-controller@5.1.1-preview-938fc5d87
@metamask-previews/signature-controller@39.2.0-preview-938fc5d87
@metamask-previews/social-controllers@2.0.0-preview-938fc5d87
@metamask-previews/storage-service@1.0.1-preview-938fc5d87
@metamask-previews/subscription-controller@6.1.2-preview-938fc5d87
@metamask-previews/transaction-controller@64.3.0-preview-938fc5d87
@metamask-previews/transaction-pay-controller@19.2.1-preview-938fc5d87
@metamask-previews/user-operation-controller@41.2.0-preview-938fc5d87

Copy link
Copy Markdown
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Had one more comment, but from a Core Platform perspective this looks good otherwise.

Only other comment I have is, is there any part of this controller that we don't need right now and don't anticipate needing in the future? There seems to be a lot of code here, and while all of it may be necessary (I'm not familiar with how passkeys work), if there is any way to simplify what we are introducing, now is a good time to do that rather than later.

@@ -0,0 +1,42 @@
export {
controllerName,
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.

Conventionally we do not export controller names, would you mind removing this?

Suggested change
controllerName,

Copy link
Copy Markdown
Contributor Author

@tanguyenvn tanguyenvn Apr 27, 2026

Choose a reason for hiding this comment

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

Hi @mcmire, I've removed unnecessary exports in index.ts file.
We strive to keep the codebase minimal. However, since the @simplewebauthn/server package requires NodeJS environment, we have to port necessary logic from this package to the webauthn folder to make it compatible with our environment.

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 f921608. Configure here.

@tanguyenvn tanguyenvn enabled auto-merge April 27, 2026 16:01
@tanguyenvn tanguyenvn requested a review from mcmire April 27, 2026 16:10
Copy link
Copy Markdown
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

LGTM.

@tanguyenvn tanguyenvn added this pull request to the merge queue Apr 27, 2026
Merged via the queue into main with commit d6bd865 Apr 27, 2026
362 checks passed
@tanguyenvn tanguyenvn deleted the feat/TO-540-passkey-controller branch April 27, 2026 18:41
@dlefloch
Copy link
Copy Markdown

@codex test

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants