feat(24-01): implement Route 53 credential factory
- lib/services/route53-factory.ts: isRoute53Configured() / getRoute53Client() / resetRoute53Client(), following the veeam-factory.ts singleton shape - No explicit credentials option passed to Route53Client — relies on the AWS SDK's default credential chain reading AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY from process.env, exactly how BWS injects them at the container entrypoint - CLAUDE.md: document the AWS_* env-prefix exception in the integration table - All 7 route53-factory.test.ts assertions pass; npx tsc --noEmit clean
This commit is contained in:
parent
4dd9d5dab8
commit
210f84d343
2 changed files with 48 additions and 0 deletions
|
|
@ -80,6 +80,7 @@ Examples: `getAutotaskClient()`, `getMsgraphClient()`, `getDattoRmmClient()`,
|
||||||
| Veeam VSPC | `VEEAM_VSPC_*` |
|
| Veeam VSPC | `VEEAM_VSPC_*` |
|
||||||
| Auvik / Addigy / IT Glue / Mimecast / S1 / Duo / Zoom / QBO / Zabbix / Salesbldr | `<NAME>_*` |
|
| Auvik / Addigy / IT Glue / Mimecast / S1 / Duo / Zoom / QBO / Zabbix / Salesbldr | `<NAME>_*` |
|
||||||
| PAX8 | `PAX8_*` (OAuth2 client-credentials, read-only partner/reseller API) |
|
| PAX8 | `PAX8_*` (OAuth2 client-credentials, read-only partner/reseller API) |
|
||||||
|
| AWS Route 53 | `AWS_*` (literal `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_REGION` — intentional exception to the per-service prefix convention; the AWS SDK's default credential chain hardcodes these names. Injected by BWS at the container entrypoint, never in `.env`) |
|
||||||
| Anthropic | `ANTHROPIC_API_KEY` (analyzer pipeline + `ai-triage-service.ts`) |
|
| Anthropic | `ANTHROPIC_API_KEY` (analyzer pipeline + `ai-triage-service.ts`) |
|
||||||
| OpenRouter | `OPENROUTER_API_KEY` (alternate analyzer provider, opt-in per request) |
|
| OpenRouter | `OPENROUTER_API_KEY` (alternate analyzer provider, opt-in per request) |
|
||||||
| Backblaze B2 | `B2_*` (LogLift evidence storage) |
|
| Backblaze B2 | `B2_*` (LogLift evidence storage) |
|
||||||
|
|
|
||||||
47
lib/services/route53-factory.ts
Normal file
47
lib/services/route53-factory.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { Route53Client } from '@aws-sdk/client-route-53';
|
||||||
|
|
||||||
|
let route53ClientInstance: Route53Client | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if AWS Route 53 credentials are configured.
|
||||||
|
*/
|
||||||
|
export function isRoute53Configured(): boolean {
|
||||||
|
return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create the Route 53 client singleton instance.
|
||||||
|
*
|
||||||
|
* Intentionally does NOT pass an explicit `credentials` option — omitting it
|
||||||
|
* lets @aws-sdk/credential-provider-node's default credential chain read
|
||||||
|
* AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN from
|
||||||
|
* process.env automatically (fromEnv() is first in the chain). This is
|
||||||
|
* exactly how Bitwarden Secrets Manager (`bws run`) injects credentials at
|
||||||
|
* the docker-entrypoint.sh layer. Do NOT "fix" this by adding an explicit
|
||||||
|
* credentials object — see 24-RESEARCH.md Pitfall 1.
|
||||||
|
*/
|
||||||
|
export function getRoute53Client(): Route53Client {
|
||||||
|
if (!route53ClientInstance) {
|
||||||
|
if (!isRoute53Configured()) {
|
||||||
|
throw new Error(
|
||||||
|
'AWS credentials missing. Please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (and AWS_REGION) environment variables.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route 53 is a global service but the SDK still requires a signing
|
||||||
|
// region; us-east-1 is the conventional default AWS's own CLI/console use.
|
||||||
|
route53ClientInstance = new Route53Client({
|
||||||
|
region: process.env.AWS_REGION || 'us-east-1',
|
||||||
|
});
|
||||||
|
console.log('Route 53 client initialized');
|
||||||
|
}
|
||||||
|
|
||||||
|
return route53ClientInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the singleton instance (useful for testing).
|
||||||
|
*/
|
||||||
|
export function resetRoute53Client(): void {
|
||||||
|
route53ClientInstance = null;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue