Multi-Tenancy
IOTA SDK implements multi-tenancy to serve multiple organizations (tenants) from a single deployment while maintaining complete data isolation.
Architecture Overview
Tenant Identification
Subdomain-Based Routing
Tenants are identified by subdomain:
tenant-a.iota-sdk.com → Tenant A
tenant-b.iota-sdk.com → Tenant B
tenant-c.iota-sdk.com → Tenant CTenant Resolution Flow
Data Isolation
Row-Level Isolation
The platform uses a shared database schema with row-level isolation via tenant_id. All tenant-scoped tables include a tenant_id column, and queries add WHERE tenant_id = ? so each tenant only sees their own data. There are no per-tenant PostgreSQL schemas or SET search_path switching.
Automatic Query Filtering
All database queries automatically include tenant filters:
Tenant Context
Context Propagation
Tenant ID flows through the request context:
Context Safety
Tenant context is:
- Set once per request
- Immutable after setting
- Passed to all layers
- Used in all queries
Shared Resources
Cross-Tenant Services
Some services operate across tenants:
Shared Entities
Certain entities are shared across tenants:
| Entity | Sharing | Purpose |
|---|---|---|
| Currency | Global | ISO standard codes |
| Settings Schema | Template | Default settings structure |
| Permissions | Template | RBAC definitions |
Tenant Lifecycle
Creating a Tenant
Tenant Operations
| Operation | Effect | Access |
|---|---|---|
| Create | New tenant record, data isolation via tenant_id | Superadmin only |
| Suspend | Block all access | Superadmin only |
| Delete | Remove tenant data (row-level) | Superadmin only |
| Backup | Export tenant data | Superadmin only |
| Settings | Configure tenant | Tenant admin |
Security Considerations
Data Leakage Prevention
Security Layers
- Authentication - Valid session/token required
- Tenant Assignment - User belongs to tenant
- Permission Check - User has required permission
- Query Filtering - All queries scoped to tenant
Tenant-Aware Features
Localization
Each tenant can have different defaults:
| Setting | Scope | Example |
|---|---|---|
| Language | Tenant | English, Russian, Uzbek |
| Currency | Tenant | USD, UZS, EUR |
| Timezone | Tenant | UTC+5, UTC+3 |
Customization
Tenants can customize:
- Branding (logos, colors)
- Feature flags (enable/disable modules)
- Default settings (date formats, number formats)
- Custom fields (extend entities)
Implementation Details
Database and Migrations
The implementation uses a single shared schema and one connection pool. Isolation is row-level only (all tenant-scoped tables have tenant_id; queries use WHERE tenant_id = ?). There is no per-tenant schema switching or SET search_path. Migrations are applied once to the shared schema; a single migration history table tracks applied versions.
Performance Considerations
Connection Pooling
- Single shared pool across all tenants
- No per-tenant connection or schema context
Query Optimization
- Include
tenant_idin indexes for tenant-scoped tables - Consider partitioning by
tenant_idfor tables that exceed measurable thresholds (for example, more than 100 million rows or 100GB) or when per-tenant query/maintenance latency degrades beyond acceptable limits
Best Practices
- Never Bypass Tenant Context - Always use middleware and include
tenant_idin WHERE clauses - Test with Multiple Tenants - Ensure isolation in tests
- Monitor Per-Tenant - Track usage and performance per tenant where needed
Next Steps
- Domain-Driven Design - How DDD works with multi-tenancy
- Module System - Module registration in multi-tenant setup