Why
KeySecure whitelists the caller's egress IP. Staging (holapc) shares a dynamic ISP IP with the office, so every IP change (latest: 116.101.186.4 on 2026-10-27) breaks all card calls with 1003. A static-IP VPS (185.215.180.97) now runs tinyproxy (basic auth, CONNECT only to the KeySecure hosts on 443), whitelisted in sandbox-payconsole.
What
- New optional env
KEYSECURE_PROXY_URL. When set, only the KeySecure module'sHttpModuleusesHttpsProxyAgentwithproxy: false; Fireblocks/Sumsub/Airwallex are untouched. Unset = unchanged behaviour. - URL validated at startup; the error never echoes credentials.
- Every KeySecure request (client, token store, simulator) carries a per-request
AbortSignal.timeout(timeoutMs), so a hung proxy CONNECT cannot outliveKEYSECURE_TIMEOUT_MS;ERR_CANCELEDmaps totimeout(writes stay outcome-unknown). - Tests: options, config validation, module wiring, a never-answering proxy, and the Proxy-Authorization header on the CONNECT wire. Each mutation-checked.
Verification
-
yarn jest src/modules/keysecure: 417 passed, 2 skipped;yarn buildOK. - Manual: token call via the proxy from holapc returns
code 0; direct call still 403 for 116.101.186.4. - Opus review gate: PASS after 2 rounds (2 accepted NITs: free-form
http://base URL would bypass the agent; no signal test at token store/simulator).
Staging moanapay/staging/app-env already has KEYSECURE_PROXY_URL.