@verifast/kyc-sdk
v0.1.0
Published
VeriFast embeddable KYC SDK (Mode B) — drive onboarding liveness inside your own app.
Maintainers
Readme
@verifast/kyc-sdk
Embeddable KYC SDK (Mode B) — run VeriFast onboarding liveness inside your own app, owning the UX. (For the zero-integration option, use the hosted link instead.)
How it fits
Your backend creates an onboarding with your member API key:
POST /v1/kyc/onboarding { "subject_ref": "<your customer id>" } → { "onboarding_id": "...", "client_token": "...", ... }The
client_tokenis a one-time, short-lived token scoped to this one onboarding. Never put your member API key in the client app — only theclient_token.Your app passes those to the SDK. It runs the document-first flow — consent → country + document type → photograph the document (front, plus back for cards) → OCR read-back to confirm name/DOB → AWS Face Liveness (backend-vended, narrowly-scoped temporary AWS creds — no Cognito) → submits the result with the confirmed applicant, and calls your callbacks.
Your backend learns the outcome via the completion webhook (or by polling
GET /v1/kyc/onboarding/{id}).
Install
npm install @verifast/kyc-sdk aws-amplify @aws-amplify/ui-react @aws-amplify/ui-react-livenessThe aws-amplify* packages are optional peers — only needed for the live capture
component (<VeriFastKyc>); the headless client has no dependencies.
React component
import { VeriFastKyc } from "@verifast/kyc-sdk";
<VeriFastKyc
onboardingId={onboardingId}
clientToken={clientToken}
baseUrl="https://api.verifast.solutions" // or "" if same-origin / proxied
onSuccess={(r) => router.push("/onboarding/done")}
onFail={(r) => setError(`Liveness ${r.status}`)}
onError={(e) => console.error(e)}
/>The component OCRs the document via the backend and pre-fills the confirm step, so the
applicant only corrects what's wrong (no blind typing). Pass countries to override the
default option list (e.g. the full ISO set, or your policy-allowed subset). When the
backend is the offline stub (dev), it renders a "Simulate liveness" button so you can
build your flow without AWS or a camera.
The AWS Face Liveness detector ships with a dark VeriFast theme by default (Amplify
ThemeProvider + a small injected stylesheet scoped to .vf-kyc-liveness). Pass
themed={false} to leave it unstyled and theme it yourself.
Headless client (build your own UI)
import { VeriFastKycClient, KycAuthError } from "@verifast/kyc-sdk/client";
const client = new VeriFastKycClient({ onboardingId, clientToken, baseUrl });
const session = await client.startSession(); // session.credentials for your own widget
// After you capture the document front, OCR it so the user can confirm name/DOB:
const doc = await client.analyzeDocument(frontBase64); // { fullName, dateOfBirth, ... }
// Run your liveness capture, then submit with the confirmed applicant + images:
const result = await client.submitResult(session.sessionId, {
idDocumentBase64: frontBase64,
idDocumentBackBase64: backBase64, // national ID / licence only
applicant: {
firstName: doc.firstName ?? "",
lastName: doc.lastName ?? "",
dateOfBirth: doc.dateOfBirth,
nationality: "MNG", // ISO 3166-1 alpha-3
documentType: "PASSPORT", // PASSPORT | IDENTIFICATION_CARD | DRIVER_LICENSE
consentStore: true,
},
});startSession()/analyzeDocument()/submitResult() throw KycAuthError (401:
expired/used link) or KycError (other failures).
Device fingerprint (login-risk / account-takeover defense)
On your LOGIN page, compute the cross-member device id and send it to your backend with
the login attempt; your backend forwards it as device_id to POST /v1/kyc/logins
(your member API key must never reach the browser):
import { computeDeviceFingerprint } from "@verifast/kyc-sdk/fingerprint";
const deviceId = await computeDeviceFingerprint(); // "vf1:<sha256>", cached per siteNo npm? A 1.3 KB standalone build is hosted by VeriFast:
<script src="https://<verifast-host>/fingerprint.js"></script>
<script>
const deviceId = await window.VeriFastDevice.computeDeviceFingerprint();
</script>The id uses only origin-independent, low-churn hardware signals (no canvas — privacy browsers randomize it per-site, which would break cross-member matching) and is cached per site for stability. VeriFast never stores it raw: member-salted hash locally, one-way OPRF token for the network-wide burned-device check.
Build & test
npm run build # tsc → dist/ (ESM + .d.ts)
npm run build && node --test test/client.test.mjs # headless-client smoke testsIAM (live capture)
The backend IAM principal needs sts:GetFederationToken +
rekognition:StartFaceLivenessSession (vending) and the Rekognition compute actions.
See web/app/kyc/INTEGRATION.md.
