Client provisioning playbook¶
Resolves: GAP-D02 — No client provisioning playbook.
This is the end-to-end guide for deploying a new client from zero to go-live. An AI agent or a deployment engineer can follow this document sequentially. Each step has a clear completion signal — do not proceed to the next step until the current one passes.
Related: deployment sequence · configuration manifest · secrets manifest · module activation matrix · post-deployment checklist
Estimated time: First deployment (greenfield, competent engineer or AI agent): 2–3 days. Subsequent clients: approximately 1 day. Most time is in third-party credential procurement and regulatory sign-off, not the technical steps.
Prerequisites¶
Confirm all of the following before starting. Missing prerequisites will block later steps.
AWS
- An AWS Organisation is in place with SCPs baseline applied
- You have permission to create a new member account in the Organisation
- The bootstrap IAM role ARN (arn:aws:iam::{master-account}:role/BankBootstrapRole) is documented and reachable
- GitHub Actions OIDC provider is registered in the AWS Organisation master account
GitHub
- Access to the totara-bank GitHub organisation
- Repository secrets in bank-platform, bank-core, bank-kyc, bank-aml, bank-payments, bank-credit, bank-risk-platform, and bank-app can be set
- The environment (dev, uat, or prod) has been created in each repository
Neon - A Neon account (or Organisation plan) with capacity for a new project - Neon API key with project creation permissions
Snowflake - A Snowflake account with the SYSADMIN and SECURITYADMIN roles available - Snowflake account identifier documented
Third-party credentials (may take days to procure — start early) - eIDV provider: GreenID API key OR Frankie One API key (jurisdiction-dependent) - Credit bureau: Equifax AU API credentials (AU deployments) and/or Centrix NZ API credentials (NZ deployments) - Payment rails: sponsor bank approval for BPAY (AU); NPP Financial Institution Identifier (AU); NZ faster payments institution credentials (NZ) - Card bureau: Cuscal or Monoova API credentials (if card issuance is enabled) - ATM network: Westpac network agreement (NZ standalone) or rediATM/Coles agreement (AU) if applicable
Regulatory - The institution has a New Zealand banking licence, an Australian ADI authorisation, or both, as applicable to the target jurisdiction - AUSTRAC enrolment completed (AU) - FMA / RBNZ notification completed (NZ)
Step 1 — AWS account structure¶
Create a new AWS member account within the Organisation for this client. Use the naming convention bank-{client-id}-{env} (e.g. bank-acorn-prod).
- In the AWS Organisations console, create the member account. Set the email address to
aws-{client-id}-{env}@{internal-domain}. - Apply the landing zone SCP baseline. The baseline SCPs restrict:
- Disabling CloudTrail
- Deleting KMS keys with less than 30 days pending deletion
- Leaving a region outside the approved set (ap-southeast-2 for AU, ap-southeast-2 or us-east-1 for NZ)
- Create the
BankBootstrapRolein the new account with a trust relationship to the master account's CI/CD role. This is the only role used for the first bootstrap run. - Register the GitHub Actions OIDC provider in the new account. The OIDC audience must match the value in the
bank-platformrepository's workflow file. - Document the new account ID in the client's configuration entry.
Completion signal: aws sts get-caller-identity --profile bank-{client-id}-{env}-bootstrap returns the expected account ID.
Step 2 — Infrastructure bootstrap¶
Follow the deployment sequence Phase 0 exactly. Summary:
- Authenticate manually for the first run (see Phase 0, Step 0.1 in the deployment sequence).
- Run MOD-104 (
bank-platformbootstrap pipeline). This may take 15–20 minutes on first run as it creates all shared infrastructure. - Once MOD-104 is healthy, run MOD-103 and MOD-102 in parallel.
- Run the Flyway baseline migrations for all eight databases (connection strings are written to SSM by MOD-103).
- Run MOD-045 and MOD-076 in parallel.
- Run MOD-046 after MOD-103 and MOD-045 are both complete.
Do not proceed to Step 3 until MOD-046 reports healthy.
Completion signal: All Phase 0 modules are in Deployed state in the SST console. Neon project is visible in the Neon dashboard. Snowflake environment is configured.
Step 3 — Tenant identity configuration¶
Configure the Cognito user pool that MOD-104 created.
All Cognito configuration is applied via the bank-platform configuration pipeline, not via the AWS console. Set the following values in SSM Parameter Store under /bank/{env}/identity/:
| Parameter | Value |
|---|---|
institution_name |
Display name of the institution (e.g. "Acorn Bank") |
mfa_policy |
required (recommended) or optional |
password_policy |
strong (min 12 chars, complexity enforced) |
session_timeout_minutes |
Typically 15 for banking apps |
custom_jurisdiction_claim |
NZ, AU, or NZ+AU — see Step 4 |
branding_logo_s3_key |
S3 key for the institution's logo (upload separately) |
branding_primary_colour |
Hex colour code for the app UI |
The custom:jurisdiction pool attribute must be set — this is the runtime signal that all modules use to switch jurisdiction-specific behaviour. It is set here in the pool definition and then asserted per-token at login time.
Completion signal: A test Cognito user can authenticate and the decoded JWT contains custom:jurisdiction with the correct value.
Step 4 — Jurisdiction profile activation¶
Set the jurisdiction and institution type in AppConfig. These flags control which modules activate, which payment rails are available, and which regulatory rules apply.
In the bank-platform AppConfig application, set the deployment profile:
{
"deployment.jurisdiction": "NZ",
"deployment.institution_type": "bank",
"deployment.institution_name": "Acorn Bank",
"deployment.client_id": "acorn"
}
deployment.jurisdiction options:
- NZ — enables NZ-specific modules (OBR, DCS, NZ faster payments, Centrix credit bureau, FMA reporting). Disables AU-only modules (BPAY, NPP, AUSTRAC).
- AU — inverse of above.
- NZ+AU — enables both. Use only if the institution has licences in both jurisdictions.
deployment.institution_type options:
- bank — full feature set
- building_society — building society profile (typically narrower product set; check module activation matrix)
- credit_union — credit union profile (member-ownership constraints active)
Open banking:
- openbanking.profiles.enabled: set to [] to disable, ["au-cdr"] for AU CDR, ["nz-consumer-data"] for NZ consumer data, or both.
- openbanking.cdr.software_product_id: required if CDR is enabled; the UUID assigned by the CDR Register.
Completion signal: The AppConfig profile is deployable without validation errors. The deployment pipeline can read the jurisdiction value.
Step 5 — Payment rail configuration¶
Configure connectivity to the payment rails that are active for this jurisdiction. All payment rail credentials must be stored in Secrets Manager (see secrets manifest) before the SD04 Payments modules start.
BPAY (AU only)¶
Required if payments.bpay.enabled = true.
| Config | Location | Value |
|---|---|---|
payments.bpay.sponsor_bank.bic |
SSM /bank/{env}/payments/bpay-sponsor-bic |
Sponsor bank BIC code |
payments.bpay.bsb |
SSM /bank/{env}/payments/bpay-bsb |
Institution BSB |
payments.bpay.inbound.enabled |
AppConfig payments profile |
true | false |
payments.bpay.outbound.enabled |
AppConfig payments profile |
true | false |
| BPAY API credentials | Secrets Manager /bank/{env}/payments/bpay-credentials |
JSON with client_id, client_secret |
NPP (AU only)¶
Required if payments.npp.enabled = true.
| Config | Location | Value |
|---|---|---|
payments.npp.financial_institution_identifier |
SSM /bank/{env}/payments/npp-fii |
NPP FII assigned by NPPA |
payments.cop.enabled |
AppConfig payments profile |
Confirmation of payee on/off |
| NPP gateway credentials | Secrets Manager /bank/{env}/payments/npp-credentials |
Provided by NPP access point provider |
NZ faster payments (NZ only)¶
Required if payments.nz_faster_payments.enabled = true.
| Config | Location | Value |
|---|---|---|
| Institution identifier | SSM /bank/{env}/payments/nz-faster-payments-id |
Assigned by Payments NZ |
| API credentials | Secrets Manager /bank/{env}/payments/nz-faster-payments-credentials |
JSON with API key |
SWIFT / correspondent banking (optional)¶
Required only if payments.swift.enabled = true.
| Config | Location | Value |
|---|---|---|
| BIC | SSM /bank/{env}/payments/swift-bic |
Institution's SWIFT BIC |
| Correspondent bank details | SSM /bank/{env}/payments/correspondent-bank-* |
One entry per correspondent |
| SWIFT credentials | Secrets Manager /bank/{env}/payments/swift-credentials |
SWIFT Alliance Lite2 credentials |
Completion signal: The payments health endpoint returns 200 and all enabled rail connectors show connected status.
Step 6 — Third-party integration wiring¶
Configure the third-party service integrations. All API credentials must be in Secrets Manager before the relevant modules start.
Credit bureaux¶
| Jurisdiction | Provider | Secret path |
|---|---|---|
| AU | Equifax Australia | /bank/{env}/credit/equifax-au-credentials |
| NZ | Centrix NZ | /bank/{env}/credit/centrix-nz-credentials |
| NZ | ifax NZ (alternative) | /bank/{env}/credit/ifax-nz-credentials |
Store credentials as JSON with at minimum api_key and endpoint fields. The credit bureau module reads these at startup and validates connectivity.
eIDV providers¶
| Provider | Jurisdiction | Secret path |
|---|---|---|
| GreenID | AU + NZ | /bank/{env}/kyc/greenid-credentials |
| Frankie One | AU + NZ (alternative) | /bank/{env}/kyc/frankieone-credentials |
Only one eIDV provider is active at a time. Set kyc.eidv.provider in AppConfig to greenid or frankieone. The KYC module reads this flag at startup.
Card bureau¶
| Provider | Condition | Secret path |
|---|---|---|
| Cuscal | AU card issuance | /bank/{env}/cards/cuscal-credentials |
| Monoova | AU (alternative) | /bank/{env}/cards/monoova-credentials |
Set cards.bureau.provider in AppConfig to cuscal or monoova if card issuance is enabled.
ATM network¶
| Network | Condition | Config path |
|---|---|---|
| Westpac network | NZ standalone ATM agreement | SSM /bank/{env}/atm/network = westpac |
| rediATM / Coles | AU ATM agreement | SSM /bank/{env}/atm/network = rediatm |
ATM network is optional. If not enabled, set atm.enabled = false in AppConfig.
Completion signal: Each third-party integration health check returns 200 in the monitoring dashboard.
Step 7 — Module activation¶
Set feature flags in AppConfig to activate the correct set of modules for this institution. Reference the module activation matrix for the definitive mapping of institution type to module set.
The activation flags are in the features AppConfig profile:
- Required modules for all deployments: always
true, do not change. - Jurisdiction-conditional modules (e.g. OBR, DCS, AUSTRAC): set based on
deployment.jurisdiction. - Institution-type-conditional modules (e.g. building society specific modules): set based on
deployment.institution_type. - Optional modules (e.g. card issuance, cross-border, open banking APIs): set based on the client's contracted product set.
Apply the activation flags before running the application module deployment in Step 10 — modules read their activation flag at startup and skip initialisation if inactive. This avoids deploying module infrastructure for features the institution does not use.
Completion signal: AppConfig profile validates without errors. A dry-run deployment reports the expected set of active modules.
Step 8 — Threshold configuration¶
Set the operational thresholds that govern regulatory and risk behaviour. These are stored in AppConfig (hot-reload — changes take effect at runtime without a redeploy) unless noted.
See the configuration manifest for the full list. Key thresholds to set before go-live:
| Threshold | Default | Notes |
|---|---|---|
aml.cash_threshold_nzd |
10000 |
NZD cash reporting threshold (NZ only) |
aml.cash_threshold_aud |
10000 |
AUD cash reporting threshold (AU only) |
prudential.related_party.warning_pct_tier1 |
10 |
% of Tier 1 capital — warning |
prudential.related_party.breach_pct_tier1 |
15 |
% of Tier 1 capital — breach/block |
prudential.obr.haircut_pct |
Client-specific | NZ only; set per RBNZ OBR policy |
prudential.dcs.coverage_limit_nzd |
100000 |
NZ deposit compensation scheme limit |
payments.scam.hold_threshold_aud |
Client-specific | AU only; consult compliance team |
payments.scam.hard_hold_threshold_aud |
Client-specific | AU only |
payments.scam.auto_release_hours |
24 |
Soft hold auto-release window |
Thresholds must be reviewed with the compliance team before go-live. Defaults are conservative but may need adjustment for the institution's specific risk appetite.
Completion signal: AppConfig thresholds profile validates. Compliance sign-off documented.
Step 9 — Secrets provisioning¶
Before any application module starts, every required secret must be present in AWS Secrets Manager with the correct structure. A missing secret causes a module startup failure that is difficult to diagnose at scale.
Follow the secrets manifest for the complete list of required secrets. Key categories:
- Database credentials (written by MOD-103 — should already exist)
- Third-party API credentials (populated in Steps 5 and 6)
- Internal service-to-service tokens
- Signing keys for JWTs and audit events
- Encryption keys for PII fields (separate from KMS — these are application-layer keys)
Run the secrets validation script before proceeding:
This script checks that every required secret path exists and is non-empty. It does not read secret values — it only verifies presence.
Completion signal: validate-secrets.py exits with code 0, reporting all secrets present.
Step 10 — Application module deployment¶
Run all system domain pipelines in the order defined in the deployment sequence:
- Phase 1 and Phase 2 in parallel (SD01 Core Banking + SD02 KYC)
- Phase 3 (SD03 AML) — after Phase 1 and Phase 2 are both healthy
- Phases 4, 5, and 6 in parallel (SD04 Payments + SD05 Credit + SD06 Risk)
- Phase 7 (SD08 App) — after all of the above
Trigger each pipeline via the GitHub Actions workflow dispatch, passing env={env} and client_id={client-id} as inputs.
Monitor the deployment in the SST console. Each module emits a health event to the observability platform (MOD-076) on startup. A green status in the dashboard indicates a healthy module.
Do not proceed to Step 11 until all modules in all phases report healthy.
Completion signal: SST console shows all modules Deployed. Observability dashboard shows no startup errors.
Step 11 — Smoke test suite¶
Run the smoke test suite after each phase and again after the full deployment. The smoke tests cover the minimum viable paths for each system domain.
The smoke test suite includes:
| Test | Domain | What it checks |
|---|---|---|
| Account creation | SD01 | A test account can be created and is visible in the ledger |
| Balance enquiry | SD01 | A balance read returns a non-null value |
| KYC flow | SD02 | A test customer can complete eIDV and receive a KYC-passed token |
| Transaction event | SD03 | A synthetic transaction triggers an AML event without false positives |
| Domestic payment | SD04 | A test payment completes the instruction-to-clearing cycle (sandbox mode) |
| Credit application | SD05 | A test application reaches a decision state |
| Risk threshold | SD06 | A related-party exposure above the warning threshold triggers an alert |
| App login | SD08 | A test user can log in, view their account, and navigate the app |
All smoke tests must pass before proceeding to Step 12.
Completion signal: All smoke tests pass with exit code 0.
Step 12 — Post-deployment verification¶
Run through the post-deployment checklist in full. This is a manual or semi-automated review covering:
- All environment-specific configuration values match the agreed specification
- Feature flags are set correctly for the institution type and jurisdiction
- Secrets are present for all enabled integrations
- Observability dashboards are active and showing data
- Alert notification channels (PagerDuty / Slack) are wired and tested
- Log groups are routing to the correct retention policy
- CloudTrail is active and audit logs are being written to the audit S3 bucket
- Backup schedules are confirmed active (see backup and recovery)
Completion signal: Post-deployment checklist signed off by deployment engineer or AI agent run report.
Step 13 — Go-live gate¶
Before go-live, a compliance officer or designated approver must confirm the following:
Regulatory reporting - AML regulatory reporting pipelines (AUSTRAC for AU, FMA reporting for NZ) have been configured with the correct reporting entity identifiers. - A test STR (Suspicious Transaction Report) has been generated and validated in format (not submitted to regulator). - CCCFA / NCCP disclosure module is active and generating disclosures for credit products.
AML monitoring - AML monitoring is confirmed active: synthetic high-value transactions trigger alerts. - Sanctions screening is live and the sanctions list has been refreshed at least once. - Transaction monitoring rules have been reviewed and signed off by the compliance team.
KYC gates - KYC gate enforcement is confirmed: an account cannot be activated without a KYC-passed token. - Step-up KYC rules are active for the product set.
Jurisdiction
- The custom:jurisdiction claim is present in test JWTs and routes to the correct regulatory rules.
- If NZ+AU: both jurisdictions have been tested end-to-end.
Documentation - The client's configuration entry in this wiki is up to date. - Runbook access has been confirmed for the client's operations team.
Completion signal: Go-live gate signed off by compliance officer. Deployment record created.
Rollback (if needed at any step)¶
If a step fails and cannot be resolved forward:
- Use
npx sst rollback --stage {env} --filter {module-slug}to roll back individual modules. - For Step 2 failures (Phase 0), contact the engineering lead before rolling back — Phase 0 modules affect the entire environment.
- For Steps 3–7 (configuration), update the AppConfig or SSM value and redeploy the affected module — no full rollback needed.
- For Step 9 failures (missing secrets), add the missing secret and re-trigger the module deployment — no rollback needed.
Database schema migrations cannot be rolled back automatically. If a migration causes an issue, write a compensating migration and run it forward. See schema migrations.