Skip to content

ADR-035: Snowflake account configuration and data residency

Status Superseded
Date 2026-04-10
Deciders CTO, Head of Architecture
Affects repos bank-risk-platform, bank-aml, bank-credit, bank-platform
Superseded by ADR-054

⚠️ This ADR has been superseded by ADR-054.


Superseded. This ADR has been superseded by ADR-054 (DCM Projects for Snowflake DDL management). The SQL DDL script approach described here has been replaced by DCM Projects for new modules. Existing modules (MOD-038, MOD-085, MOD-098) are pending migration.

ADR-035: Snowflake account configuration and data residency

Status

Superseded — 2026-05-03 (by ADR-054). Supplements ADR-002 (Snowflake as analytics platform) and ADR-023 (cloud region strategy) with explicit data residency configuration.

Context

ADR-002 selected Snowflake as the analytics and risk compute platform. ADR-023 established ap-southeast-2 (Sydney) as the bank's cloud region and confirmed NZ customer data may reside in Sydney under contractual DPA. Neither ADR specified the Snowflake account region, account isolation model, or network access controls. For APRA, RBNZ, and AUSTRAC compliance the data residency posture of the analytics platform must be explicitly documented.

Decision

Account region: Single Snowflake account in AWS AP-SOUTHEAST-2 (Sydney). No cross-region replication at launch.

NZ data residency: NZ customer data in the Sydney Snowflake account is acceptable under the same contractual DPA basis as ADR-023. This is consistent with the position RBNZ has accepted for cloud-hosted banks operating without a local AWS region. When an AWS NZ region becomes available, the data migration trigger follows ADR-023 — an operational decision, not a platform rebuild.

Domain database structure: One Snowflake database per system domain, consistent with AP-010. Ownership and RBAC boundaries follow system domain boundaries (SD), not business domain boundaries.

Database System domain Repo Business domain owner
CORE SD01 Core Banking bank-core BD02 Finance
CUSTOMER SD02 KYC Platform bank-kyc BD01 Customer
FINCRIME SD03 AML Monitoring bank-aml BD07 Financial Crime
PAYMENTS SD04 Payments bank-payments BD06 Payments
CREDIT SD05 Credit bank-credit BD05 Credit
RISK SD06 Risk Platform bank-risk-platform BD08 Risk
PLATFORM SD07 Data Platform bank-platform BD09 Technology

SD08 (App / bank-app) does not produce data products in Snowflake and has no database.

Schema governance within each database

Each Snowflake database uses a layered schema structure. Schema names are lowercase.

Layer 1 — Raw data products (raw_<module_slug>)

One schema per source Neon module that produces data. Named after the module slug. These are the raw data products — append-only Iceberg tables written by the CDC pipeline (ADR-003). Ownership belongs to the team responsible for the source module.

Examples:

Schema Source module Source tables
CORE.raw_accounts MOD-001 Account ledger accounts, postings
CORE.raw_transactions MOD-002 Transaction store transactions
CUSTOMER.raw_onboarding MOD-006 Customer onboarding customers, onboarding_events
CUSTOMER.raw_kyc MOD-009 eIDV & document verification kyc_checks, identity_documents
PAYMENTS.raw_domestic MOD-021 Domestic payment execution payments, payment_events
FINCRIME.raw_aml_cases MOD-013 AML transaction monitoring aml_cases, aml_alerts
CREDIT.raw_applications MOD-030 Credit application credit_applications, bureau_responses

The full raw schema map is maintained in each module's YAML (raw_snowflake_schema field — to be added when modules reach In progress status). This section documents the pattern; module-level detail lives with the module.

Layer 2 — Analytical data products (domain schema)

Snowflake Dynamic Tables that derive from raw data products. Named by analytical concern, not by source module.

Schema Database Purpose
CORE.intelligence CORE Spend analytics, balance trends, idle cash signals
PAYMENTS.intelligence PAYMENTS Payment predictions, FX signals
FINCRIME.typology FINCRIME AML typology models, SAR decision inputs
CREDIT.decisions CREDIT Affordability models, pre-approval signals
RISK.capital RISK Capital and liquidity positions (CET1, RWA, LCR, NSFR)
RISK.customer_risk RISK Customer risk scores, fraud model outputs
PLATFORM.regulatory PLATFORM Regulatory returns, cross-domain aggregations

Layer 2 schemas may read from raw schemas in other databases — but only via a documented cross-domain data contract (see access controls below).

Layer 3 — Reporting views (reporting schema in each database)

Snowflake views or Dynamic Tables serving the Snowflake read API (ADR-038 Tier 3). Named reporting within the relevant domain DB. These are the surfaces the API layer queries — they never expose raw Iceberg columns directly.

Data product ownership rule

A data product is owned by the system domain that writes it. The owning domain team controls schema evolution, partition strategy, and access grants. No other team may write to a raw schema they do not own. Analytical schemas (Layer 2) may be written by the risk/analytics team using data from multiple raw schemas, provided cross-domain data contracts are in place.

Access controls: - Snowflake RBAC — one functional role per system domain; no cross-domain SELECT without a documented data contract - Column-level masking on all PII fields — unmasked access requires elevated role, all access logged to audit trail - Network policy restricts connections to Lambda NAT Gateway IPs (ap-southeast-2) and authorised engineer IPs via VPN only — no public account URL access

Compute isolation: One dedicated virtual warehouse per domain. Auto-suspend after 5 minutes idle. No shared warehouses — cost and performance isolated per domain.

IaC approach

Snowflake objects are managed as versioned SQL DDL scripts, not via Pulumi, Terraform, or the Snowflake Terraform provider. SQL is the native IaC for Snowflake — it is idempotent (CREATE OR REPLACE), human-readable, diffable in code review, and requires no external state file.

MOD-102 (bank-platform) owns account-level objects: warehouses, databases, RBAC roles, storage integrations (S3, SNS, GitHub), network policy, PII tag taxonomy, and column-level masking policies. These are applied once at account bootstrap by CI from versioned scripts in bank-platform/snowflake/setup/.

Domain repos (bank-risk-platform and future domain repos) own domain-specific objects within their assigned database — schemas, tables, Dynamic Tables, and grants. Scripts live in each repo's infra/snowflake/ directory and are applied by domain CI. A manifest.yml in that directory declares the ordered script list.

Deployment rule: MOD-102 must be applied before any domain module's Snowflake scripts run — it provisions the databases and roles that domain scripts reference.

Migration path

When an AWS NZ region is available: NZ customer databases are cloned to a new Snowflake account in the NZ region, traffic is cut over, and the Sydney account retains AU customer data only. Application layer is unaffected — connection strings updated via Secrets Manager (ADR-030).

Rejected alternatives

Option Reason rejected
US East or US West Snowflake region AU/NZ data residency obligations not satisfied
AP-NORTHEAST-1 (Tokyo) Outside AU/NZ data residency boundary
Separate Snowflake accounts per domain Operational overhead; cross-account Secure Data Sharing adds complexity without benefit at launch scale


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

Capabilities

Capability Description Relationship
CAP-030 Regulator evidence portal enabled — Snowflake Secure Data Sharing enables regulator account access
CAP-033 Tenant data isolation enabled — one Snowflake DB per system domain with RBAC isolation
CAP-034 Jurisdiction configuration layer enabled — NZ/AU data residency formalised; migration trigger defined
CAP-035 Per-jurisdiction regulatory report profiles enabled — PLATFORM.regulatory schema holds jurisdiction-specific returns

ADR Title Relationship
ADR-002 Snowflake as the analytics and risk compute platform this ADR supplements ADR-002 with residency and account config
ADR-003 CDC pipeline — Neon Postgres to Snowflake via Firehose and Apache Iceberg raw schemas receive CDC data
ADR-023 Cloud provider and region strategy same region constraint (ap-southeast-2)
ADR-038 Data access tier policy — Snowflake as the reporting and insight layer reporting schemas (Layer 3) serve the Tier 3 read API

All ADRs Compiled 2026-05-22 from source/entities/adrs/ADR-035.yaml