diff --git a/README.md b/README.md index 83e1205..be1b82b 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ Configuration is managed through environment variables: - `BITGO_CUSTOM_BITCOIN_NETWORK` - Custom Bitcoin network (optional) - `ADVANCED_WALLET_MANAGER_URL` - Advanced Wallet Manager URL (required) - `ADVANCED_WALLET_MANAGER_CERT` - Path to Advanced Wallet Manager certificate (required) +- `AWM_SERVER_CERT_ALLOW_SELF_SIGNED` - Allow self-signed certificates from Advanced Wallet Manager (default: false) ### TLS/mTLS Configuration @@ -70,8 +71,8 @@ Both modes use the same TLS configuration variables: #### mTLS Settings (when TLS_MODE=mtls) - `MTLS_REQUEST_CERT` - Request client certificates (default: true) -- `ALLOW_SELF_SIGNED` - Allow self-signed certificates (default: false) -- `MTLS_ALLOWED_CLIENT_FINGERPRINTS` - Comma-separated list of allowed client certificate fingerprints (optional) +- `CLIENT_CERT_ALLOW_SELF_SIGNED` - Allow self-signed certificates for incoming client connections (default: false) +- `MTLS_ALLOWED_CLIENT_FINGERPRINTS` - Comma-separated list of allowed fingerprints for incoming client connections (optional) #### Outbound mTLS to KMS @@ -79,6 +80,7 @@ Both modes use the same TLS configuration variables: - The same `TLS_CERT` and `TLS_KEY` are used as the client certificate and key for outbound mTLS requests to KMS. - `KMS_TLS_CERT_PATH` - Path to the CA certificate to verify the KMS server (required when outbound mTLS is enabled). - If `TLS_MODE=disabled`, outbound mTLS to KMS is also disabled by default. +- `KMS_SERVER_CERT_ALLOW_SELF_SIGNED` - Allow self-signed certificates from the KMS (default: false) > **Note:** If you want to use a different client certificate for KMS, you will need to extend the configuration. By default, the same cert/key is used for both inbound and outbound mTLS. @@ -105,10 +107,11 @@ openssl req -new -x509 -key server.key -out server.crt -days 365 -subj "/CN=loca ```bash export APP_MODE=advanced-wallet-manager export KMS_URL=https://your-kms-service +export KMS_TLS_CERT_PATH=./server.crt +export KMS_SERVER_CERT_ALLOW_SELF_SIGNED=true export TLS_KEY_PATH=./server.key export TLS_CERT_PATH=./server.crt -export MTLS_REQUEST_CERT=true -export ALLOW_SELF_SIGNED=true +export CLIENT_CERT_ALLOW_SELF_SIGNED=true npm start ``` @@ -123,8 +126,8 @@ export TLS_KEY_PATH=./server.key export TLS_CERT_PATH=./server.crt export ADVANCED_WALLET_MANAGER_URL=https://localhost:3080 export ADVANCED_WALLET_MANAGER_CERT=./server.crt -export MTLS_REQUEST_CERT=false -export ALLOW_SELF_SIGNED=true +export AWM_SERVER_CERT_ALLOW_SELF_SIGNED=true +export CLIENT_CERT_ALLOW_SELF_SIGNED=true npm start ``` @@ -141,7 +144,7 @@ curl -k -X POST https://localhost:3081/ping/advancedWalletManager ### Security Best Practices 1. **Use CA-signed certificates** instead of self-signed -2. **Set `ALLOW_SELF_SIGNED=false`** in production +2. **Set `CLIENT_CERT_ALLOW_SELF_SIGNED=false`** in production 3. **Configure client certificate allowlisting** with `MTLS_ALLOWED_CLIENT_FINGERPRINTS` 4. **Use separate certificates** for each service 5. **Regularly rotate certificates** @@ -157,7 +160,7 @@ export KMS_URL=https://production-kms.example.com export TLS_KEY_PATH=/secure/path/advanced-wallet-manager.key export TLS_CERT_PATH=/secure/path/advanced-wallet-manager.crt export MTLS_REQUEST_CERT=true -export ALLOW_SELF_SIGNED=false +export CLIENT_CERT_ALLOW_SELF_SIGNED=false export MTLS_ALLOWED_CLIENT_FINGERPRINTS=ABC123...,DEF456... npm start ``` @@ -172,7 +175,7 @@ export TLS_CERT_PATH=/secure/path/master.crt export ADVANCED_WALLET_MANAGER_URL=https://advanced-wallet-manager.internal.example.com:3080 export ADVANCED_WALLET_MANAGER_CERT=/secure/path/advanced-wallet-manager.crt export MTLS_REQUEST_CERT=true -export ALLOW_SELF_SIGNED=false +export CLIENT_CERT_ALLOW_SELF_SIGNED=false npm start ``` @@ -202,7 +205,7 @@ podman run -d \ -e TLS_CERT_PATH=/app/certs/advanced-wallet-manager-cert.pem \ -e KMS_URL=host.containers.internal:3000 \ -e NODE_ENV=development \ - -e ALLOW_SELF_SIGNED=true \ + -e CLIENT_CERT_ALLOW_SELF_SIGNED=true \ bitgo-onprem-express # View logs @@ -222,7 +225,7 @@ podman run -d \ -e TLS_CERT_PATH=/app/certs/test-ssl-cert.pem \ -e ADVANCED_WALLET_MANAGER_URL=https://host.containers.internal:3080 \ -e ADVANCED_WALLET_MANAGER_CERT=/app/certs/advanced-wallet-manager-cert.pem \ - -e ALLOW_SELF_SIGNED=true \ + -e CLIENT_CERT_ALLOW_SELF_SIGNED=true \ bitgo-onprem-express # View logs @@ -276,7 +279,7 @@ openssl x509 -in certificate.crt -text -noout #### 2. mTLS Authentication Failures - Verify client certificates are provided -- Check `ALLOW_SELF_SIGNED` setting matches certificate type +- Check `CLIENT_CERT_ALLOW_SELF_SIGNED` setting matches certificate type - Confirm client certificate fingerprints are in allowlist - Ensure both services use compatible TLS settings diff --git a/src/__tests__/api/advancedWalletManager/kmsClient.test.ts b/src/__tests__/api/advancedWalletManager/kmsClient.test.ts index a112b4d..ea43ae7 100644 --- a/src/__tests__/api/advancedWalletManager/kmsClient.test.ts +++ b/src/__tests__/api/advancedWalletManager/kmsClient.test.ts @@ -30,7 +30,7 @@ describe('postMpcV2Key', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; // app setup diff --git a/src/__tests__/api/advancedWalletManager/mpcFinalize.test.ts b/src/__tests__/api/advancedWalletManager/mpcFinalize.test.ts index da0de60..96e0e64 100644 --- a/src/__tests__/api/advancedWalletManager/mpcFinalize.test.ts +++ b/src/__tests__/api/advancedWalletManager/mpcFinalize.test.ts @@ -29,7 +29,7 @@ describe('MPC Finalize', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; app = enclavedApp(cfg); diff --git a/src/__tests__/api/advancedWalletManager/mpcInitialize.test.ts b/src/__tests__/api/advancedWalletManager/mpcInitialize.test.ts index 20838b8..e9e1da3 100644 --- a/src/__tests__/api/advancedWalletManager/mpcInitialize.test.ts +++ b/src/__tests__/api/advancedWalletManager/mpcInitialize.test.ts @@ -30,7 +30,7 @@ describe('MPC Initialize', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; // configStub = sinon.stub(configModule, 'initConfig').returns(cfg); diff --git a/src/__tests__/api/advancedWalletManager/nonRecovery.test.ts b/src/__tests__/api/advancedWalletManager/nonRecovery.test.ts index 6574aa2..fae1d56 100644 --- a/src/__tests__/api/advancedWalletManager/nonRecovery.test.ts +++ b/src/__tests__/api/advancedWalletManager/nonRecovery.test.ts @@ -18,7 +18,7 @@ describe('Non Recovery', () => { timeout: 60000, tlsMode: TlsMode.DISABLED, httpLoggerFile: '', - allowSelfSigned: true, + clientCertAllowSelfSigned: true, kmsUrl: 'kms.example.com', }; diff --git a/src/__tests__/api/advancedWalletManager/postIndependentKey.test.ts b/src/__tests__/api/advancedWalletManager/postIndependentKey.test.ts index 731d0cc..c33a41f 100644 --- a/src/__tests__/api/advancedWalletManager/postIndependentKey.test.ts +++ b/src/__tests__/api/advancedWalletManager/postIndependentKey.test.ts @@ -36,7 +36,7 @@ describe('postIndependentKey', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; // app setup diff --git a/src/__tests__/api/advancedWalletManager/postMpcV2Key.test.ts b/src/__tests__/api/advancedWalletManager/postMpcV2Key.test.ts index 350d2cd..53b92b4 100644 --- a/src/__tests__/api/advancedWalletManager/postMpcV2Key.test.ts +++ b/src/__tests__/api/advancedWalletManager/postMpcV2Key.test.ts @@ -38,7 +38,7 @@ describe('postMpcV2Key', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; configStub = sinon.stub(configModule, 'initConfig').returns(cfg); diff --git a/src/__tests__/api/advancedWalletManager/recoveryMpcV2.test.ts b/src/__tests__/api/advancedWalletManager/recoveryMpcV2.test.ts index 8104676..e59bc17 100644 --- a/src/__tests__/api/advancedWalletManager/recoveryMpcV2.test.ts +++ b/src/__tests__/api/advancedWalletManager/recoveryMpcV2.test.ts @@ -62,7 +62,7 @@ describe('recoveryMpcV2', async () => { kmsUrl: kmsUrl, httpLoggerFile: '', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: true, }; diff --git a/src/__tests__/api/advancedWalletManager/recoveryMultisigTransaction.test.ts b/src/__tests__/api/advancedWalletManager/recoveryMultisigTransaction.test.ts index 00a4648..1b41305 100644 --- a/src/__tests__/api/advancedWalletManager/recoveryMultisigTransaction.test.ts +++ b/src/__tests__/api/advancedWalletManager/recoveryMultisigTransaction.test.ts @@ -20,7 +20,7 @@ describe('UTXO recovery', () => { timeout: 60000, httpLoggerFile: '', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, kmsUrl: 'kms.example.com', recoveryMode: true, }; diff --git a/src/__tests__/api/advancedWalletManager/recoveryMusigEth.test.ts b/src/__tests__/api/advancedWalletManager/recoveryMusigEth.test.ts index 792798d..dadd11c 100644 --- a/src/__tests__/api/advancedWalletManager/recoveryMusigEth.test.ts +++ b/src/__tests__/api/advancedWalletManager/recoveryMusigEth.test.ts @@ -39,7 +39,7 @@ describe('recoveryMultisigTransaction', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: true, }; diff --git a/src/__tests__/api/advancedWalletManager/signMpcRecoveryTransaction.test.ts b/src/__tests__/api/advancedWalletManager/signMpcRecoveryTransaction.test.ts index ae32433..74b9049 100644 --- a/src/__tests__/api/advancedWalletManager/signMpcRecoveryTransaction.test.ts +++ b/src/__tests__/api/advancedWalletManager/signMpcRecoveryTransaction.test.ts @@ -17,7 +17,7 @@ describe('EdDSA Recovery Signing', () => { timeout: 60000, httpLoggerFile: '', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: true, }; diff --git a/src/__tests__/api/advancedWalletManager/signMpcTransaction.test.ts b/src/__tests__/api/advancedWalletManager/signMpcTransaction.test.ts index 593093e..5c56791 100644 --- a/src/__tests__/api/advancedWalletManager/signMpcTransaction.test.ts +++ b/src/__tests__/api/advancedWalletManager/signMpcTransaction.test.ts @@ -43,7 +43,7 @@ describe('signMpcTransaction', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; configStub = sinon.stub(configModule, 'initConfig').returns(cfg); diff --git a/src/__tests__/api/advancedWalletManager/signMultisigTransaction.test.ts b/src/__tests__/api/advancedWalletManager/signMultisigTransaction.test.ts index 8ea556f..d4a1998 100644 --- a/src/__tests__/api/advancedWalletManager/signMultisigTransaction.test.ts +++ b/src/__tests__/api/advancedWalletManager/signMultisigTransaction.test.ts @@ -36,7 +36,7 @@ describe('signMultisigTransaction', () => { httpLoggerFile: '', kmsUrl: kmsUrl, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; configStub = sinon.stub(configModule, 'initConfig').returns(cfg); diff --git a/src/__tests__/api/master/accelerate.test.ts b/src/__tests__/api/master/accelerate.test.ts index 624279a..c848ce5 100644 --- a/src/__tests__/api/master/accelerate.test.ts +++ b/src/__tests__/api/master/accelerate.test.ts @@ -51,7 +51,7 @@ describe('POST /api/:coin/wallet/:walletId/accelerate', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'test-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; const app = expressApp(config); diff --git a/src/__tests__/api/master/consolidate.test.ts b/src/__tests__/api/master/consolidate.test.ts index 44cca87..08e0c84 100644 --- a/src/__tests__/api/master/consolidate.test.ts +++ b/src/__tests__/api/master/consolidate.test.ts @@ -55,7 +55,7 @@ describe('POST /api/:coin/wallet/:walletId/consolidate', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'test-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; const app = expressApp(config); diff --git a/src/__tests__/api/master/consolidateUnspents.test.ts b/src/__tests__/api/master/consolidateUnspents.test.ts index 708f2c0..b23aeba 100644 --- a/src/__tests__/api/master/consolidateUnspents.test.ts +++ b/src/__tests__/api/master/consolidateUnspents.test.ts @@ -51,7 +51,7 @@ describe('POST /api/:coin/wallet/:walletId/consolidateunspents', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'test-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; const app = expressApp(config); diff --git a/src/__tests__/api/master/ecdsa.test.ts b/src/__tests__/api/master/ecdsa.test.ts index f34f307..4b51869 100644 --- a/src/__tests__/api/master/ecdsa.test.ts +++ b/src/__tests__/api/master/ecdsa.test.ts @@ -47,7 +47,7 @@ describe('Ecdsa Signing Handler', () => { advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: 'disabled', - allowSelfSigned: true, + clientCertAllowSelfSigned: true, } as any, coin, ); diff --git a/src/__tests__/api/master/eddsa.test.ts b/src/__tests__/api/master/eddsa.test.ts index 19b0060..c1a46c9 100644 --- a/src/__tests__/api/master/eddsa.test.ts +++ b/src/__tests__/api/master/eddsa.test.ts @@ -42,7 +42,7 @@ describe('Eddsa Signing Handler', () => { advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: 'disabled', - allowSelfSigned: true, + clientCertAllowSelfSigned: true, } as any, coin, ); diff --git a/src/__tests__/api/master/generateWallet.test.ts b/src/__tests__/api/master/generateWallet.test.ts index 37cf53b..a98a0d3 100644 --- a/src/__tests__/api/master/generateWallet.test.ts +++ b/src/__tests__/api/master/generateWallet.test.ts @@ -50,7 +50,7 @@ describe('POST /api/:coin/wallet/generate', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; // Setup middleware stubs before creating app @@ -1141,7 +1141,7 @@ describe('POST /api/:coin/wallet/generate', () => { disableEnvCheck: true, authVersion: 2, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; try { diff --git a/src/__tests__/api/master/musigRecovery.test.ts b/src/__tests__/api/master/musigRecovery.test.ts index b046861..5d8ea0a 100644 --- a/src/__tests__/api/master/musigRecovery.test.ts +++ b/src/__tests__/api/master/musigRecovery.test.ts @@ -30,7 +30,7 @@ describe('POST /api/:coin/wallet/recovery', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: true, }; diff --git a/src/__tests__/api/master/nonRecovery.test.ts b/src/__tests__/api/master/nonRecovery.test.ts index 8bd6884..c5038b3 100644 --- a/src/__tests__/api/master/nonRecovery.test.ts +++ b/src/__tests__/api/master/nonRecovery.test.ts @@ -27,7 +27,7 @@ describe('Non Recovery Tests', () => { advancedWalletManagerCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, httpLoggerFile: '', - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: false, }; diff --git a/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts b/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts index 4b8f4e5..bd9e149 100644 --- a/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts +++ b/src/__tests__/api/master/recoveryConsolidationsWallet.test.ts @@ -37,7 +37,7 @@ describe('POST /api/:coin/wallet/recoveryconsolidations', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'test-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: true, }; const app = expressApp(config); diff --git a/src/__tests__/api/master/recoveryWallet.test.ts b/src/__tests__/api/master/recoveryWallet.test.ts index 8329cb3..16d30b6 100644 --- a/src/__tests__/api/master/recoveryWallet.test.ts +++ b/src/__tests__/api/master/recoveryWallet.test.ts @@ -29,7 +29,7 @@ describe('Recovery Tests', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: true, }; diff --git a/src/__tests__/api/master/recoveryWalletMpcV2.test.ts b/src/__tests__/api/master/recoveryWalletMpcV2.test.ts index b377363..cc65e36 100644 --- a/src/__tests__/api/master/recoveryWalletMpcV2.test.ts +++ b/src/__tests__/api/master/recoveryWalletMpcV2.test.ts @@ -36,7 +36,7 @@ describe('MBE mpcv2 recovery', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, recoveryMode: true, }; diff --git a/src/__tests__/api/master/sendMany.test.ts b/src/__tests__/api/master/sendMany.test.ts index 9d99e75..ee5417a 100644 --- a/src/__tests__/api/master/sendMany.test.ts +++ b/src/__tests__/api/master/sendMany.test.ts @@ -33,7 +33,7 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; const app = expressApp(config); @@ -584,7 +584,7 @@ describe('POST /api/:coin/wallet/:walletId/sendmany', () => { disableEnvCheck: true, authVersion: 2, tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; try { diff --git a/src/__tests__/api/master/signAndSendTxRequest.test.ts b/src/__tests__/api/master/signAndSendTxRequest.test.ts index 00dbb7a..8906a59 100644 --- a/src/__tests__/api/master/signAndSendTxRequest.test.ts +++ b/src/__tests__/api/master/signAndSendTxRequest.test.ts @@ -56,7 +56,7 @@ describe('POST /api/:coin/wallet/:walletId/txrequest/:txRequestId/signAndSend', advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: 'dummy-cert', tlsMode: TlsMode.DISABLED, - allowSelfSigned: true, + clientCertAllowSelfSigned: true, }; const app = expressApp(config); diff --git a/src/__tests__/routes.test.ts b/src/__tests__/routes.test.ts index c9f5f94..23b3acd 100644 --- a/src/__tests__/routes.test.ts +++ b/src/__tests__/routes.test.ts @@ -13,7 +13,7 @@ describe('Routes', () => { setupRoutes(app, { appMode: AppMode.ADVANCED_WALLET_MANAGER, httpLoggerFile: '', - allowSelfSigned: true, + clientCertAllowSelfSigned: true, tlsMode: TlsMode.DISABLED, kmsUrl: 'http://localhost:3000/kms', timeout: 5000, diff --git a/src/advancedWalletManagerApp.ts b/src/advancedWalletManagerApp.ts index 8bb24f4..f4115c9 100644 --- a/src/advancedWalletManagerApp.ts +++ b/src/advancedWalletManagerApp.ts @@ -30,7 +30,7 @@ export function startup(config: AdvancedWalletManagerConfig, baseUri: string): ( logger.info('Advanced Wallet Manager starting...'); logger.info(`Base URI: ${baseUri}`); logger.info(`mTLS Mode: ${config.tlsMode}`); - logger.info(`Allow Self-Signed Certificates: ${config.allowSelfSigned}`); + logger.info(`Allow Self-Signed Certificates: ${config.clientCertAllowSelfSigned}`); logger.info(`Port: ${config.port}`); logger.info(`Bind: ${config.bind}`); logger.info(`KMS URL: ${config.kmsUrl}`); diff --git a/src/api/master/clients/advancedWalletManagerClient.ts b/src/api/master/clients/advancedWalletManagerClient.ts index b3b2c6b..551359e 100644 --- a/src/api/master/clients/advancedWalletManagerClient.ts +++ b/src/api/master/clients/advancedWalletManagerClient.ts @@ -227,7 +227,7 @@ export class AdvancedWalletManagerClient { private readonly advancedWalletManagerCert: string; private readonly tlsKey?: string; private readonly tlsCert?: string; - private readonly allowSelfSigned: boolean; + private readonly awmServerCertAllowSelfSigned: boolean; private readonly coin?: string; private readonly tlsMode: TlsMode; @@ -239,16 +239,18 @@ export class AdvancedWalletManagerClient { } if ( cfg.tlsMode === TlsMode.MTLS && - (!cfg.tlsKey || !cfg.tlsCert || !cfg.advancedWalletManagerUrl) + (!cfg.tlsKey || !cfg.tlsCert || !cfg.advancedWalletManagerCert) ) { - throw new Error('tlsKey and tlsCert are required for mTLS communication'); + throw new Error( + 'tlsKey, tlsCert and advancedWalletManagerCert are required for mTLS communication', + ); } this.baseUrl = cfg.advancedWalletManagerUrl; - this.advancedWalletManagerCert = cfg.advancedWalletManagerCert; + this.advancedWalletManagerCert = cfg.advancedWalletManagerCert as string; this.tlsKey = cfg.tlsKey; this.tlsCert = cfg.tlsCert; - this.allowSelfSigned = cfg.allowSelfSigned ?? false; + this.awmServerCertAllowSelfSigned = cfg.awmServerCertAllowSelfSigned ?? false; this.coin = coin; this.tlsMode = cfg.tlsMode; @@ -258,7 +260,7 @@ export class AdvancedWalletManagerClient { // Build the type-safe API client this.apiClient = buildApiClient(requestFactory, AdvancedWalletManagerApiSpec); - logger.info('EnclavedExpressClient initialized with URL: %s', this.baseUrl); + logger.info('Advanced Wallet Manager initialized with URL: %s', this.baseUrl); } private createHttpsAgent(): https.Agent { @@ -266,7 +268,7 @@ export class AdvancedWalletManagerClient { throw new Error('TLS key and certificate are required for HTTPS agent'); } return new https.Agent({ - rejectUnauthorized: !this.allowSelfSigned, + rejectUnauthorized: !this.awmServerCertAllowSelfSigned, ca: this.advancedWalletManagerCert, // Use Master Express's own certificate as client cert when connecting to Advanced Wallet Manager key: this.tlsKey, @@ -342,7 +344,7 @@ export class AdvancedWalletManagerClient { */ async ping(): Promise { try { - logger.info('Pinging enclaved express service at: %s', this.baseUrl); + logger.info('Pinging Advanced Wallet Manager at: %s', this.baseUrl); let request = this.apiClient['v1.health.ping'].post({}); if (this.tlsMode === TlsMode.MTLS) { @@ -351,11 +353,11 @@ export class AdvancedWalletManagerClient { const response = await request.decodeExpecting(200); - logger.info('Enclaved express service ping successful'); + logger.info('Advanced Wallet Manager ping successful'); return response.body; } catch (error) { logger.error( - 'Failed to ping enclaved express service: %s', + 'Failed to ping Advanced Wallet Manager: %s', (error as DecodeError).decodedResponse.body, ); throw error; @@ -367,7 +369,7 @@ export class AdvancedWalletManagerClient { */ async getVersion(): Promise { try { - logger.info('Getting version information from enclaved express service'); + logger.info('Getting version information from Advanced Wallet Manager'); let request = this.apiClient['v1.health.version'].get({}); if (this.tlsMode === TlsMode.MTLS) { @@ -810,7 +812,7 @@ export function createawmClient( return new AdvancedWalletManagerClient(cfg, coin); } catch (error) { const err = error as Error; - logger.error('Failed to create enclaved express client: %s', err.message); + logger.error('Failed to create advanced wallet manager client: %s', err.message); return undefined; } } diff --git a/src/initConfig.ts b/src/initConfig.ts index 652f244..0255f34 100644 --- a/src/initConfig.ts +++ b/src/initConfig.ts @@ -61,7 +61,7 @@ const advancedWalletManagerConfig: AdvancedWalletManagerConfig = { httpLoggerFile: 'logs/http-access.log', kmsUrl: '', // Will be overridden by environment variable tlsMode: TlsMode.MTLS, - allowSelfSigned: false, + clientCertAllowSelfSigned: false, }; function determineTlsMode(): TlsMode { @@ -103,6 +103,7 @@ function advancedWalletManagerEnvConfig(): Partial // KMS settings kmsUrl, kmsTlsCertPath: readEnvVar('KMS_TLS_CERT_PATH'), + kmsServerCertAllowSelfSigned: readEnvVar('KMS_SERVER_CERT_ALLOW_SELF_SIGNED') === 'true', // mTLS settings keyPath: readEnvVar('TLS_KEY_PATH'), crtPath: readEnvVar('TLS_CERT_PATH'), @@ -110,7 +111,7 @@ function advancedWalletManagerEnvConfig(): Partial tlsCert: readEnvVar('TLS_CERT'), tlsMode: determineTlsMode(), mtlsAllowedClientFingerprints: readEnvVar('MTLS_ALLOWED_CLIENT_FINGERPRINTS')?.split(','), - allowSelfSigned: readEnvVar('ALLOW_SELF_SIGNED') === 'true', + clientCertAllowSelfSigned: readEnvVar('CLIENT_CERT_ALLOW_SELF_SIGNED') === 'true', recoveryMode: readEnvVar('RECOVERY_MODE') === 'true', }; } @@ -137,13 +138,15 @@ function mergeAkmConfigs( headersTimeout: get('headersTimeout'), kmsUrl: get('kmsUrl'), kmsTlsCertPath: get('kmsTlsCertPath'), + kmsTlsCert: get('kmsTlsCert'), + kmsServerCertAllowSelfSigned: get('kmsServerCertAllowSelfSigned'), keyPath: get('keyPath'), crtPath: get('crtPath'), tlsKey: get('tlsKey'), tlsCert: get('tlsCert'), tlsMode: get('tlsMode'), mtlsAllowedClientFingerprints: get('mtlsAllowedClientFingerprints'), - allowSelfSigned: get('allowSelfSigned'), + clientCertAllowSelfSigned: get('clientCertAllowSelfSigned'), recoveryMode: get('recoveryMode'), }; } @@ -215,7 +218,7 @@ const defaultMasterExpressConfig: MasterExpressConfig = { advancedWalletManagerUrl: '', // Will be overridden by environment variable advancedWalletManagerCert: '', // Will be overridden by environment variable tlsMode: TlsMode.MTLS, - allowSelfSigned: false, + clientCertAllowSelfSigned: false, }; function determineProtocol(url: string, tlsMode: TlsMode, isBitGo = false): string { @@ -230,6 +233,7 @@ function determineProtocol(url: string, tlsMode: TlsMode, isBitGo = false): stri function masterExpressEnvConfig(): Partial { const advancedWalletManagerUrl = readEnvVar('ADVANCED_WALLET_MANAGER_URL'); const advancedWalletManagerCert = readEnvVar('ADVANCED_WALLET_MANAGER_CERT'); + const awmServerCertAllowSelfSigned = readEnvVar('AWM_SERVER_CERT_ALLOW_SELF_SIGNED') === 'true'; const tlsMode = determineTlsMode(); if (!advancedWalletManagerUrl) { @@ -243,8 +247,8 @@ function masterExpressEnvConfig(): Partial { } // Debug mTLS environment variables - const allowSelfSignedRaw = readEnvVar('ALLOW_SELF_SIGNED'); - const allowSelfSigned = allowSelfSignedRaw === 'true'; + const clientCertAllowSelfSignedRaw = readEnvVar('CLIENT_CERT_ALLOW_SELF_SIGNED'); + const clientCertAllowSelfSigned = clientCertAllowSelfSignedRaw === 'true'; return { appMode: AppMode.MASTER_EXPRESS, @@ -262,6 +266,7 @@ function masterExpressEnvConfig(): Partial { authVersion: Number(readEnvVar('BITGO_AUTH_VERSION')), advancedWalletManagerUrl: advancedWalletManagerUrl, advancedWalletManagerCert: advancedWalletManagerCert, + awmServerCertAllowSelfSigned, customBitcoinNetwork: readEnvVar('BITGO_CUSTOM_BITCOIN_NETWORK'), // mTLS settings keyPath: readEnvVar('TLS_KEY_PATH'), @@ -270,7 +275,7 @@ function masterExpressEnvConfig(): Partial { tlsCert: readEnvVar('TLS_CERT'), tlsMode, mtlsAllowedClientFingerprints: readEnvVar('MTLS_ALLOWED_CLIENT_FINGERPRINTS')?.split(','), - allowSelfSigned, + clientCertAllowSelfSigned, recoveryMode: readEnvVar('RECOVERY_MODE') === 'true', }; } @@ -301,6 +306,7 @@ function mergeMasterExpressConfigs( authVersion: get('authVersion'), advancedWalletManagerUrl: get('advancedWalletManagerUrl'), advancedWalletManagerCert: get('advancedWalletManagerCert'), + awmServerCertAllowSelfSigned: get('awmServerCertAllowSelfSigned'), customBitcoinNetwork: get('customBitcoinNetwork'), keyPath: get('keyPath'), crtPath: get('crtPath'), @@ -308,7 +314,7 @@ function mergeMasterExpressConfigs( tlsCert: get('tlsCert'), tlsMode: get('tlsMode'), mtlsAllowedClientFingerprints: get('mtlsAllowedClientFingerprints'), - allowSelfSigned: get('allowSelfSigned'), + clientCertAllowSelfSigned: get('clientCertAllowSelfSigned'), recoveryMode: get('recoveryMode'), }; } @@ -371,7 +377,7 @@ export function configureMasterExpressMode(): MasterExpressConfig { advancedWalletManagerCert: fs.readFileSync(config.advancedWalletManagerCert, 'utf-8'), }; logger.info( - `Successfully loaded Advanced Wallet Manager certificate from file: ${config.advancedWalletManagerCert.substring( + `Successfully loaded Advanced Wallet Manager certificate from file: ${config.advancedWalletManagerCert?.substring( 0, 50, )}...`, diff --git a/src/kms/kmsClient.ts b/src/kms/kmsClient.ts index 935ac94..4f473fd 100644 --- a/src/kms/kmsClient.ts +++ b/src/kms/kmsClient.ts @@ -35,11 +35,12 @@ export class KmsClient { const kmsUrlObj = new URL(cfg.kmsUrl); if (cfg.tlsMode === TlsMode.MTLS) { kmsUrlObj.protocol = 'https:'; - if (cfg.kmsTlsCert) { + if (cfg.kmsTlsCert || cfg.kmsServerCertAllowSelfSigned) { this.agent = new https.Agent({ ca: cfg.kmsTlsCert, cert: cfg.tlsCert, key: cfg.tlsKey, + rejectUnauthorized: !cfg.kmsServerCertAllowSelfSigned, }); } } else { diff --git a/src/shared/appUtils.ts b/src/shared/appUtils.ts index 815454f..485fb4f 100644 --- a/src/shared/appUtils.ts +++ b/src/shared/appUtils.ts @@ -124,7 +124,7 @@ export async function prepareIpc(ipcSocketFilePath: string): Promise { */ export function createMtlsMiddleware(config: { tlsMode: TlsMode; - allowSelfSigned?: boolean; + clientCertAllowSelfSigned?: boolean; mtlsAllowedClientFingerprints?: string[]; }): express.RequestHandler { return (req: express.Request, res: express.Response, next: express.NextFunction) => { @@ -146,7 +146,7 @@ export function createMtlsMiddleware(config: { // If client cert is provided, validate it if (hasValidClientCert) { // Check if self-signed certificates are allowed - if (!config.allowSelfSigned && clientCert.issuer.CN === clientCert.subject.CN) { + if (!config.clientCertAllowSelfSigned && clientCert.issuer.CN === clientCert.subject.CN) { return res.status(403).json({ error: 'mTLS Authentication Failed', message: 'Self-signed certificates are not allowed', diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts index 53ce682..2d711fb 100644 --- a/src/shared/types/index.ts +++ b/src/shared/types/index.ts @@ -30,6 +30,7 @@ export interface AdvancedWalletManagerConfig extends BaseConfig { kmsUrl: string; kmsTlsCertPath?: string; kmsTlsCert?: string; + kmsServerCertAllowSelfSigned?: boolean; // mTLS settings keyPath?: string; crtPath?: string; @@ -37,7 +38,7 @@ export interface AdvancedWalletManagerConfig extends BaseConfig { tlsCert?: string; tlsMode: TlsMode; mtlsAllowedClientFingerprints?: string[]; - allowSelfSigned?: boolean; + clientCertAllowSelfSigned?: boolean; } // Master Express mode specific configuration @@ -48,8 +49,10 @@ export interface MasterExpressConfig extends BaseConfig { customRootUri?: string; disableEnvCheck?: boolean; authVersion?: number; + // AWM client settings advancedWalletManagerUrl: string; - advancedWalletManagerCert: string; + advancedWalletManagerCert?: string; + awmServerCertAllowSelfSigned?: boolean; customBitcoinNetwork?: string; // mTLS settings keyPath?: string; @@ -58,7 +61,8 @@ export interface MasterExpressConfig extends BaseConfig { tlsCert?: string; tlsMode: TlsMode; mtlsAllowedClientFingerprints?: string[]; - allowSelfSigned?: boolean; + clientCertAllowSelfSigned?: boolean; + recoveryMode?: boolean; } // Union type for the configuration