@openliveness/web 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +99 -16
  2. package/package.json +31 -2
package/README.md CHANGED
@@ -1,39 +1,122 @@
1
1
  # @openliveness/web
2
2
 
3
- Browser side of openliveness. Shows the QR code and waits for the phone to finish.
3
+ > Browser SDK for [openliveness](https://github.com/ramuvenky/openliveness) — proves there is a real, live human in front of the camera, without sending any biometric data to a server.
4
+
5
+ In a world where deepfakes and AI-generated video are becoming indistinguishable from reality, this package lets your web app verify that the person on the other end of a camera is actually a live human — **without the user's face, video, or any biometric features ever leaving their phone**.
6
+
7
+ ## Why liveness without the cloud
8
+
9
+ Browser-only liveness is broken. Virtual-camera software (OBS, ManyCam) lets an attacker feed AI-generated video into any `getUserMedia()` call, and the browser has no way to tell real-camera footage from injected footage. This is the dominant fraud vector against remote liveness checks today.
10
+
11
+ Every commercial fix ships your users' faces to the vendor's cloud. **openliveness does not.** All biometric computation runs on the user's phone, which cryptographically proves its camera is genuine using hardware attestation (Apple App Attest / Google Play Integrity). Your backend — and this package — only ever see a signed attestation JWT.
12
+
13
+ ## How it works
14
+
15
+ ```
16
+ Browser shows QR → User scans with phone → Phone runs liveness locally
17
+ → Phone signs result with hardware key
18
+ → Server verifies proof
19
+ → Browser session complete
20
+ ```
21
+
22
+ This package handles the browser half: display the QR, wait for the phone to finish, hand you the JWT.
23
+
24
+ ## Install
4
25
 
5
26
  ```bash
6
27
  pnpm add @openliveness/web
28
+ # or
29
+ npm install @openliveness/web
7
30
  ```
8
31
 
32
+ Zero runtime dependencies beyond `qrcode`. Works with any framework or no framework.
33
+
34
+ ## Usage
35
+
9
36
  ```ts
10
37
  import { verify } from '@openliveness/web';
11
38
 
12
39
  const result = await verify({
13
- relayUrl: 'localhost:3000', // your relay host
14
- assuranceRequired: 'IAL2',
15
- onQRReady: (dataUrl) => (img.src = dataUrl),
40
+ relayUrl: 'localhost:3000', // your relay — see "Running the relay" below
41
+ assuranceRequired: 'IAL2', // 'IAL2' | 'software_only'
42
+ onQRReady: (dataUrl) => (document.getElementById('qr').src = dataUrl),
16
43
  onPhoneConnected: () => setStatus('Follow the steps on your phone'),
17
44
  });
18
45
 
19
- // send result.token to your backend and verify it with @openliveness/verify
46
+ // result.decision === 'pass'
47
+ // result.assuranceLevel === 'IAL2'
48
+ // result.token === JWT — forward it to your backend
20
49
  ```
21
50
 
22
- **You run the relay yourself.** It's the Node server that brokers the
23
- browser↔phone handshake — see
24
- [openliveness/relay](https://github.com/ramuvenky/openliveness/tree/main/relay)
25
- for the `docker compose` setup. Point `relayUrl` at wherever you deploy it.
51
+ Send `result.token` to your backend and verify it with [`@openliveness/verify`](https://www.npmjs.com/package/@openliveness/verify). **Never trust the browser result on its own** — the JWT is the cryptographic proof; everything else is UI state.
26
52
 
27
- It uses a WebSocket and falls back to polling (1s, growing 1.5x up to 5s) if the socket fails.
28
- If the phone reports a failed check, `verify()` rejects with `CDLRetryableError`. Call `verify()` again for a fresh session.
29
-
30
- React:
53
+ ### React
31
54
 
32
55
  ```tsx
33
56
  import { LivenessWidget } from '@openliveness/web/react';
34
57
 
35
- <LivenessWidget relayUrl="relay.openliveness.dev" onComplete={(r) => send(r.token)} />
58
+ <LivenessWidget
59
+ relayUrl="localhost:3000"
60
+ onComplete={(r) => send(r.token)}
61
+ />
36
62
  ```
37
63
 
38
- `relyingParty` defaults to the page hostname. Always re-check the token on your backend,
39
- the browser result alone is not proof.
64
+ ### Errors
65
+
66
+ If the phone reports a failed check, `verify()` rejects with `CDLRetryableError` — call `verify()` again for a fresh session.
67
+
68
+ Transport: WebSocket first, falling back to HTTP polling (1s, growing 1.5x up to 5s) if the socket fails.
69
+
70
+ ## Running the relay
71
+
72
+ This package talks to a small Node service — the relay — that brokers the browser↔phone handshake and issues the JWT. **You run the relay yourself.** It is open source and ships in the same repo:
73
+
74
+ ```bash
75
+ git clone https://github.com/ramuvenky/openliveness.git
76
+ cd openliveness/relay && docker compose up -d
77
+ # relay listens on http://localhost:3000
78
+ ```
79
+
80
+ Point `relayUrl` at wherever you deploy it. The relay never sees biometric data — only signed scores.
81
+
82
+ ## The complete picture
83
+
84
+ openliveness is four pieces working together. This package is one of them:
85
+
86
+ | Where | Package | Role |
87
+ |-------|---------|------|
88
+ | Browser | **`@openliveness/web`** *(this package)* | Shows QR, waits for the phone |
89
+ | Phone | [Android SDK](https://jitpack.io/#ramuvenky/openliveness) · iOS SDK (coming soon) | Runs the five liveness layers, signs the result |
90
+ | Relay | [`relay/`](https://github.com/ramuvenky/openliveness/tree/main/relay) | Brokers the handshake, issues the JWT |
91
+ | Server | [`@openliveness/verify`](https://www.npmjs.com/package/@openliveness/verify) | Verifies the JWT on your backend |
92
+
93
+ ## What you don't ship by using this
94
+
95
+ - Video, photos, face embeddings, or any biometric features leaving the user's device
96
+ - A dependency on anyone's cloud (relay is self-host; phone runs locally)
97
+ - GDPR Article 9 scope for your backend — you never process special-category data
98
+
99
+ ## Who this is for
100
+
101
+ - **Banks and financial institutions** — IAL2-grade liveness for KYC onboarding without cloud biometric processing
102
+ - **Healthcare** — patient verification where biometric data must stay on-device (HIPAA, GDPR)
103
+ - **Government and public sector** — remote liveness proofing with auditable, open-source algorithms
104
+ - **KYC and identity platforms** — add liveness without becoming a biometric data processor
105
+ - **Any application** — where proving human presence must not compromise privacy
106
+
107
+ ## Documentation
108
+
109
+ - [Project README](https://github.com/ramuvenky/openliveness#readme) — overview and design principles
110
+ - [Technical specification](https://github.com/ramuvenky/openliveness/blob/main/docs/Spec.md) — full 28-section protocol reference
111
+ - [Threat model](https://github.com/ramuvenky/openliveness/blob/main/protocol/ThreatModel.md) — what this protects against, what it does not
112
+ - [Attestation schema](https://github.com/ramuvenky/openliveness/blob/main/protocol/AttestationSchema.json) — JWT payload contract
113
+
114
+ ## Contributing
115
+
116
+ Issues and pull requests welcome at [github.com/ramuvenky/openliveness](https://github.com/ramuvenky/openliveness). See [CONTRIBUTING.md](https://github.com/ramuvenky/openliveness/blob/main/CONTRIBUTING.md) — the iOS SDK port is currently the highest-value contribution.
117
+
118
+ Report security issues privately per [SECURITY.md](https://github.com/ramuvenky/openliveness/blob/main/SECURITY.md).
119
+
120
+ ## License
121
+
122
+ Apache 2.0
package/package.json CHANGED
@@ -1,8 +1,37 @@
1
1
  {
2
2
  "name": "@openliveness/web",
3
- "version": "0.1.0",
4
- "description": "Browser SDK for openliveness: QR display and session tracking",
3
+ "version": "0.1.1",
4
+ "description": "Browser SDK for openliveness — liveness verification where biometric data never leaves the user's phone. Proves there is a real live human in front of the camera without sending video, photos, or face embeddings to a server.",
5
5
  "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ramuvenky/openliveness.git",
9
+ "directory": "web-sdk"
10
+ },
11
+ "homepage": "https://github.com/ramuvenky/openliveness#readme",
12
+ "bugs": "https://github.com/ramuvenky/openliveness/issues",
13
+ "keywords": [
14
+ "liveness",
15
+ "liveness-detection",
16
+ "face-liveness",
17
+ "presentation-attack-detection",
18
+ "pad",
19
+ "anti-spoofing",
20
+ "deepfake-detection",
21
+ "injection-attack",
22
+ "kyc",
23
+ "ial2",
24
+ "nist-800-63",
25
+ "biometrics",
26
+ "privacy",
27
+ "gdpr",
28
+ "hardware-attestation",
29
+ "app-attest",
30
+ "play-integrity",
31
+ "cross-device",
32
+ "qr-code",
33
+ "openliveness"
34
+ ],
6
35
  "main": "dist/index.js",
7
36
  "types": "dist/index.d.ts",
8
37
  "exports": {