Five sections covering the structural decisions, the data model under them, and the operational characteristics you can show to an architecture review or a regulator.
§ 01
What "multi-tenant" actually means here
Multi-tenant in core banking is a phrase that means very different things to different vendors. For Coreal it means tenant isolation at four layers simultaneously: (1) IAM — every tenant has its own OAuth client space, role definitions and token issuer; (2) network — tenant API traffic terminates on tenant-scoped endpoints with separate rate limits; (3) data — every ledger row carries a tenant_id and every query is scoped through a tenant predicate enforced by row-level security; (4) operations — separate audit logs, separate alert routing, separate runbooks per tenant. An incident in tenant A cannot leak data, exhaust resources or create regulatory contamination for tenant B.
§ 02
Why the ledger is partitioned, not sharded
Sharding spreads one logical ledger across many physical nodes for scale. Partitioning per tenant means each tenant has its own logical ledger inside the same physical database, with isolation guaranteed by schema boundaries and explicit row-level security policies. Coreal uses partitioning rather than full sharding because tenants are a fundamentally different unit of isolation than customers — each tenant has its own audit, regulatory perimeter, and recovery profile. A tenant should be restorable, exportable, and auditable as a unit. With shared physical infrastructure but partitioned data, this is achievable; with full sharding, it becomes a multi-region operations problem.
§ 03
BPM as the spine
Every money-movement flow in the core banking platform is a BPM process — onboarding, KYC step-up, withdrawal approval, card issuance, dispute lifecycle, AML case management. Process definitions are versioned artefacts, executed by a Camunda-class engine. Each instance carries a journal of state transitions, actor IDs, decision metadata and elapsed time. When the regulator asks "show me every withdrawal over £10k that required dual approval in March", the answer is a query against the BPM event log, not a custom report against application code. The process model is the source of truth for what should happen; the event log is the source of truth for what did happen.
§ 04
Sponsor-bank controls as gateway policy
A BaaS deployment depends on the sponsor bank's acceptance of the platform's control envelope. In Coreal, sponsor-bank-level controls — exposure caps per customer, velocity limits, KYT thresholds for crypto in/out — are encoded as policies in the provider gateway, not as application-layer checks. This means the bank's risk team can audit the policy file directly, see the active version, and reason about coverage without reading product code. When the bank requires a tightening (a new sanctions list, an exposure ceiling change, a new merchant category block), it is a policy commit with an approval flow, not an engineering ticket.
§ 05
Idempotency as a hard invariant
Every API request that mutates the ledger carries an idempotency-key. The platform stores key→outcome bindings for 24 hours; a duplicate key returns the original outcome without re-processing. This is not a courtesy feature — it is a hard requirement for double-entry correctness. Without it, network retries from clients, scheme replays, or queue redelivery can result in duplicated postings, broken balances, and a reconciliation problem that surfaces hours or days later. Coreal's gateway rejects unkeyed mutating requests at the boundary; internal services must surface a key on every retryable operation.