Skip to main content

Multi-Tenancy

Each tenant in Kora CBA gets a dedicated PostgreSQL database. The platform database stores the tenant registry, and the API gateway resolves every request to the correct tenant database at runtime.

Tenant Resolution​

The gateway resolves the current tenant using:

PriorityMethodExample
1X-Tenant-ID headerX-Tenant-ID: demo_bank
2JWT tenant_id claimEmbedded in access token
3Subdomaindemobank.cba-platform.com

For API integrations, always send the X-Tenant-ID header explicitly.

Database Isolation​

┌──────────────────────────────┐
│ Platform Database │
│ ┌────────────────────────┐ │
│ │ platform.tenants │ │
│ │ platform.api_keys │ │
│ │ platform.webhooks │ │
│ │ platform.audit_log │ │
│ └────────────────────────┘ │
└──────────────────────────────┘

┌─────────────────┐ ┌─────────────────┐
│ tenant_demo_bank│ │ tenant_acme_bank│
│ │ │ │
│ gl.accounts │ │ gl.accounts │
│ gl.journals │ │ gl.journals │
│ account.accounts│ │ account.accounts│
│ transaction.* │ │ transaction.* │
└─────────────────┘ └─────────────────┘
  • Platform database — Shared tenant registry, API keys, webhook subscriptions, and platform audit logs.
  • Tenant databases — Fully isolated. Each tenant has its own GL chart of accounts, customer records, account balances, and transactions.
  • Row-level security — PostgreSQL RLS policies enforce tenant boundaries within each database as an additional safety layer.

Tenant Object​

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"code": "demo_bank",
"name": "Demo Bank Ltd",
"status": "active",
"config": {
"default_currency": "NGN",
"timezone": "Africa/Lagos",
"base_interest_rate": 2.5,
"reserve_requirement_ratio": 0.10,
"max_accounts_per_customer": 10,
"enable_overdraft": true,
"max_overdraft_percentage": 10.0,
"fee_rounding": "ROUND_HALF_UP",
"settlement_time_hours": 24
},
"branding": {
"logo_url": "https://cdn.korastratum.com/demo_bank/logo.png",
"primary_color": "#003366"
},
"feature_flags": {
"virtual_accounts": true,
"international_transfers": false,
"biometric_auth": false,
"islamic_banking": false,
"bill_payment": true,
"card_issuance": true,
"ussd_service": true,
"agent_banking": false,
"trade_finance": false,
"wealth_management": true
},
"regulatory_config": {
"reserve_requirement_ratio": 0.10,
"compliance_level": "tier1"
}
}

Tenant Configuration​

Tenant-level settings control default behaviour across services:

SettingDescriptionDefault
default_currencyBase currency for the tenantNGN
timezoneTimezone for reporting and schedulesAfrica/Lagos
base_interest_rateDefault savings interest rate (%)2.5
reserve_requirement_ratioRequired reserve ratio0.10
max_accounts_per_customerMax accounts a single customer can hold10
enable_overdraftWhether overdraft is availabletrue
max_overdraft_percentageMax overdraft as % of balance10.0
fee_roundingRounding mode for fee calculationsROUND_HALF_UP
settlement_time_hoursInterbank settlement window24

Feature Flags​

Feature flags enable or disable entire product modules per tenant:

FlagDescription
virtual_accountsVirtual/sub-account management
international_transfersSWIFT cross-border transfers
bill_paymentBill payment and airtime
card_issuanceDebit/credit card issuance
ussd_serviceUSSD banking channel
agent_bankingAgent banking network
islamic_bankingSharia-compliant products
trade_financeLetters of credit, trade finance
wealth_managementInvestment and portfolio management
biometric_authBiometric authentication

Requests to disabled features return 403 Forbidden.

Integration Configuration​

Each tenant can configure third-party integration providers (e.g., NIP providers, SMS gateways, payment processors) at the tenant level.

Get Integration Config​

GET /api/v1/platform/tenants/:id/integrations/:provider

Update Integration Config​

PUT /api/v1/platform/tenants/:id/integrations/:provider
{
"provider": "interswitch",
"enabled": true,
"config": {
"client_id": "ISW-XXXXXX",
"base_url": "https://qa.interswitchng.com",
"timeout_ms": 30000,
"retry_count": 3
},
"is_primary": true
}
note

Integration credentials are encrypted at rest. The config object varies by provider — refer to each provider's setup guide for required fields. Changes take effect immediately for all new requests.

Next Steps​