ADR-030: Secrets management — AWS Secrets Manager¶
| Status | Accepted |
| Date | 2026-04-10 |
| Deciders | CTO, Head of Architecture |
| Affects repos | bank-core, bank-kyc, bank-aml, bank-payments, bank-credit, bank-risk-platform, bank-platform, bank-app |
Status¶
Accepted — 2026-04-10
Context¶
Lambda functions across all system domains require secure access to credentials: Neon Postgres connection strings, Cognito client secrets, external API keys, and signing keys. ADR-022 deferred the secrets management tool choice. Credentials must not appear in environment variables, source code, or logs. DT-001 requires an audit trail on all secret access and automatic rotation for credentials.
Decision¶
AWS Secrets Manager is the secrets store for all production credentials.
Access pattern: Each Lambda's IAM execution role grants secretsmanager:GetSecretValue
scoped to its own domain path only. No Lambda may access another domain's secrets.
Path naming convention:
/bank/{env}/{domain}/{service}/{name}
e.g. /bank/prod/payments/neon/connection-string
/bank/prod/kyc/eidv-provider/api-key
/bank/prod/platform/cognito/client-secret
Caching: AWS Lambda Powertools SecretsProvider caches values in the execution
environment — one API call per cold start, not per invocation. TTL configurable per
secret (default 5 minutes).
Neon rotation: Neon supports multiple database roles per project. Secrets Manager rotation Lambda cycles the active role on schedule without connection downtime — the inactive role is updated and tested, then promoted as primary.
Non-secret config (endpoints, environment identifiers, non-sensitive feature values) uses AWS Systems Manager Parameter Store (free standard tier). Parameter Store holds no credentials — the distinction is enforced in code review and pipeline policy.
Rejected alternatives¶
| Option | Reason rejected |
|---|---|
| AWS Parameter Store (for secrets) | No built-in rotation — rotation Lambda required, which recreates the maintenance burden |
| HashiCorp Vault | Always-on process; conflicts with serverless model; significant operational overhead |
| Environment variables | No rotation, no audit trail, exposed in Lambda console — non-compliant with DT-001 |
Consequences¶
DT-001 rotation and audit trail requirements satisfied without custom code. Secret access auditable via CloudTrail per domain. IAM path scoping enforces domain isolation — a compromised Lambda cannot read another domain's credentials. Cost ~$0.40/secret/month, negligible at launch secret count.
Related decisions¶
| ADR | Title | Relationship |
|---|---|---|
| ADR-022 | CI/CD and deployment strategy | resolves the deferred secrets management decision from ADR-022 |
| ADR-024 | Database hosting — Neon serverless Postgres | Neon connection string rotation via Secrets Manager |
| ADR-025 | API layer — HTTP API Gateway and SST | Lambda IAM execution roles constrain secret path access |
| --- |
Signoff record¶
| Date | Name | Role | Status |
|---|---|---|---|
| 2026-04-10 | Ross Millen | CTO | Approved |
| 2026-04-10 | Ross Millen | Head of Architecture | Approved |
| 2026-04-10 | Ross Millen | Head of Data | Approved |
All ADRs
Compiled 2026-05-22 from source/entities/adrs/ADR-030.yaml