Passkey authentication

The network allows users to issue key generation requests and authenticate them using Passkeys. This chapter describes the protocol flow in detail and points to code examples.

Code example

The full working example is in our demo page in the repository

  1. We provide Passkey authentication via PasskeyAuth module. Let's create the NetworkSigner with associated PasskeyAuth object.

// Generate ephemeral secret key esk
const sk = ed.utils.randomPrivateKey();
ephSK = sk;
// Derive public part epk from esk
ephPK = await ed.getPublicKeyAsync(sk);
// Arbitrary ID to identify the ephemeral key
const ephId = uuidv4();
// Create a client that connects to the backend service
const wpClient = await createWalletProviderService(clusterConfig);
// Here we configure the relying party for local development
const rpConfig: RelyingPartyConfig = {
  rpId: 'localhost',
  rpName: 'http://localhost:5173',
};
// Information about the owner of the passkey 
const passkeyUser: PasskeyUser = {
  id: userId,
  displayName: 'Alice',
  name: '[email protected] ' + userId, // For development purposes
};

// Get passkey credential id from your storage
const credentialId = getPasskeyCredentialId();
// Create Passkey authenticator
const passkeyAuth = new PasskeyAuth(
  rpConfig,
  passkeyUser,
  ephId,
  ephPK,
  // Lifetime of one hour for ephPK
  60 * 60,
  // If credentialId is null, we will do passkey register, otherwise, we will do passkey auth/login
  credentialId,
);

// Create a new signer instance
const sdk = new NetworkSigner(wpClient, threshold, partiesNumber, passkeyAuth);
  1. Now, you can generate a key like in the EOA example by calling the authenticateAndCreateKey method.

  2. Calling this method will prompt the browser to request Passkey User Verification. Once user verification is done, the KeygenResponse is returned.

  3. The response will contain the passkeyCredentialId information used to request authentication. The dApp is responsible for storing that value persistently (most likely on their backend). The passkeyCredentialId can be later reused in subsequent keygen requests. In our demo webpage we use local storage for simplicity.

The esk key can be later used by the frontend in subsequent signgen requests for authenticating.

Flow

This section describes the passkey authentication flow in detail.

The actors:

  1. WPFE - Wallet Provider frontend. Logic implemented in walletprovider-sdk library. Communicates with WPBE

  2. WPBE - Wallet Provider service backend. The example service is here. Communicates with Aggregator

  3. Aggregator - Gateway to the network of operators, gets requests from WPBE and forwards them to Operators

  4. Operator - Node that runs DKLS23 protocol, waits for incoming requests from Aggregator

User wants to do a keygen, WPFE library prepares setup_opts and starts the protocol:

  1. WPFE generates a random ephemeral key pair {ephPK, ephSK}

  2. WPFE creates KeygenSetupOpts, that contains public part ephPK, permissions, and other parameters required to do keygen

3-9 passing the setup_opts, and collecting the challenges from the operators

  1. WPBE calculates final_challenge that consist of a hash of the setup_opts and challenges ch_i from the Operators

  2. Forward final_challenge to WPFE

  3. Fetch passkey_id This step is implementation-specific. In our demo webpage, we simply store the passkey_id on the browser's local storage. However, in a real-world scenario, the dApp should store passkey information on its backend.

If passkey_id is not set, we register a new passkey; otherwise, we use the one already created:

  1. The passkey_id is not set, create a register request, use final_challenge from the network as a challenge for passkey registration

  2. User authenticates using passkey compatible device

  3. Get the authentication response sigs

  4. Pass it to WPBE

  5. The passkey_id is set, create login request, use final_challenge from the network as a challenge for passkey authentication

  6. User authenticates using passkey compatible device

  7. Get the authentication response sigs

  8. Pass it to WPBE

User signature goes to the network:

1-5 Creation of setup_msg by Aggregator

  1. Aggregator sends setup_msg to all Operators, the setup_msg contains all information required to authenticate and execute keygen

7-8 Operators compute final_challenge on their own, using data from setup_msg

Verification of passkeys depends on the passkey with the givenpasskey_id being stored in the Operators database.

  1. If passkey_id is not set, verify registration of passkey,

  2. Store passkey_id in the database

  3. The passkey_id is present in the database, fetch the passkey and verify the request

  4. Update passkey in the database after verification

6-11 Run keygen and return a response to the user.

Last updated