Skip to content

Security & Crypto

The server is a dumb blob store. It stores ciphertext, wrapped keys, and metadata. It never receives:

  • Plaintext secrets
  • AES keys
  • Private keys
  • Unwrapped key material

A compromised server leaks nothing usable. An attacker would need both the ciphertext (from the server) and a victim’s SSH private key (from their machine) to decrypt anything.

PurposeAlgorithm
Bulk encryptionAES-256-GCM
Key wrappingECDH (X25519) + HKDF + AES-256-GCM
Key exchangeEd25519 → X25519 conversion
Key derivationHKDF-SHA256
Nonces12 bytes, cryptographically random
ChecksumsSHA-256
Auth tokensHMAC-SHA256 (JWT)
Machine authEd25519 signatures

Hardcoded, never configurable:

  • Salt: envsh-v1
  • Info: aes-key-wrap

Every push generates a new random AES-256 key. Keys are never reused across pushes.

GCM nonces are always 12 bytes from crypto/rand. Never counter-based.

AES keys are zeroed from memory immediately after use (encrypt or decrypt).

The audit_log table does not allow UPDATE or DELETE. All actions are recorded permanently.

Every push includes base_version. The server uses SELECT ... FOR UPDATE to prevent concurrent overwrites.

envsh-machine-v1:base64(Ed25519_private_key)

The prefix envsh-machine-v1: identifies the key format. The base64 payload is the raw Ed25519 private key (64 bytes).

  1. User submits email → server sends 6-digit code (5-minute TTL)
  2. User submits code → server issues JWT (24h) + refresh token (30d, single-use)
  3. Code is stored as SHA-256 hash in Redis
  4. 3 attempts per code, 10 failures per hour triggers 1-hour lockout
  1. CLI sends machine ID → server returns 32-byte nonce (30-second TTL)
  2. CLI signs nonce with Ed25519 private key
  3. Server verifies signature against stored public key
  4. Server issues JWT (15 minutes, non-refreshable)
ThreatMitigated?How
Server compromiseYesServer only has ciphertext
Database dumpYesAll secrets encrypted, keys wrapped
Man-in-the-middleYesTLS + GCM authentication
Stolen SSH keyPartialAttacker needs ciphertext too (from server)
Brute-force loginYesRate limits + lockout
Replay attacksYesSingle-use nonces, JWT expiry
Version overwritesYesConflict detection with FOR UPDATE

The cryptographic library (pkg/crypto/) is MIT-licensed and open for audit. The server is AGPL-3.0.