For the complete documentation index, see llms.txt. This page is also available as Markdown.

Encryption & Key Management

AES-256-GCM encryption and AWS KMS key management


Data at Rest

All sensitive data stored by the platform is encrypted using AES-256-GCM:

  • API response payloads for dashboard sessions are encrypted end-to-end with a per-session derived key

  • Session keys are derived as HMAC-SHA256(masterKey, userId:sessionId) — each session gets a unique key

  • Rotating the master encryption key immediately invalidates all active sessions

Data in Transit

All API traffic uses TLS 1.2+. There are no unencrypted endpoints.

Incoming webhooks (from payment networks) are verified using RSA-SHA256 signature validation against published public keys. Requests with missing or invalid signatures are rejected and logged.


API Key Storage

API keys are never stored in plaintext. Only the SHA-256 hash of each key is persisted in MongoDB:

  • SHA-256 is appropriate here (not bcrypt) because 128-bit entropy makes brute-force infeasible and enables fast O(1) indexed lookups

  • The full key is shown once at creation via the dashboard and is not recoverable afterward

  • Revocation is instant — deleting the hash record immediately blocks all requests using that key


Signing Keys (AWS KMS)

On-chain signing operations (ERC-4337 UserOps, Safe transactions) use AWS KMS with secp256k1 key material:

  • The private key is generated inside and never leaves the KMS HSM

  • All signing requests call kms.sign() — the plaintext key is never in application memory

  • The IAM role requires only kms:Sign and kms:GetPublicKey — no export permissions

  • DER-encoded ECDSA signatures are normalized (low-S) for EVM compatibility


WebAuthn Passkey Authentication

Dashboard users authenticate using WebAuthn passkeys (device biometrics or hardware security keys):

  • No passwords stored anywhere in the system

  • Private keys are generated and stored by the device's secure enclave

  • The server verifies assertions using @simplewebauthn/server — the private key never leaves the device

  • Signature counters are checked on every login to detect cloned authenticators

For high-value actions (initiating a transfer from the dashboard), a second passkey ceremony is required — generating cryptographic proof that the user physically authorized the specific action.


Session Security

Layer
Lifetime
Purpose

JWT access token

3 hours

API credential, auto-refreshed every 30 min

mw_sess httpOnly cookie

7 days

Session identity — not accessible by JavaScript

MongoDB UserSession

7 days

Server-side revocation support

Session key (in-memory)

Page load

AES key — never persisted to disk

Deleting a UserSession record from MongoDB immediately invalidates all tokens for that session, even within the 3-hour JWT lifetime.

Last updated

Was this helpful?