User → Entry-Hub → Security-Switch → Database-Vault

- Client sends HTTPS request to Entry-Hub
- Entry-Hub validates and forwards request via mTLS to Security-Switch
- Security-Switch validates (defense-in-depth) and forwards via mTLS to Database-Vault
- Database-Vault validates (defense-in-depth), encrypts, stores, and responds
- Response returns back:
Database-Vault → Security-Switch → Entry-Hub → Client
- Load configuration: HTTPS server certificates, mTLS client certs for Security-Switch
- Validate configuration: check certificate files exist, validate cert/key pairs, test Security-Switch connectivity
- Configure HTTPS server: TLS server for external clients
- Configure mTLS client: certificates for communicating with Security-Switch
- Start HTTPS server on port 8443: accept TLS clients
- Receive HTTPS request: from external client (curl, app, etc.)
- Validate HTTP method: accept POST only
- Read request body: JSON with email, password, SSH key
- Parse JSON: convert into
RegisterRequeststruct
- Validate required fields: email, password, SSH key present
- Validate email format: RFC 5322 compliant
- Validate password length: minimum 8 characters
- Check for weak passwords: common password dictionary check
- Validate password complexity: at least 3 character categories
- Validate SSH key format: algorithm, encoding, wire format structure
- Initialize mTLS client: certificates for Security-Switch
- Certificate validation: verify Security-Switch certificate chain, check organization="SecuritySwitch"
- Create mTLS request: POST to Security-Switch
/api/register - Send via mTLS: authenticated connection to Security-Switch
- Receive response: success/error from Security-Switch
- Log operation: audit trail
- Forward response: HTTP status + JSON message to original client
- Error handling: HTTP 400 (validation), 401 (auth), 500 (internal), 502 (bad gateway), 503 (service unavailable)
- Error categorization: detailed logs vs sanitized client messages
- Load configuration: mTLS server certificates, mTLS client certs for Database-Vault
- Validate configuration: check certificate files exist, validate cert/key pairs.
- Configure mTLS server: accept only authenticated Entry-Hub connections
- Configure mTLS client: certificates for communicating with Database-Vault
- Start mTLS server on port 8444: certificate-only connections
- Verify mTLS: check Entry-Hub certificate (middleware)
- Certificate validation: verify certificate chain, CA validation, check organization = "EntryHub"
- Authentication logging: log successful/failed authentication attempts with certificate details
- Validate HTTP method: accept POST only
- Read request body: JSON with email, password, SSH key
- Parse JSON: convert into
RegisterRequeststruct
- Validate required fields: email, password, SSH key present
- Validate email format: RFC 5322 + security checks
- Validate password length: minimum 8 characters
- Check for weak passwords: common password dictionary check
- Validate password complexity: at least 3 character categories
- Validate SSH key format: algorithm, encoding, wire format structure
- Initialize mTLS client: certificates for Database-Vault
- Certificate validation: verify Database-Vault certificate chain, check organization="DatabaseVault"
- Create mTLS request: POST to Database-Vault
/api/store-user - Send via mTLS: authenticated connection to Database-Vault
- Receive response: success/error from Database-Vault
- Log operation: audit trail
- Forward response: HTTP status + JSON message to Entry-Hub
- Error handling: HTTP 400 (validation), 401 (auth), 403 (forbidden), 500 (internal), 502 (bad gateway), 504 (gateway timeout)
- Error categorization: detailed internal logs vs sanitized upstream messages
- Load configuration: mTLS certificates, encryption key, database URL
- Validate configuration: check certificate files exist, validate cert/key pairs
- Validate encryption key: check AES-256 key from environment variable
- Key validation: ensure 32-byte length, entropy check, format verification
- Mask database credentials in logs: hide username/password, preserve host/port/database for debugging
- Configure mTLS server: certificates to accept only Security-Switch
- Start mTLS server on port 8445: authenticated connections only
- Verify mTLS: check Security-Switch certificate (middleware)
- Certificate validation: verify certificate chain, CA validation, check organization="SecuritySwitch"
- Authentication logging: log successful/failed authentication attempts with certificate details
- Validate HTTP method: accept POST only
- Read request body: JSON with email, password, SSH key
- Parse JSON: convert into
RegisterRequeststruct
- Validate required fields: email, password, SSH key present
- Validate email format: RFC 5322 compliant
- Validate password length: minimum 8 characters
- Check for weak passwords: common password dictionary check
- Validate password complexity: at least 3 character categories
- Validate SSH key format: algorithm, encoding, wire format structure
- Hash email: SHA-256 hash for fast database indexing and primary key functionality
- Encrypt email: AES-256-GCM secure encryption with random salt and nonce
- Email encryption process: random salt + random nonce = different output for same email
- Key derivation ensures: unique encryption per user while maintaining decryption capability
- Generate password salt: 16 bytes cryptographically secure random
- Hash password: Argon2id with generated salt
- Password hashing parameters: 1 iteration, 32MB memory, 4 threads, 32-byte output
- Check for duplicate email hash: query with SHA-256 email hash
- Duplicate detection: email hash enables exact match queries without exposing emails
- Check for duplicate SSH key: query with SSH public key
- Create user record: encrypted email, password hash, salt, SSH key, timestamps
- User record structure: email_hash (PK), encrypted_email, email_salt, password_hash, password_salt, ssh_public_key, created_at, updated_at
- Save in database: atomic transaction
- Storage transaction: ensure complete user record creation or rollback
- Log operation: audit trail with timestamp
- Audit logging: record SHA-256 email hash for zero-knowledge identification and operation status
- Send response: HTTP 201 Created + JSON success message to Security-Switch
- Error handling: HTTP 400 (validation), 401 (auth), 403 (forbidden), 409 (conflict), 500 (internal), 503 (database unavailable)
- Error categorization: detailed storage errors vs sanitized upstream messages
Database-Vault implements non-deterministic email encryption using AES-256-GCM with unique keys per user email, ensuring identical email addresses produce completely different ciphertext across users.
- Source:
RAMUSB_ENCRYPTION_KEYenvironment variable (64 hex characters = 32 bytes) - Algorithm: AES-256 master key for cryptographic operations
- Validation: 32-byte length enforcement, entropy checks, secure format verification
- Generation:
openssl rand -hex 32for production deployment
Each email address gets a unique encryption key through this secure process:
-
Random Salt Generation
- 16 bytes cryptographically secure random
- Unique salt per user email
-
Key Derivation (HKDF-SHA256)
- Input: masterKey (32 bytes) + salt (16 bytes) + context string
- Context:
"email-encryption-secure-v1"for operation separation - Output: 32-byte AES-256 key unique to this email
-
Random Nonce Generation
- 12 bytes for AES-GCM mode
- Random nonce per encryption operation
Input: email address + master key
- Generate random salt (16 bytes)
- Derive unique key using HKDF-SHA256(masterKey, salt, context)
- Generate random nonce (12 bytes)
- Encrypt with AES-256-GCM
- Combine: nonce + ciphertext + authentication tag
- Encode as base64 for database storage
- Store encrypted email (base64) and salt (hex) in database
Output: Different ciphertext every time, even for identical emails
Input: encrypted email (base64) + salt (hex) + master key
- Decode salt from hex to bytes
- Reproduce the same encryption key using HKDF-SHA256(masterKey, salt, context)
- Decode ciphertext from base64 to bytes
- Extract nonce from first 12 bytes of ciphertext
- Extract encrypted data from remaining bytes
- Decrypt with AES-256-GCM using reproduced key and extracted nonce
- Verify authentication tag (automatic in GCM mode)
Output: Original email address or authentication failure
- Same Email, Different Output: Identical emails across users produce completely different ciphertext
- Random Salt Per User: Each user gets unique encryption key even for same email
- Random Nonce Per Operation: Additional randomness prevents pattern analysis
- Confidentiality: AES-256 encryption prevents plaintext email exposure
- Authenticity: GCM authentication tag prevents tampering and forgery
- Forward Secrecy: Derived keys not stored; regenerated from salt when needed
- Zero-Knowledge: Only master key is the critical secret component
- Fast Indexing: SHA-256 email hash enables database queries without decryption
- Master Key: Single point of secret (environment variable only)
- Derived Keys: Generated on-demand, never permanently stored
- Salt Storage: Safe to store in database (used for key derivation during decryption)
- Context Separation: Different operations use different context strings
- Memory Cleanup: Sensitive key material cleared after cryptographic operations
- Entry-Hub accepts clients: any (external clients in the Tailscal private network)
- Security-Switch accepts clients: organization =
"EntryHub"only - Database-Vault accepts clients: organization =
"SecuritySwitch"only
- Master key source:
RAMUSB_ENCRYPTION_KEYenvironment variable (64 hex chars = 32 bytes) - Key derivation: HKDF-SHA256 for operation-specific keys
- Context strings: prevent key reuse across different operations
- SHA-256 email hashing: enables fast database lookup without exposing email content
- Non-deterministic email encryption: provides maximum security with random salt per user
- HTTP 400: validation errors (bad input)
- HTTP 401: authentication errors (missing/invalid certificates)
- HTTP 403: authorization errors (wrong organization)
- HTTP 409: conflict errors (duplicate email/SSH key)
- HTTP 500: internal server errors
- HTTP 502: upstream service errors
- HTTP 503: service unavailable (database down)
- HTTP 504: upstream timeout errors
- Hashing: Argon2id (memory-hard, GPU-resistant)
- Salt: 16 bytes random per user
- Parameters: 1 iteration, 32MB memory, 4 threads
- Weak password check: dictionary-based validation
- Complexity: minimum 3 of 4 character categories
- Supported algorithms: ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256/384/521
- Wire format validation: algorithm consistency, base64 structure, length validation
- Security: prevent malformed keys, algorithm substitution attacks