- From: Slobodan Pejić <notifications@github.com>
- Date: Tue, 24 Jun 2025 06:56:12 -0700
- To: w3ctag/design-reviews <design-reviews@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3ctag/design-reviews/issues/1097/3000607234@github.com>
pejic left a comment (w3ctag/design-reviews#1097) Hi @yoavweiss! Thanks for taking a look. I have amended the explainer with an API Shape section (copied below) providing examples for both registration (passkey enrollment) and assertion (payment). --- ### API Shape When API users want to create a passkey for payments they register via `navigator.credential.create` setting the payment extension (`"isPayment": true`), and now the public key is returned with the browser bound public key in clientDataJSON and the signature in the payment extension's outputs. E.g., ``` credential = await navigator.credentials.create({ challenge: /* random Uint8Array generated by the server */, ... extensions: { "payment": { isPayment: true, // An optional list of allowed algorithms. When not present or empty, the // pubKeyCredparams are used defaulting to ES256 and RS256. In this // example ES256 and RS256 are allowed and RS256 is preferred. browserBoundPubKeyCredParams: [ { type: "public-key", alg: -257 // "RS256" }, { type: "public-key", alg: -7 // "ES256" } ] } } }); clientData = JSON.parse(arrayBufferToString(credential.response.clientDataJSON)); // browserBoundPublicKey is a base64url encoded - COSE_key representation of the public key const bbkPublicKeyBase64UrlEncoded = clientData.payment.browserBoundPublicKey; // The signature is an array buffer with a format specific to the algorithm. const signatureArrayBuffer = credential.getClientExtenionResults().payment.browserBoundSignature.signature; // The credential is sent to the server. // Later the server verifies the cryptographic signature over clientDataJSON using browserBoundPublicKey. ``` When API users want to assert payments, they use the secure payment confirmation API (via PaymentRequest) and now the browser bound public key and signature are returned in the response, the public key in clientDataJSON and the signature in payment extension outputs (same as the registration above): E.g., ``` const request = new PaymentRequest([{ supportedMethods: "secure-payment-confirmation", data: { // List of credential IDs obtained from the bank. credentialIds, rpId: "fancybank.example", // The challenge is also obtained from the bank. challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the bank */]), ... // An optional list of allowed algorithms defaulting to ES256 and RS256. // In this example ES256 and RS256 are allowed and ES256 is preferred. // Browser bound keys are not created when already present, so this // list is only used when the browser bound key does need to be // created. browserBoundPubKeyCredParams: [ { type: "public-key", alg: -7 // "ES256" }, { type: "public-key", alg: -257 // "RS256" } ] }], ...); const response = await request.show(); await response.complete('success'); const credential = response.details; clientData = JSON.parse(arrayBufferToString(credential.response.clientDataJSON)); // browserBoundPublicKey is a base64url encoded - COSE_key representation of the public key const bbkPublicKeyBase64UrlEncoded = clientData.payment.browserBoundPublicKey; // The signature is an array buffer with a format specific to the algorithm. const signatureArrayBuffer = credential.getClientExtenionResults().payment.browserBoundSignature.signature; // The credential is sent to the server. // Later the server verifies the cryptographic signature over clientDataJSON using browserBoundPublicKey. ``` -- Reply to this email directly or view it on GitHub: https://github.com/w3ctag/design-reviews/issues/1097#issuecomment-3000607234 You are receiving this because you are subscribed to this thread. Message ID: <w3ctag/design-reviews/issues/1097/3000607234@github.com>
Received on Tuesday, 24 June 2025 13:56:15 UTC