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:
| Priority | Method | Example |
|---|---|---|
| 1 | X-Tenant-ID header | X-Tenant-ID: demo_bank |
| 2 | JWT tenant_id claim | Embedded in access token |
| 3 | Subdomain | demobank.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:
| Setting | Description | Default |
|---|---|---|
default_currency | Base currency for the tenant | NGN |
timezone | Timezone for reporting and schedules | Africa/Lagos |
base_interest_rate | Default savings interest rate (%) | 2.5 |
reserve_requirement_ratio | Required reserve ratio | 0.10 |
max_accounts_per_customer | Max accounts a single customer can hold | 10 |
enable_overdraft | Whether overdraft is available | true |
max_overdraft_percentage | Max overdraft as % of balance | 10.0 |
fee_rounding | Rounding mode for fee calculations | ROUND_HALF_UP |
settlement_time_hours | Interbank settlement window | 24 |
Feature Flags
Feature flags enable or disable entire product modules per tenant:
| Flag | Description |
|---|---|
virtual_accounts | Virtual/sub-account management |
international_transfers | SWIFT cross-border transfers |
bill_payment | Bill payment and airtime |
card_issuance | Debit/credit card issuance |
ussd_service | USSD banking channel |
agent_banking | Agent banking network |
islamic_banking | Sharia-compliant products |
trade_finance | Letters of credit, trade finance |
wealth_management | Investment and portfolio management |
biometric_auth | Biometric 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
}
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
- Authentication — How JWT tokens carry tenant context.
- Accounts — Account management within a tenant.
- General Ledger — Per-tenant chart of accounts and journals.