-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Summary
Replace the custom certificate/key management system with GunDB SEA (Security, Encryption, Authorization) for cryptographic identity. Keep Google OAuth for user authentication and Calendar integration, with the server acting as a trusted bridge linking Google identity to SEA keypairs.
Motivation
- Simplify codebase: Remove ~400 lines of custom crypto code
- Use battle-tested crypto: SEA uses native Web Crypto API (ECDSA, PBKDF2, AES)
- Built-in verification: Peers automatically verify signatures - no custom certificate checking
- Public-read, user-only-write: SEA's
gun.user()provides this pattern natively - Future-proof: Clear path to fully decentralized auth later
Architecture
┌─────────────┐ ┌─────────────────────────┐ ┌─────────────┐
│ Browser │────▶│ Express Server │────▶│ Google │
│ │ │ │ │ OAuth │
│ 1. OAuth │ │ 1. Verify Google auth │ └─────────────┘
│ 2. Get seed│◀────│ 2. Generate signed seed│
│ 3. Derive │ │ 3. Calendar API proxy │
│ SEA keys│ │ │
│ 4. gun.user│ └───────────┬─────────────┘
│ .auth() │ │
└──────┬──────┘ │
│ │
▼ ▼
┌─────────────────────────────────────────────┐
│ GunDB P2P Network │
│ │
│ - Topics stored in user space (~pubkey) │
│ - All writes cryptographically signed │
│ - Peers verify signatures automatically │
│ - Public discovery graph for topic listing │
└─────────────────────────────────────────────┘
How It Works
Server-Side Seed Generation
The server generates a deterministic seed using HMAC:
// New endpoint: /auth/sea-seed
const seed = HMAC(SEA_SECRET, googleUserId);
res.json({ seed });- Same Google user always gets the same seed → same SEA keypair
- Server secret required for seed generation (trusted bridge)
- Enables future key rotation by versioning seeds
Client-Side SEA Authentication
// After Google OAuth callback
const { seed } = await fetch('/auth/sea-seed').then(r => r.json());
// Derive SEA keypair deterministically (using @gooddollar/gun-pk-auth)
const seaPair = genDeterministicSEAPair(seed);
// Authenticate to GunDB
const user = gun.user();
user.auth(seaPair, callback);
// user.is.pub is now the user's verified identityTopic Storage Pattern
// Create topic in user's protected space (only author can write)
user.get('topics').get(topicId).put(topicData);
// Link to public discovery graph
gun.get('public-topics').get(topicId).put({
author: user.is.pub,
title: topicData.title
});
// Others read via author's public key (automatically verified by SEA)
gun.user(authorPubKey).get('topics').get(topicId).on((data) => {
// Data is cryptographically verified
});Implementation Checklist
Phase 1: Add SEA Seed Endpoint
- Create
/auth/sea-seedendpoint inserver/routes/auth.js - Use HMAC with server secret to generate deterministic seed
- Add
SEA_SECRETto.env.example
Phase 2: Client SEA Integration
- Add
gun/sea.jsscript toclient/index.html - Add
@gooddollar/gun-pk-authfor deterministic key derivation - Create
client/js/sea-auth.jswith SEA authentication helpers - Update
client/js/app.js:- Replace
generateAndRegisterKeys()with SEA auth flow - Update
checkAuth()to use SEA session - Remove crypto.js imports
- Replace
Phase 3: Update Topic Storage Pattern
- Change topic writes to use
user.get('topics')(protected) - Add public discovery graph
gun.get('public-topics') - Update topic reads to verify via author's public key
- Update interest tracking to use SEA-signed data
Phase 4: Remove Legacy Code
- Delete
client/js/crypto.js - Delete
server/services/keyManagement.js - Delete
server/services/certificateService.js - Remove
/auth/register-keyendpoint - Remove
node-forgedependency frompackage.json - Clean up GunDB storage (certificates, publicKeys namespaces)
Phase 5: Update Documentation
- Update README with new auth flow
- Update
.env.examplewithSEA_SECRET
Files to Modify
| File | Action |
|---|---|
server/routes/auth.js |
Add /auth/sea-seed, remove /auth/register-key |
server/index.js |
Remove certificate/key service imports |
client/index.html |
Add sea.js script |
client/js/app.js |
Replace crypto flow with SEA auth |
client/js/crypto.js |
DELETE |
server/services/keyManagement.js |
DELETE |
server/services/certificateService.js |
DELETE |
package.json |
Add @gooddollar/gun-pk-auth, remove node-forge |
.env.example |
Add SEA_SECRET |
Dependencies
Add:
@gooddollar/gun-pk-auth- Deterministic SEA keypair generation from seeds
Remove:
node-forge- No longer needed for server-side crypto
Security Considerations
- SEA_SECRET must be kept secure - Compromise allows impersonation of any user
- Seed is sensitive - Transmitted over HTTPS only, never stored client-side
- Google account compromise = GunDB identity compromise - Same trust model as current system
- Key rotation - Possible by versioning seeds (e.g.,
HMAC(secret,${userId}:v2))
Future Decentralization Path
The server's role is minimal and can be removed later:
| Current (Phase 1) | Future Options |
|---|---|
| Server generates seed from Google ID | Client derives seed from Google ID directly |
| DID/Verifiable Credentials | |
| Web3 wallet signatures as seed |
The SEA-based topic storage pattern remains unchanged regardless of how the seed is generated.
References
- GunDB SEA Documentation
- GunDB Auth Documentation
- @gooddollar/gun-pk-auth - Deterministic keypair generation
- Stack Overflow: Public read / private write in GunDB
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels