Multi-Tenancy
Ithbat IAM is designed for multi-tenant SaaS and enterprise identity. Every tenant is an isolated identity namespace — its own users, roles, groups, settings, branding, audit logs, and data. Tenants never share user records or session tokens.
Architecture overview
graph TD
subgraph Global Platform
PlatformAdmin[Platform Admin]
BillingService[Billing Service]
end
subgraph Tenant A
UsersA[Users]
RolesA[Roles & Permissions]
BrandingA[Custom Branding]
SAMLA[SAML Config]
AuditA[Audit Logs]
end
subgraph Tenant B
UsersB[Users]
RolesB[Roles & Permissions]
BrandingB[Custom Branding]
SAMLB[SAML Config]
AuditB[Audit Logs]
end
PlatformAdmin --> |manages| TenantA
PlatformAdmin --> |manages| TenantB
BillingService --> TenantA
BillingService --> TenantB
Data isolation
Ithbat uses PostgreSQL Row-Level Security (RLS) to enforce tenant isolation at the database layer. The current tenant ID is set in the PostgreSQL session (SET LOCAL app.current_tenant_id = '...') before every query, and RLS policies ensure that queries return only rows belonging to that tenant. Even if an application-level bug allowed a cross-tenant query, the database layer enforces isolation.
Enterprise tenants on dedicated plans receive a fully separate database instance.
Tenant creation and setup
Registering a tenant (self-service)
POST /api/v1/tenants/register
Content-Type: application/json
{
"name": "Acme Corp",
"slug": "acme",
"adminEmail": "[email protected]",
"adminFirstName": "Omar",
"adminLastName": "Hassan",
"plan": "growth",
"region": "ksa"
}
The slug becomes the tenant's subdomain: acme.ithbat.io. It must be unique, lowercase, and contain only letters, numbers, and hyphens.
After registration, the admin email receives an invitation to set up their account.
Creating a tenant via platform API
Platform administrators can create tenants directly:
POST /api/v1/tenants
Authorization: Bearer {platform_admin_token}
Content-Type: application/json
{
"name": "Acme Corp",
"slug": "acme",
"plan": "enterprise",
"region": "ksa"
}
Subdomain routing
Every tenant gets a subdomain at {slug}.ithbat.io. The hosted authentication pages (login, registration, MFA, password reset) are served on this subdomain, branded with the tenant's colors and logo.
| URL | What it serves |
|---|---|
acme.ithbat.io | Tenant login page |
acme.ithbat.io/register | Self-service registration |
acme.ithbat.io/forgot-password | Password reset |
The subdomain resolves the tenant context automatically — no need to pass a tenant ID in the URL for hosted authentication flows.
Custom domains
Tenants on Growth and Enterprise plans can use their own domain for the hosted authentication UI.
Step 1 — Add the custom domain
POST /api/v1/tenant/custom-domain
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json
{
"domain": "auth.acme.com"
}
Response includes a DNS verification record:
{
"domain": "auth.acme.com",
"verificationToken": "ithbat-verify=abc123xyz",
"verificationRecord": {
"type": "TXT",
"name": "_ithbat-challenge.auth.acme.com",
"value": "abc123xyz"
},
"status": "pending"
}
Step 2 — Add DNS records
At your DNS provider, add:
| Type | Name | Value |
|---|---|---|
TXT | _ithbat-challenge.auth.acme.com | abc123xyz |
CNAME | auth.acme.com | acme.ithbat.io |
DNS propagation typically takes 5–30 minutes.
Step 3 — Verify the domain
POST /api/v1/tenant/custom-domain/verify
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Ithbat checks for the TXT record. On success, the domain is activated and Ithbat automatically provisions an SSL/TLS certificate.
Get custom domain status
GET /api/v1/tenant/custom-domain
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Remove a custom domain
DELETE /api/v1/tenant/custom-domain
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Tenant branding
Customize the tenant's hosted UI with your own logo, colors, and favicon.
PATCH /api/v1/tenant/settings/branding
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json
{
"logoUrl": "https://cdn.acme.com/logo.svg",
"faviconUrl": "https://cdn.acme.com/favicon.ico",
"primaryColor": "#0B7285",
"accentColor": "#C8943F",
"backgroundColor": "#F7FAFB",
"companyName": "Acme Corp"
}
Branding is applied immediately on the tenant's hosted authentication pages.
Data residency
Ithbat IAM offers three deployment regions. When a tenant is created, the region field determines where their data is stored and processed. Data does not cross regions.
| Region code | Location | Infrastructure |
|---|---|---|
global | EU (Frankfurt) | CranL Global |
ksa | Riyadh, Saudi Arabia | CranL KSA — data stays in-Kingdom |
egypt | Cairo, Egypt | CranL Egypt |
Available regions:
GET /api/v1/regions
[
{ "code": "global", "name": "Global (EU)", "available": true },
{ "code": "ksa", "name": "Saudi Arabia (KSA)", "available": true },
{ "code": "egypt", "name": "Egypt", "available": true }
]
KSA and Egypt regions are operated on CranL infrastructure, meeting local data residency requirements. For customers subject to PDPL (Saudi Arabia) or Egypt's data protection rules, use the ksa or egypt region respectively.
Tenant settings
Get general settings
GET /api/v1/tenant/settings
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Update general settings
PATCH /api/v1/tenant/settings/general
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json
{
"name": "Acme Corp",
"defaultLanguage": "en",
"allowRegistration": true,
"requireEmailVerification": true,
"sessionTimeout": 3600
}
Update security settings
PATCH /api/v1/tenant/settings/security
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json
{
"requireMfa": false,
"allowedAuthMethods": ["password", "saml", "google"],
"ipWhitelistEnabled": false
}
Organizations within a tenant
Organizations are sub-units within a tenant — departments, customers, or regional divisions. A tenant can have multiple organizations. Users can belong to multiple organizations with different roles in each.
Create an organization
POST /api/v1/organizations
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json
{
"name": "Engineering",
"description": "Product engineering team"
}
Add a user to an organization
POST /api/v1/organizations/{orgId}/members
Authorization: Bearer {token}
Content-Type: application/json
{
"userId": "3fa85f64-...",
"roles": ["role-id-1"]
}
List organizations
GET /api/v1/organizations
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Tenant lifecycle
Suspend a tenant
Suspension prevents all authentication for the tenant's users. Existing data is preserved.
POST /api/v1/tenants/{id}/suspend
Authorization: Bearer {platform_admin_token}
Reactivate a tenant
POST /api/v1/tenants/{id}/reactivate
Authorization: Bearer {platform_admin_token}
Update tenant metadata
Attach arbitrary key-value metadata to a tenant for your own tracking purposes:
PATCH /api/v1/tenants/{id}/metadata
Authorization: Bearer {platform_admin_token}
Content-Type: application/json
{
"salesforceId": "0015000000XYZ",
"contractEndDate": "2027-12-31"
}
Delete a tenant
Tenant deletion is permanent and irreversible. All users, sessions, audit logs, and settings are permanently removed.
DELETE /api/v1/tenants/{id}
Authorization: Bearer {platform_admin_token}
Tenant API reference summary
| Method | Endpoint | Permission |
|---|---|---|
POST | /api/v1/tenants/register | Public |
GET | /api/v1/tenants/current | tenant:read |
GET | /api/v1/tenants/{id}/stats | tenant:read |
GET | /api/v1/tenants | tenant:write |
POST | /api/v1/tenants | Platform admin |
PUT | /api/v1/tenants/{id} | tenant:write |
DELETE | /api/v1/tenants/{id} | Platform admin |
POST | /api/v1/tenants/{id}/suspend | Platform admin |
POST | /api/v1/tenants/{id}/reactivate | Platform admin |
PATCH | /api/v1/tenants/{id}/metadata | tenant:write |
GET | /api/v1/tenant/settings | settings:read |
PATCH | /api/v1/tenant/settings/general | settings:write |
PATCH | /api/v1/tenant/settings/branding | settings:write |
PATCH | /api/v1/tenant/settings/security | settings:write |
POST | /api/v1/tenant/custom-domain | settings:write |
POST | /api/v1/tenant/custom-domain/verify | settings:write |
DELETE | /api/v1/tenant/custom-domain | settings:write |
Next steps
- RBAC & Permissions — set up roles and permissions within your tenant
- SAML 2.0 — configure enterprise SSO for your tenant
- Billing — manage your tenant's subscription and plan