GUMBA
Guarded Universal Message Bundle Access
Novel proof-based access control where keys never leave the host
v1.0.0The GUMBA Insight
Traditional encrypted chat systems distribute keys to participants, creating key management nightmares and security vulnerabilities. GUMBA takes a radically different approach:
Traditional Approach
- • Keys sent to all participants
- • Key compromise = full breach
- • Complex key rotation
- • Forward secrecy challenges
GUMBA Approach
- • Keys never leave the host node
- • Access via cryptographic proofs
- • Simple membership verification
- • Automatic key rotation
Overview
GUMBA establishes protected digital spaces (bundles) where only verified members can access content. Instead of distributing encryption keys, visitors prove their membership through cryptographic proofs, and the host node serves decrypted content via secure ANNEX channels.
Architecture Components
GumbaKey
Deterministic key derivation from owner secret + bundle ID. Handles AES-256-GCM encryption with automatic nonce management.
GumbaMemberTree
SHA3-256 Merkle tree tracking members and roles. Provides O(log n) membership proofs.
GumbaProof
Three proof types for access verification: Challenge-Response, Attestation, and Merkle proofs.
GumbaGate
Access control layer that issues challenges, verifies proofs, and manages proof caching.
GumbaBundle
Encrypted message container with role-based access control and event emission.
GumbaHub
Node-level manager for multiple bundles. Handles sessions, access requests, and message delivery.
Proof Types
GUMBA supports three types of cryptographic proofs for access verification:
Challenge-Response
Most CommonThe host issues a random nonce challenge. The visitor signs it with their ML-DSA-65 (post-quantum) private key. The host verifies the signature against the visitor's registered public key.
// Host issues challenge
const challenge = hub.issueChallenge('chat-room', visitorDokoId);
// Visitor signs with their private key
const signedProof = GumbaProof.signChallenge(challenge, visitorSecretKey);
// Host verifies and grants access
const result = await hub.handleAccessRequest('chat-room', signedProof, visitorNodeId);
Attestation
DelegationAn existing member with sufficient role can vouch for a new member. This creates a signed attestation that grants the new member temporary access.
// Alice (admin) creates attestation for Bob
const attestation = GumbaProof.createAttestation({
bundleId: 'private-room',
grantorDokoId: alice.dokoId,
granteeDokoId: bob.dokoId,
grantorSecretKey: alice.secretKey,
grantedRole: GUMBA_ROLE.MEMBER,
});
// Bob uses attestation to gain access
const result = await hub.handleAccessRequest('private-room', attestation, bobNodeId);
Merkle Proof
Zero-KnowledgeProves membership using a Merkle tree path without revealing the full member list. Useful for privacy-preserving access where member identities should remain hidden.
// Create membership proof
const merkleProof = GumbaProof.createMerkleProof(alice.dokoId, bundle.memberTree);
// Verify membership without exposing other members
const verified = GumbaProof.verifyMerkleProof(merkleProof, bundle.memberTree.getRoot());
Role Hierarchy
GUMBA uses a hierarchical role system where higher roles can grant access to lower roles:
Full control
Manage members
Post messages
Read only
| Role | Permissions |
|---|---|
| OWNER | Full control, cannot be removed, can add/remove any role |
| ADMIN | Can add/remove members up to MEMBER role, post messages |
| MEMBER | Can post messages, can attest readers |
| READER | Read-only access to messages |
Security Features
Replay Protection
Challenge nonces are single-use. Each challenge is removed from the pending pool after verification, preventing replay attacks.
Post-Quantum Signatures
All signatures use ML-DSA-65 (Dilithium), a NIST-approved post-quantum signature algorithm.
Automatic Key Rotation
Bundle keys automatically rotate after a configurable message count, limiting the impact of any potential key compromise.
Session Expiry
Cached access automatically expires. Expired sessions are cleaned up to prevent stale access.
Revocation
Member removal immediately clears proof cache. Revoked members must re-authenticate (and will fail).
Self-Custody
Keys never leave your node. Your messages stay on YOUR hardware. True digital sovereignty.
Access Flow
┌─────────────────┐ ┌─────────────────┐
│ Visitor Node │ │ Host Node │
│ (has DOKO key) │ │ (has bundle) │
└────────┬────────┘ └────────┬────────┘
│ │
│ 1. Request access to bundle │
│ ─────────────────────────────────────────────> │
│ │
│ 2. Issue challenge (random nonce) │
│ <───────────────────────────────────────────── │
│ │
│ 3. Sign challenge with DOKO private key │
│ ─────────────────────────────────────────────> │
│ │
│ 4. Verify signature, check membership │
│ ┌───────────┴───────────┐
│ │ • Verify ML-DSA-65 sig │
│ │ • Check member tree │
│ │ • Create session │
│ └───────────┬───────────┘
│ │
│ 5. Grant access + session token │
│ <───────────────────────────────────────────── │
│ │
│ 6. Request messages (with session) │
│ ─────────────────────────────────────────────> │
│ │
│ 7. Decrypt & deliver via ANNEX │
│ <───────────────────────────────────────────── │
│ │
Quick Start
import { GumbaHub, GumbaProof, GUMBA_ROLE } from 'yakmesh/mesh/gumba.js';
// Create hub with node identity
const hub = new GumbaHub(nodeIdentity, annexInstance);
// Create a bundle (encrypted chat room)
hub.createBundle('team-chat', { name: 'Team Chat Room' });
// Add members
const bundle = hub.getBundle('team-chat');
bundle.addMember(aliceDokoId, GUMBA_ROLE.ADMIN, ownerDokoId);
bundle.addMember(bobDokoId, GUMBA_ROLE.MEMBER, ownerDokoId);
// Register public keys (for verification)
hub.registerPublicKey(aliceDokoId, alicePublicKey);
hub.registerPublicKey(bobDokoId, bobPublicKey);
// Handle access request from visitor
const challenge = hub.issueChallenge('team-chat', visitorDokoId);
// ... visitor signs challenge ...
const access = await hub.handleAccessRequest('team-chat', signedProof, visitorNodeId);
if (access.granted) {
// Get messages for this session
const messages = await hub.getMessages(access.sessionId);
// Post a message
await hub.postMessage(access.sessionId, { text: 'Hello team!' });
}
Configuration
// Default GUMBA configuration
const GUMBA_CONFIG = {
keyRotationThreshold: 10000, // Rotate key after N messages
proofCacheTime: 5 * 60 * 1000, // 5 minutes cache
challengeExpiry: 60 * 1000, // 1 minute challenge validity
attestationMaxAge: 24 * 60 * 60 * 1000, // 24 hour attestation validity
};
Use Cases
Private Chat Rooms
Replace Discord/Slack with self-hosted, post-quantum secure chat. No facial recognition, no central authority.
Secure File Sharing
Share sensitive documents with verified team members. Files never leave your control until access is proven.
Team Collaboration
Role-based access for different team levels. Admins manage members, members contribute, readers observe.
Whistleblower Channels
Anonymous access via Merkle proofs. Prove you belong without revealing your identity to other members.