Skip to content

feat(awm): backup awm client configurations#196

Open
margueriteblair wants to merge 1 commit intomasterfrom
margieblair/wcn-362-akm-support-separate-awm-instances-for-user-and-backup-key
Open

feat(awm): backup awm client configurations#196
margueriteblair wants to merge 1 commit intomasterfrom
margieblair/wcn-362-akm-support-separate-awm-instances-for-user-and-backup-key

Conversation

@margueriteblair
Copy link
Copy Markdown

Ticket: WCN-362

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 1, 2026

@margueriteblair margueriteblair force-pushed the margieblair/wcn-362-akm-support-separate-awm-instances-for-user-and-backup-key branch 2 times, most recently from f94534e to 059e29d Compare May 1, 2026 22:04
@margueriteblair margueriteblair changed the title feat(adv-wallets): backup key server configs feat(awm): backup keyserver configs May 1, 2026
@margueriteblair margueriteblair force-pushed the margieblair/wcn-362-akm-support-separate-awm-instances-for-user-and-backup-key branch from e39a781 to 9e0531d Compare May 4, 2026 19:21
@margueriteblair
Copy link
Copy Markdown
Author

@claude

@margueriteblair margueriteblair changed the title feat(awm): backup keyserver configs feat(awm): backup awm client configurations May 4, 2026
@margueriteblair margueriteblair marked this pull request as ready for review May 4, 2026 19:49
@margueriteblair margueriteblair requested a review from a team as a code owner May 4, 2026 19:49
Comment thread src/masterBitgoExpress/middleware/middleware.ts
Comment thread src/initConfig.ts
Comment on lines +502 to +547
// Handle cert loading for backup AWM (only when backup URL is configured)
if (config.advancedWalletManagerBackupUrl) {
if (config.awmBackupServerCaCertPath) {
try {
if (fs.existsSync(config.awmBackupServerCaCertPath)) {
config.awmBackupServerCaCert = fs.readFileSync(config.awmBackupServerCaCertPath, 'utf-8');
logger.info(
`✓ AWM backup server CA certificate loaded from file: ${config.awmBackupServerCaCertPath?.substring(
0,
50,
)}...`,
);
} else {
throw new Error(`Certificate file not found: ${config.awmBackupServerCaCertPath}`);
}
} catch (e) {
const err = e instanceof Error ? e : new Error(String(e));
throw new Error(`Failed to read AWM backup server CA cert: ${err.message}`);
}
}

if (config.awmBackupClientTlsKeyPath) {
try {
config.awmBackupClientTlsKey = fs.readFileSync(config.awmBackupClientTlsKeyPath, 'utf-8');
logger.info(
`✓ AWM backup client key loaded from file: ${config.awmBackupClientTlsKeyPath}`,
);
} catch (e) {
const err = e instanceof Error ? e : new Error(String(e));
throw new Error(`Failed to read AWM backup client key: ${err.message}`);
}
}

if (config.awmBackupClientTlsCertPath) {
try {
config.awmBackupClientTlsCert = fs.readFileSync(config.awmBackupClientTlsCertPath, 'utf-8');
logger.info(
`✓ AWM backup client certificate loaded from file: ${config.awmBackupClientTlsCertPath}`,
);
} catch (e) {
const err = e instanceof Error ? e : new Error(String(e));
throw new Error(`Failed to read AWM backup client cert: ${err.message}`);
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the cert loading block for backup AWM is a near-copy of the primary cert loading above. could extract a small helper like loadCertFromPath(path, label) to avoid the duplication.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it - will impl

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not impl lol. wont block on it - can do in a followup

Comment thread src/types/request.ts Outdated
Comment thread src/types/request.ts Outdated
@margueriteblair margueriteblair force-pushed the margieblair/wcn-362-akm-support-separate-awm-instances-for-user-and-backup-key branch 3 times, most recently from c58c1a2 to 07d8951 Compare May 5, 2026 19:14
Comment thread src/initConfig.ts
return undefined;
}
try {
const backupConfig: MasterExpressConfig = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so with this setup, it it currently possible to have fields (keys or certs) from two different instances, for example key from main client, and cert from backup - we should enforce that it's all or nothing, no? As in, either they use backup fields for all of the config or none of it. Intermixing the two will lead to random state.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can add validation to the starting point of the app, the configureMasterExpressMode() maybe? For the fields that need to move together, perhaps smth like:

if (config.awmBackupClientTlsKey && !config.awmBackupClientTlsCert) {
  throw new Error('backup key and cert must both exist');
}
...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yeah I'd agree with this - either provide the appropriate certs for the backup instance, or nothing

@margueriteblair margueriteblair force-pushed the margieblair/wcn-362-akm-support-separate-awm-instances-for-user-and-backup-key branch from 07d8951 to 233fef6 Compare May 5, 2026 20:35
Copy link
Copy Markdown
Contributor

@pranavjain97 pranavjain97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Comment thread src/initConfig.ts
Comment on lines +502 to +547
// Handle cert loading for backup AWM (only when backup URL is configured)
if (config.advancedWalletManagerBackupUrl) {
if (config.awmBackupServerCaCertPath) {
try {
if (fs.existsSync(config.awmBackupServerCaCertPath)) {
config.awmBackupServerCaCert = fs.readFileSync(config.awmBackupServerCaCertPath, 'utf-8');
logger.info(
`✓ AWM backup server CA certificate loaded from file: ${config.awmBackupServerCaCertPath?.substring(
0,
50,
)}...`,
);
} else {
throw new Error(`Certificate file not found: ${config.awmBackupServerCaCertPath}`);
}
} catch (e) {
const err = e instanceof Error ? e : new Error(String(e));
throw new Error(`Failed to read AWM backup server CA cert: ${err.message}`);
}
}

if (config.awmBackupClientTlsKeyPath) {
try {
config.awmBackupClientTlsKey = fs.readFileSync(config.awmBackupClientTlsKeyPath, 'utf-8');
logger.info(
`✓ AWM backup client key loaded from file: ${config.awmBackupClientTlsKeyPath}`,
);
} catch (e) {
const err = e instanceof Error ? e : new Error(String(e));
throw new Error(`Failed to read AWM backup client key: ${err.message}`);
}
}

if (config.awmBackupClientTlsCertPath) {
try {
config.awmBackupClientTlsCert = fs.readFileSync(config.awmBackupClientTlsCertPath, 'utf-8');
logger.info(
`✓ AWM backup client certificate loaded from file: ${config.awmBackupClientTlsCertPath}`,
);
} catch (e) {
const err = e instanceof Error ? e : new Error(String(e));
throw new Error(`Failed to read AWM backup client cert: ${err.message}`);
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not impl lol. wont block on it - can do in a followup

// Create backup client if backup URL is configured; falls back to primary client
try {
const awmBackupClient = createAwmBackupClient(bitgoReq.config, bitgoReq.params?.coin);
bitgoReq.awmBackupClient = awmBackupClient ?? awmClient;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth noting this in the README that we fall back to the default

Copy link
Copy Markdown
Contributor

@pranishnepal pranishnepal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, though you might need to update some tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants