Follow-up to #652. PR #659 addressed the highest-value items — at-rest KDF (scrypt + AES-256-GCM), loopback-by-default bind, opt-in API token, rate-limit loopback allow-list + ban, and /docs gating. This issue tracks the remaining hardening that was intentionally left out of that PR to keep it focused and reviewable.
1. Remove the networked private-key export from the HTTP API (#652 §1, remainder)
A "reveal raw private key" endpoint should never be reachable over the network, even when authenticated. Make it a CLI / localhost-only operation (a script that reads the encrypted store locally), or hard-restrict it to loopback and the API token. Pulling key export off the wire is the single highest-impact route to remove.
2. Per-route strict rate-limit + credential-keyed lockout (#652 §2, remainder)
PR #659 added a global, loopback-allow-listed limiter with ban. Auth-gated fund-moving routes should additionally carry tighter per-route limits (e.g. 3–5 attempts / 15 min) with exponential backoff/lockout. Note: 2025–2026 credential-stuffing bots rotate IPs/fingerprints, so lockout keyed only on source IP is weak — consider keying on the credential/identity as well.
3. Passphrase rotation without re-encrypting every wallet (KEK/DEK)
Today the Gateway passphrase is used directly as the encryption key for every keystore, so rotating it requires decrypting and re-encrypting every wallet. The standard fix is a random per-Gateway data-encryption key (DEK) wrapped by a passphrase-derived key-encryption key (KEK): rotating the passphrase then only re-wraps the DEK, not each wallet — and makes passphrase rotation a clean first-class operation.
4. Optional mTLS for networked deployments
For genuinely multi-client / networked setups, mutual TLS is stronger than a shared bearer token. Lower priority than the above for the single-user local case.
Notes
Refs: #652, #659
Follow-up to #652. PR #659 addressed the highest-value items — at-rest KDF (scrypt + AES-256-GCM), loopback-by-default bind, opt-in API token, rate-limit loopback allow-list + ban, and
/docsgating. This issue tracks the remaining hardening that was intentionally left out of that PR to keep it focused and reviewable.1. Remove the networked private-key export from the HTTP API (#652 §1, remainder)
A "reveal raw private key" endpoint should never be reachable over the network, even when authenticated. Make it a CLI / localhost-only operation (a script that reads the encrypted store locally), or hard-restrict it to loopback and the API token. Pulling key export off the wire is the single highest-impact route to remove.
2. Per-route strict rate-limit + credential-keyed lockout (#652 §2, remainder)
PR #659 added a global, loopback-allow-listed limiter with
ban. Auth-gated fund-moving routes should additionally carry tighter per-route limits (e.g. 3–5 attempts / 15 min) with exponential backoff/lockout. Note: 2025–2026 credential-stuffing bots rotate IPs/fingerprints, so lockout keyed only on source IP is weak — consider keying on the credential/identity as well.3. Passphrase rotation without re-encrypting every wallet (KEK/DEK)
Today the Gateway passphrase is used directly as the encryption key for every keystore, so rotating it requires decrypting and re-encrypting every wallet. The standard fix is a random per-Gateway data-encryption key (DEK) wrapped by a passphrase-derived key-encryption key (KEK): rotating the passphrase then only re-wraps the DEK, not each wallet — and makes passphrase rotation a clean first-class operation.
4. Optional mTLS for networked deployments
For genuinely multi-client / networked setups, mutual TLS is stronger than a shared bearer token. Lower priority than the above for the single-user local case.
Notes
docs/security-hardening.md(added in fix / harden Gateway wallet security — at-rest KDF, loopback bind, opt-in API auth, rate-limiting (#652) #659).Refs: #652, #659