Security

Threat model, cryptographic primitives, and production hardening checklist.

Threat Model

ThreatMitigation
Brute-force PINArgon2id hashing (slow by design)
Replay attacksRedis idempotency keys (1-hour TTL)
Webhook forgeryConstant-time secret comparison
IP spoofingX-Forwarded-For only honored from trusted proxies
Double-creditAtomic order state transitions
Key compromiseAES-256-GCM encryption at rest
Timing attackssubtle crate for all secret comparisons

Cryptography

Wallet Key Derivation

HKDF-SHA256 from master seed + phone number → deterministic ed25519 keypair

Encryption at Rest

AES-256-GCM with 12-byte random nonce per record. Key from WALLET_ENCRYPTION_KEY env var.

PIN Hashing

Argon2id — memory-hard, resistant to GPU and ASIC attacks. 4-digit PINs only.

Secret Comparisons

All authentication checks use the subtle crate for constant-time comparison.

Production Checklist

Before deploying to mainnet:

  • ☐ENVIRONMENT=production
  • ☐WEBHOOK_SECRET — strong random value
  • ☐INTERNAL_API_KEY — strong random value
  • ☐WALLET_MASTER_SEED — backed up offline, encrypted
  • ☐WALLET_ENCRYPTION_KEY — backed up separately from master seed
  • ☐FEE_PAYER_SECRET — funded mainnet account
  • ☐DATABASE_SSL=true
  • ☐TLS at reverse proxy (Caddy / nginx / ALB)
  • ☐TRUSTED_PROXY_IPS set to proxy IP only
  • ☐AT_ALLOWED_IPS set to Africa's Talking production IPs
  • ☐STELLAR_HORIZON_URL → mainnet Horizon
  • ☐STELLAR_NETWORK_PASSPHRASE → mainnet passphrase
  • ☐USDC_ISSUER → mainnet Circle USDC issuer
  • ☐Security audit of wallet derivation and transaction signing
  • ☐Monitoring on failed transactions and refund failures