Web SDK
A single facescan.js script. Dark-neon liveness modal, FaceMesh + ONNX anti-spoof, auto-attach buttons. Verify server-side with one call.
- Passive + active liveness
- WASM / WebGPU inference
- Graceful active-only fallback
Face Scan is a drop-in identity provider. Add webcam liveness and Sign in with Face Scan to any site — on-device inference, a trained anti-spoof model, challenge-response, and server-signed ES256 tokens.
<script src="/sdk/facescan.js" defer></script>
These buttons call the actual SDK loaded on this page. Your camera stays on your device — only a signed proof leaves the browser.
Runs the webcam liveness modal, then returns a server-signed liveness token and score.
The branded button below is rendered by FaceScan.renderButton. It launches passwordless OIDC login.
Inference runs client-side for instant UX. Trust comes from a server-issued challenge nonce and a signed proof you verify on your backend.
Your page calls checkLiveness(). The SDK asks Face Scan for a one-time nonce and an ordered challenge sequence — blink, turn, smile.
MediaPipe FaceMesh drives the active challenges while our ONNX anti-spoof model scores every frame. The neon ring fills as confidence accrues.
Face Scan mints an ES256 liveness token bound to the nonce. Your backend verifies it against JWKS — or posts it to /liveness/verify-token.
A single facescan.js script. Dark-neon liveness modal, FaceMesh + ONNX anti-spoof, auto-attach buttons. Verify server-side with one call.
Native enrollment with the device key held in the Secure Enclave. Approve web logins by scanning a QR — signatures are ECDSA P-256.
Full OIDC Authorization Code + PKCE. Drop a branded button, get an ES256 id_token with amr:["face","liveness"]. No passwords, ever.
Photos, videos, and masks don't pass. Every proof is bound to a fresh server nonce and cryptographically signed.
Frames never leave the browser by default. Our trained anti-spoof model runs locally via onnxruntime-web.
A purpose-built liveness model scores presentation attacks — screens, prints, and replays — frame by frame.
The server issues an ordered, one-time challenge sequence per session. Replays fail because the nonce won't match.
Liveness and identity tokens are ES256 JWTs signed with kid=faceScan-key-1, verifiable against public JWKS.
Two tags to load the SDK, one button to verify a human. That's the whole liveness integration.
<!-- 1. Load the SDK -->
<script src="http://localhost:4000/sdk/facescan.js" defer></script>
<script>
FaceScan.init({ clientId: "demo-web", baseUrl: "http://localhost:4000" });
</script>
<!-- 2. Auto-attach a liveness button -->
<button data-facescan-liveness data-on-success="onLive">
Verify I'm human
</button>
<script>
function onLive(result) {
// { ok, livenessToken, score, engine, challengesPassed }
await fetch("/api/verify", {
method: "POST",
body: JSON.stringify({ token: result.livenessToken })
});
}
</script>
<!-- Sign in with Face Scan -->
<div id="signin"></div>
<script>
FaceScan.renderButton("#signin", {
scope: "openid profile email",
onSuccess: (r) => console.log("code", r.code),
onError: (e) => console.warn(e)
});
</script>
// Verify a liveness token server-side:
// POST /liveness/verify-token { livenessToken }
// -> { valid, score, clientId, live }
Placeholder plans for the MVP — every tier ships the full anti-spoof stack.
For prototypes and side projects.
For growing products in production.
For scale, compliance, and SLAs.
One script. One button. A real, live human — proven.