8.4 KiB
EncryptID
Unified Identity System for the r-Ecosystem
EncryptID is a self-sovereign identity system built on WebAuthn passkeys, with derived cryptographic keys and social recovery. It provides a consistent login experience across all r-ecosystem apps: rspace.online, rwallet, rvote, rmaps, and rfiles.
Features
- 🔑 Passkey Authentication - Hardware-backed, phishing-resistant login
- 🔐 Client-Side Encryption - Keys derived locally, never leave your device
- 🛡️ Social Recovery - No seed phrases! Recover with trusted guardians
- 🌐 Cross-App SSO - One identity for all r-ecosystem apps
- 💰 Web3 Ready - Integrated with Account Abstraction smart wallets
Quick Start
Installation
npm install @rspace/encryptid
# or
pnpm add @rspace/encryptid
# or
bun add @rspace/encryptid
Basic Usage
import {
registerPasskey,
authenticatePasskey,
getKeyManager,
getSessionManager,
} from '@rspace/encryptid';
// Register a new passkey
const credential = await registerPasskey('user@example.com', 'User Name');
// Authenticate with passkey
const result = await authenticatePasskey();
// Initialize key derivation
const keyManager = getKeyManager();
if (result.prfOutput) {
await keyManager.initFromPRF(result.prfOutput);
}
// Get derived keys
const keys = await keyManager.getKeys();
console.log('Your DID:', keys.did);
// Create session
const session = getSessionManager();
await session.createSession(result, keys.did, {
encrypt: true,
sign: true,
wallet: false,
});
UI Components
<!-- Login button -->
<encryptid-login></encryptid-login>
<!-- With options -->
<encryptid-login
size="large"
variant="outline"
label="Sign in with EncryptID"
show-user
></encryptid-login>
<!-- Guardian setup -->
<encryptid-guardian-setup></encryptid-guardian-setup>
// Import to register custom elements
import '@rspace/encryptid/ui/login-button';
import '@rspace/encryptid/ui/guardian-setup';
Architecture
┌─────────────────────────────────────────────────────────────┐
│ ENCRYPTID LAYERS │
├─────────────────────────────────────────────────────────────┤
│ │
│ Layer 5: Applications │
│ ├── rspace.online (canvas) │
│ ├── rwallet (treasury) │
│ ├── rvote (voting) │
│ ├── rfiles (storage) │
│ └── rmaps (mapping) │
│ │
│ Layer 4: Session & SSO │
│ └── JWT tokens, cross-app authentication │
│ │
│ Layer 3: Smart Wallet (Account Abstraction) │
│ └── ZeroDev Kernel + Passkey Validator │
│ │
│ Layer 2: Derived Keys (WebCrypto) │
│ ├── Encryption Key (AES-256-GCM) │
│ ├── Signing Key (ECDSA P-256) │
│ └── DID Key (Ed25519 → did:key) │
│ │
│ Layer 1: Primary Authentication (WebAuthn) │
│ └── Passkeys (platform + roaming authenticators) │
│ │
└─────────────────────────────────────────────────────────────┘
Modules
webauthn.ts
WebAuthn/passkey registration and authentication with PRF extension support.
import {
registerPasskey,
authenticatePasskey,
detectCapabilities,
startConditionalUI,
} from '@rspace/encryptid';
key-derivation.ts
Cryptographic key derivation using WebCrypto API.
import {
getKeyManager,
encryptData,
decryptData,
signData,
verifySignature,
} from '@rspace/encryptid';
session.ts
Session management with authentication levels.
import {
getSessionManager,
AuthLevel,
canPerformOperation,
} from '@rspace/encryptid';
recovery.ts
Social recovery with guardians (no seed phrases!).
import {
getRecoveryManager,
GuardianType,
} from '@rspace/encryptid';
Social Recovery
EncryptID uses guardian-based recovery instead of seed phrases:
-
Add Guardians - Choose 5 trusted entities:
- Secondary passkey (backup device)
- Trusted contacts (friends/family with EncryptID)
- Hardware key (offline backup)
- Institutional guardian (service provider)
-
Recovery Threshold - Require 3 of 5 guardians to approve
-
Time-Lock - 48-hour delay before recovery completes (you can cancel)
-
Privacy - Guardians don't know each other's identities
const recovery = getRecoveryManager();
// Add a guardian
await recovery.addGuardian({
type: GuardianType.TRUSTED_CONTACT,
name: "Alice",
weight: 1,
contactEmail: "alice@example.com",
});
// Initiate recovery (if device lost)
const request = await recovery.initiateRecovery(newCredentialId);
// Guardian approves
await recovery.approveRecovery(guardianId, signature);
// Complete after time-lock
await recovery.completeRecovery();
Security Levels
Operations require different authentication levels:
| Level | Description | Example Operations |
|---|---|---|
| BASIC | Session token only | View public content |
| STANDARD | Recent WebAuthn (15 min) | Edit boards, upload files |
| ELEVATED | Fresh WebAuthn (1 min) | Sign votes, approve transactions |
| CRITICAL | Fresh + explicit consent | Add guardians, export keys |
const session = getSessionManager();
// Check if operation is allowed
const { allowed, reason } = session.canPerform('rvote:cast-vote');
if (!allowed) {
// Re-authenticate for elevated access
await authenticatePasskey();
session.upgradeAuthLevel(AuthLevel.ELEVATED);
}
Cross-App SSO
EncryptID uses Related Origin Requests to share passkeys across r-ecosystem domains.
Configuration at https://encryptid.online/.well-known/webauthn:
{
"origins": [
"https://rspace.online",
"https://rwallet.online",
"https://rvote.online",
"https://rmaps.online",
"https://rfiles.online"
]
}
Browser Support
| Feature | Chrome | Safari | Firefox | Edge |
|---|---|---|---|---|
| WebAuthn | ✅ | ✅ | ✅ | ✅ |
| Discoverable Credentials | ✅ | ✅ | ✅ | ✅ |
| PRF Extension | ✅ | ✅ | ❌ | ✅ |
| Related Origins | ✅ | ✅ | ❌ | ✅ |
| Conditional UI | ✅ | ✅ | ⚠️ | ✅ |
For browsers without PRF support, EncryptID falls back to passphrase-based key derivation.
Events
Login button component emits events:
const button = document.querySelector('encryptid-login');
button.addEventListener('login-success', (e) => {
console.log('Logged in:', e.detail.did);
});
button.addEventListener('login-error', (e) => {
console.error('Login failed:', e.detail.error);
});
button.addEventListener('logout', () => {
console.log('User logged out');
});
Guardian setup component emits events:
const setup = document.querySelector('encryptid-guardian-setup');
setup.addEventListener('guardian-added', (e) => {
console.log('Guardian added:', e.detail.name);
});
setup.addEventListener('guardian-removed', (e) => {
console.log('Guardian removed:', e.detail.id);
});
Development
# Install dependencies
bun install
# Run demo
bun run dev
# Build
bun run build
# Test
bun test
License
MIT