Skip to content

feat(passkey): passkey provider, passkey login and WebAuthn MFA (server)#616

Open
brkfun wants to merge 1 commit into
passbolt:masterfrom
brkfun:feature/passkey-provider
Open

feat(passkey): passkey provider, passkey login and WebAuthn MFA (server)#616
brkfun wants to merge 1 commit into
passbolt:masterfrom
brkfun:feature/passkey-provider

Conversation

@brkfun

@brkfun brkfun commented Jul 5, 2026

Copy link
Copy Markdown

Part of a coordinated set of 3 pull requests — passbolt_api, passbolt_styleguide and
passbolt_browser_extension — that together add first-class passkey / WebAuthn support to Passbolt,
one of the most frequently requested capabilities from the community. The three features are:

  1. Passkey provider — Passbolt acts as a WebAuthn authenticator for third-party websites
    (Dashlane / 1Password / Bitwarden style). Passkeys are created and stored inside the encrypted
    vault as a passkey resource type, offered inline via autofill (conditional mediation), and unlocked
    with the master passphrase or an optional PIN.
  2. Passkey login (passwordless) — a user can enrol a passkey to sign in to Passbolt without typing
    their passphrase. The passphrase keeps working as a fallback (a lost passkey never locks anyone
    out). Split-kit design: the client half never leaves the browser profile, the server half is only
    released after a valid assertion.
  3. Passkey as MFA — FIDO2 security keys as a second factor, alongside the existing
    TOTP / Yubikey / Duo providers.

The three repos must be deployed together. This PR is the API / server side.


This pull request is a (multiple allowed):

  • bug fix
  • change of existing behavior
  • new feature

Checklist

  • User stories are present (given, when, then format)
  • Unit tests are passing
  • Selenium tests are passing
  • Check style is not triggering new error or warning

What you did

Server-side implementation of the three passkey features above.

New PasskeyAuthentication plugin (CE):

  • Passwordless passkey login: /passkey/login/begin + /passkey/login/finish (unauthenticated,
    anti-enumeration — always 200), /passkey/setup/begin + /passkey/setup/finish (auth
    enrolment storing the credential + the server half of the passphrase kit), /passkey/collect.
  • Management: GET /passkey/settings (list credentials), DELETE /passkey/settings/{id}
    (delete one by base64url credential id, or all).
  • Organization toggle (CE, free): GET/POST /passkey/organization/settings to enable/disable
    passkey login org-wide (admin-only write, unauthenticated-readable).
  • Non-resident credentials (RESIDENT_KEY_DISCOURAGED) so several passkeys can be enrolled per
    authenticator; login supplies the user id + allowCredentials.

MultiFactorAuthentication plugin: WebAuthn/FIDO2 as a new MFA provider (setup/verify
credentials table + email notifications), mirroring the Yubikey / TOTP / Duo structure.

Passkey provider storage: a v5-passkey-aware resource type + a passkeys array in the v5 secret
definitions, so provider passkeys are stored as encrypted vault secrets.

User stories

  • Given an unauthenticated user with an enrolled passkey, when they start passkey login, then
    the server returns assertion options scoped to that user without revealing whether the
  • Given an administrator, when they POST the organization passkey setting, then it is
    persisted; given a non-admin, when they POST, then they get 403.
  • Given a user, when they delete a passkey by an unknown credential id, then

Fix included

PasskeyOrganizationSettingsService::setEnabled() persisted a raw array where the organization settings
table validates a UTF8 string, so the admin toggle 500'd on every save — now JSON-encode
read side and every other org setting.

Tests

39 new PHPUnit tests (controllers, services, organization settings) executed green locally against a
test DB; existing passkey tests still pass. composer cs-check clean.

Server-side implementation of three coordinated passkey features (see the passbolt_styleguide and
passbolt_browser_extension counterparts). Passkey / WebAuthn support is a long-standing community
request.

- Passkey login (passwordless): a new PasskeyAuthentication plugin — login and setup begin/finish
  (unauthenticated login is anti-enumeration; setup stores the credential + the server half of the
  passphrase kit), credential management (list / delete by credential id), and a CE organization toggle
  (admin-only write, unauthenticated-readable). Non-resident credentials so several passkeys can be
  enrolled per authenticator.
- Passkey MFA: WebAuthn/FIDO2 as a new MultiFactorAuthentication provider (setup/verify begin/finish,
  credentials table + email notifications), mirroring Yubikey/TOTP/Duo.
- Passkey provider: a v5-passkey resource type + a passkeys array in the v5 secret definitions, so
  provider passkeys are stored as encrypted vault secrets.

Includes 39 PHPUnit tests (green against a test DB); passes composer cs-check.
@CLAassistant

CLAassistant commented Jul 5, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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