Skip to main content

Private FaceMatch

When verifying a user, you can request ZKPassport to conduct a Private FaceMatch of the user. Prior to completing the verification, ZKPassport makes the user perform a face scan using their device camera and compares it to the photo on their ID. If the face matches, the verification process continues. The whole process is conducted locally via ML models running directly on the user's device.

The scan includes a liveness check to prevent spoofing (e.g. using someone else's photo or holding the ID photo in front of the camera): the user is asked to turn their head in prompted directions while every frame is matched against the ID photo.

For how the comparison works, the models behind it and their published accuracy, see the Private FaceMatch Technical Note.

This example uses the @zkpassport/ui verify button and verifies the proofs on your server.

import { VerifyWithZKPassport } from "@zkpassport/ui/react-button";

<VerifyWithZKPassport
purpose="Prove you are the person on the ID"
service={{ scope: "facematch" }}
query={{ facematch: true }}
onSuccess={async ({ proofs, result }) => {
// Send the proofs to your server to verify them
const response = await fetch("/api/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ proofs, result }),
});
return (await response.json()).verified;
}}
/>;

On your server, recreate the query and verify the proofs (see Quick Start):

const { query } = zkPassport.createQuery().facematch("strict").done();
const { verified } = await zkPassport.verify({
proofs,
originalQuery: query,
queryResult: result,
scope: "facematch",
});

if (verified) {
console.log(result.facematch.passed ? "FaceMatch passed" : "FaceMatch failed");
} else {
console.log("Verification failed");
}