Multi-Tenancy
Signia's multi-tenant architecture allows you to manage multiple organizations with isolated user bases and independent configurations.
What is Multi-Tenancy?
Multi-tenancy is a software architecture where a single instance serves multiple customers (tenants), each with isolated data and configuration.
Hierarchy
Tenant (Organization)
├── Applications
│ ├── Web App
│ ├── Mobile App
│ └── Admin Portal
└── Users
├── user@example.com
├── admin@example.com
└── developer@example.com
Key Concepts:
- Tenant - An organization (e.g., "Acme Corp")
- Subdomain - Unique identifier (e.g.,
acme.signiaauth.com) - Applications - Apps within the tenant
- Users - Belong to a tenant, can access multiple apps
Tenant Structure
Tenant Configuration
Each tenant has:
-
Subdomain - Unique identifier
acme.signiaauth.com -
Name - Display name
Acme Corporation -
Settings - Independent configuration
- Security policies
- Branding
- Token lifetimes
- Allowed authentication methods
-
Applications - OAuth2/OIDC clients
-
Users - Tenant-specific user base
Setting Up a Tenant
Creating a Tenant
Creating a tenant is self-service - no need to contact support!
Required Information:
- Organization name
- Subdomain (must be unique)
- Admin email
- Billing information (if applicable)
Steps:
- Sign up at signiaid.com
- Complete the registration form
- Choose your unique subdomain
- Verify your email
- Your tenant is ready to use!
Subdomain Rules:
- 3-63 characters
- Lowercase letters, numbers, hyphens
- Cannot start/end with hyphen
- Must be globally unique
✅ acme
✅ acme-corp
✅ my-company-2024
❌ Acme (uppercase)
❌ acme_corp (underscore)
❌ -acme (starts with hyphen)
❌ ac (too short)
Tenant URL Structure
Each tenant has unique URLs:
Auth Server:
https://acme.signiaauth.com
Dashboard:
https://signiaid.com
OIDC Discovery:
https://acme.signiaauth.com/.well-known/openid-configuration
Tenant Isolation
Data Isolation
Tenants are completely isolated:
- ✅ Separate databases or schemas
- ✅ Isolated user bases
- ✅ Independent configurations
- ✅ No cross-tenant data access
Security Boundaries
Tenant A Tenant B
├── Users ├── Users
│ ├── alice@a.com │ ├── bob@b.com
│ └── charlie@a.com │ └── diane@b.com
├── Apps ├── Apps
│ └── App 1 │ └── App 1
└── Settings └── Settings
└── Policy A └── Policy B
❌ Alice cannot access Tenant B
❌ Bob cannot access Tenant A apps
❌ Tenant A settings don't affect Tenant B
Tenant Configuration
Branding
Customize the authentication experience:
Logo:
- Upload custom logo
- Displayed on login screen
- Recommended: 200x50px PNG
Colors:
- Primary color
- Button color
- Background color
Domain:
- Custom domain (Enterprise)
auth.acme.com
Security Policies
Configure tenant-specific security:
Password Policies (if using passwords):
- Minimum length
- Complexity requirements
- Expiration period
- History prevention
Session Policies:
- Session timeout
- Concurrent sessions limit
- Remember device duration
Authentication Methods:
- WebAuthn/Passkeys (enabled by default)
- Magic links
- Social logins
- SAML (Enterprise)
- LDAP/Active Directory (Enterprise)
Token Configuration
Independent token settings per tenant:
Access Tokens:
- Lifetime: 1 hour - 24 hours
- Refresh rotation: enabled/disabled
- Claims included
ID Tokens:
- Lifetime: 1 hour - 24 hours
- Custom claims
Refresh Tokens:
- Lifetime: 1 day - 90 days
- Rotation policy
Multi-Tenant Applications
Single Application, Multiple Tenants
Your application can serve multiple tenants:
// Determine tenant from subdomain
const tenant = req.hostname.split('.')[0]; // "acme" from "acme.myapp.com"
// Configure OIDC client dynamically
const oidcClient = new OIDCClient({
clientId: process.env.OIDC_CLIENT_ID,
redirectUri: `https://${tenant}.myapp.com/oidc-callback`,
issuer: `https://${tenant}.signiaauth.com`, // Tenant-specific issuer
scopes: ['openid', 'profile', 'email']
});
Tenant Discovery
Automatically detect tenant:
Option 1: Subdomain-based
https://acme.myapp.com → tenant: acme
https://xyz.myapp.com → tenant: xyz
Option 2: Path-based
https://myapp.com/acme → tenant: acme
https://myapp.com/xyz → tenant: xyz
Option 3: User email domain
user@acme.com → tenant: acme
user@xyz.com → tenant: xyz
Tenant Mapping
Store tenant configuration:
const tenantConfig = {
'acme': {
name: 'Acme Corp',
issuer: 'https://acme.signiaauth.com',
clientId: 'acme-client-id',
branding: {
logo: '/logos/acme.png',
primaryColor: '#FF5722'
}
},
'xyz': {
name: 'XYZ Inc',
issuer: 'https://xyz.signiaauth.com',
clientId: 'xyz-client-id',
branding: {
logo: '/logos/xyz.png',
primaryColor: '#2196F3'
}
}
};
// Get tenant config
const config = tenantConfig[tenant];
User Management Across Tenants
Single User, Multiple Tenants
Users can belong to multiple tenants:
{
"email": "user@example.com",
"tenants": [
{
"id": "acme",
"role": "admin"
},
{
"id": "xyz",
"role": "member"
}
]
}
Tenant Switching
Allow users to switch between tenants:
function TenantSwitcher() {
const { userTenants, currentTenant, switchTenant } = useSigniaAuth();
return (
<select
value={currentTenant}
onChange={(e) => switchTenant(e.target.value)}
>
{userTenants.map(tenant => (
<option key={tenant.id} value={tenant.id}>
{tenant.name}
</option>
))}
</select>
);
}
Tenant Administration
Admin Roles
Platform Admin:
- Can create/delete tenants
- Can view all tenants
- Cannot access tenant data
Tenant Admin:
- Full access to their tenant
- Can manage users and apps
- Cannot access other tenants
Tenant Settings
Access tenant settings from dashboard:
- Navigate to Settings → Tenant
- View/edit tenant configuration
- Requires tenant admin role
Configurable:
- Organization name
- Subdomain (contact support)
- Branding
- Security policies
- Billing settings
Usage Monitoring
Track tenant usage:
Metrics:
- Active users (monthly)
- Total authentications
- API calls
- Storage used
Billing:
- Per-user pricing
- Overage charges
- Invoice history
Enterprise Features
Custom Domains
Use your own domain for authentication:
Setup:
- Purchase custom domain
- Create CNAME record:
auth.acme.com → acme.signiaauth.com - Contact Signia support to enable
- SSL certificate automatically provisioned
Benefits:
- Branded experience
- Consistent domain for users
- Better trust
Dedicated Infrastructure
For high-volume tenants:
- Dedicated database
- Isolated compute resources
- Custom SLA
- Priority support
Private Deployment
Run Signia in your infrastructure:
- On-premises deployment
- Private cloud (VPC)
- Full data control
- Custom compliance requirements
Best Practices
1. Tenant Identification
Choose the right tenant identification strategy:
Subdomain-based (Recommended):
✅ Clear separation
✅ Tenant branding possible
✅ SSL per tenant
Path-based:
⚠️ Single SSL cert
⚠️ Shared cookies
✅ Easier setup
2. Configuration Management
Store tenant configs centrally:
// Database-driven config
const config = await db.tenants.findOne({ subdomain: 'acme' });
// Cache for performance
const cache = new Map();
3. Error Handling
Handle tenant not found gracefully:
if (!tenantExists(tenant)) {
return res.status(404).render('tenant-not-found');
}
4. Testing
Test with multiple tenants:
describe('Multi-tenant auth', () => {
it('should isolate tenant A from tenant B', async () => {
// Login to tenant A
// Attempt to access tenant B
// Should be denied
});
});
Migration Strategies
From Single-Tenant to Multi-Tenant
Steps:
-
Add tenant_id column
ALTER TABLE users ADD COLUMN tenant_id VARCHAR(255);
ALTER TABLE applications ADD COLUMN tenant_id VARCHAR(255); -
Migrate existing data
UPDATE users SET tenant_id = 'default';
UPDATE applications SET tenant_id = 'default'; -
Update application logic
// Before
const users = await db.users.find();
// After
const users = await db.users.find({ tenant_id: currentTenant }); -
Add tenant middleware
app.use(tenantMiddleware);
Troubleshooting
"Tenant not found"
Cause: Invalid or non-existent tenant subdomain
Solution:
- Verify subdomain spelling
- Check tenant is active
- Contact admin if recently created
Cross-tenant access attempt
Cause: User trying to access another tenant
Solution:
- Check tenant ID in request
- Verify user belongs to tenant
- Review session data
Configuration not applying
Cause: Config cached or not saved
Solution:
- Clear config cache
- Save and refresh dashboard
- Check tenant ID in config
Next Steps
- Security Best Practices - Comprehensive security
- Dashboard Guide - Manage tenants
- Quick Start - Integrate authentication