@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.
- package/README.md +99 -16
- package/package.json +31 -2
package/README.md
CHANGED
|
@@ -1,39 +1,122 @@
|
|
|
1
1
|
# @openliveness/web
|
|
2
2
|
|
|
3
|
-
Browser
|
|
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',
|
|
14
|
-
assuranceRequired: 'IAL2',
|
|
15
|
-
onQRReady: (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
|
-
//
|
|
46
|
+
// result.decision === 'pass'
|
|
47
|
+
// result.assuranceLevel === 'IAL2'
|
|
48
|
+
// result.token === JWT — forward it to your backend
|
|
20
49
|
```
|
|
21
50
|
|
|
22
|
-
**
|
|
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
|
-
|
|
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
|
|
58
|
+
<LivenessWidget
|
|
59
|
+
relayUrl="localhost:3000"
|
|
60
|
+
onComplete={(r) => send(r.token)}
|
|
61
|
+
/>
|
|
36
62
|
```
|
|
37
63
|
|
|
38
|
-
|
|
39
|
-
|
|
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.
|
|
4
|
-
"description": "Browser SDK for openliveness
|
|
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": {
|