@realitylimit/core
v1.0.0
Published
Hardware-Bound Transaction Authorization SDK — Passwordless, per-action FIDO2 signing that eliminates session trust entirely.
Maintainers
Readme
@realitylimit/core
Hardware-Bound Transaction Authorization SDK — Passwordless, per-action FIDO2 signing.
What This Package Does
Standard WebAuthn (Passkeys) secures the login event then immediately falls back to a session cookie. @realitylimit/core extends hardware trust to every sensitive action after login.
Every wire transfer, admin deletion, or privileged mutation requires a fresh biometric hardware signature. There is no session token that can authorize transactions. Stealing the cookie gives an attacker nothing.
Installation
npm install @realitylimit/coreThree Entry Points
| Import | Environment | Use case |
|---|---|---|
| @realitylimit/core | IoT / Native / Node | Pass raw TPM/PUF hardware bytes directly |
| @realitylimit/core/server | Node.js backend | Generate and verify WebAuthn transaction challenges |
| @realitylimit/core/browser | Browser | Trigger OS hardware biometric prompt |
Usage — Web (Most Common)
Backend (Next.js / Express / any Node server)
import { createTransactionOptions, verifyTransactionExecution } from '@realitylimit/core/server';
// Step 1: When user initiates a sensitive action
const intent = { action: 'wire-transfer', amount: 500, to: 'bob' };
const userCredentials = await db.getUserCredentials(userId); // from your database
const { options, expectedChallenge, encodedIntent } = await createTransactionOptions(
'yourdomain.com',
intent,
userCredentials
);
// Save challenge + intent to your database
await db.saveChallenge({ userId, challenge: expectedChallenge, intent: encodedIntent });
return Response.json(options); // send FIDO options to client
// Step 2: When client sends back the hardware signature
const { attResp } = await req.json();
const challengeDoc = await db.getChallenge(userId);
const userCredential = await db.getCredential(userId, attResp.id);
const result = await verifyTransactionExecution(
'yourdomain.com',
'https://yourdomain.com',
attResp,
challengeDoc.challenge,
userCredential
);
if (result.verified) {
// Consume the challenge (single-use)
await db.deleteChallenge(challengeDoc.id);
// Execute the stored intent safely
await executeIntent(challengeDoc.intent);
}Frontend (React / Vue / Vanilla JS)
import { executeProtectedAction } from '@realitylimit/core/browser';
const handleTransfer = async () => {
// 1. Get FIDO challenge options from your backend
const options = await fetch('/api/protected/options', {
method: 'POST',
body: JSON.stringify({ userId, intent })
}).then(r => r.json());
// 2. Trigger OS biometric hardware prompt (FaceID / Windows Hello)
// This line physically requires the user to touch/look at their device
const attResp = await executeProtectedAction(options);
// 3. Send hardware signature to backend for verification
await fetch('/api/protected/verify', {
method: 'POST',
body: JSON.stringify({ attResp, userId })
});
};Usage — IoT / Native (Raw Hardware)
import { RealityLimitAuth } from '@realitylimit/core';
// hardwareAnchor = real bytes from TPM/PUF/Secure Enclave
// Must be at least 16 bytes. Passing fake bytes throws a CRITICAL error.
const rl = new RealityLimitAuth('device-serial-001', tpmRawBytes);
const payload = new TextEncoder().encode(JSON.stringify({
action: 'unlock-door',
timestamp: Date.now()
}));
// Creates a payload + 32-byte Carter-Wegman MAC tag
const signedPacket = rl.createPacket(payload);
// Verify on the receiving end
const isValid = rl.verifyPacket(signedPacket, payload);Security Properties
| Property | Guarantee |
|---|---|
| Forgery bound | ≤ 2^-256 (Carter-Wegman + blake2b) |
| Replay protection | Each challenge is single-use, deleted after verification |
| Phishing resistance | WebAuthn is origin-bound — proxy attacks fail |
| Session theft | Sessions don't authorize transactions — hardware does |
| Quantum resistance | secp256r1 ECDLP — no known efficient quantum attack |
Honest limitation: Physical device theft + successful biometric bypass defeats this system. No software layer can stop that.
Reference Implementation
A complete Next.js banking demo is available at:
example/web-demo
Full Documentation
- Why RealityLimit exists
- Architecture deep-dive
- Transaction flow + attack scenarios
- Cryptographic proof
- Version changelog + roadmap
License
MIT
