Tenant Settings
Each tenant can have custom configuration settings that control behavior and features.
Settings Model
Settings are stored as a JSON object, allowing flexible configuration:
interface TenantSettings {
security?: {
mfaRequired?: boolean;
passwordExpiryDays?: number;
maxConcurrentSessions?: number;
allowedIpRanges?: string[];
};
features?: {
auditLogRetentionDays?: number;
maxOrganizations?: number;
maxUsersPerOrganization?: number;
};
branding?: {
primaryColor?: string;
logoUrl?: string;
supportEmail?: string;
};
}
Get Tenant Settings
Endpoint
GET /tenants/:id/settings
Response (200 OK)
{
"security": {
"mfaRequired": false,
"passwordExpiryDays": 90,
"maxConcurrentSessions": 5,
"allowedIpRanges": []
},
"features": {
"auditLogRetentionDays": 90,
"maxOrganizations": 10,
"maxUsersPerOrganization": 100
},
"branding": {
"primaryColor": "#6366f1",
"logoUrl": null,
"supportEmail": "support@acme.com"
}
}
Update Tenant Settings
Settings are merged (not replaced) on update.
Endpoint
PATCH /tenants/:id/settings
Request
{
"security": {
"mfaRequired": true
},
"features": {
"auditLogRetentionDays": 365
}
}
Response (200 OK)
{
"security": {
"mfaRequired": true,
"passwordExpiryDays": 90,
"maxConcurrentSessions": 5,
"allowedIpRanges": []
},
"features": {
"auditLogRetentionDays": 365,
"maxOrganizations": 10,
"maxUsersPerOrganization": 100
},
"branding": {
"primaryColor": "#6366f1",
"logoUrl": null,
"supportEmail": "support@acme.com"
}
}
Merge Behavior
Only the fields you provide are updated. Existing fields are preserved. This allows partial updates without needing to send the entire settings object.
Available Settings
Security Settings
| Setting | Type | Default | Description |
|---|---|---|---|
mfaRequired | boolean | false | Require MFA for all users |
passwordExpiryDays | number | 90 | Days until password expires (0 = never) |
maxConcurrentSessions | number | 5 | Max active sessions per user |
allowedIpRanges | string[] | [] | IP allowlist (CIDR notation) |
Feature Settings
| Setting | Type | Default | Description |
|---|---|---|---|
auditLogRetentionDays | number | 90 | Days to retain audit logs |
maxOrganizations | number | 10 | Max organizations in tenant |
maxUsersPerOrganization | number | 100 | Max users per organization |
Branding Settings
| Setting | Type | Default | Description |
|---|---|---|---|
primaryColor | string | #6366f1 | Primary brand color (hex) |
logoUrl | string | null | URL to logo image |
supportEmail | string | null | Support contact email |
Code Examples
TypeScript
interface TenantSettings {
security?: {
mfaRequired?: boolean;
passwordExpiryDays?: number;
maxConcurrentSessions?: number;
allowedIpRanges?: string[];
};
features?: {
auditLogRetentionDays?: number;
maxOrganizations?: number;
maxUsersPerOrganization?: number;
};
branding?: {
primaryColor?: string;
logoUrl?: string;
supportEmail?: string;
};
}
// Get settings
async function getTenantSettings(
accessToken: string,
tenantId: string
): Promise<TenantSettings> {
const response = await fetch(
`http://localhost:8091/tenants/${tenantId}/settings`,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
},
}
);
return response.json();
}
// Update settings
async function updateTenantSettings(
accessToken: string,
tenantId: string,
settings: Partial<TenantSettings>
): Promise<TenantSettings> {
const response = await fetch(
`http://localhost:8091/tenants/${tenantId}/settings`,
{
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
},
body: JSON.stringify(settings),
}
);
return response.json();
}
// Usage: Enable MFA requirement
await updateTenantSettings(token, tenantId, {
security: { mfaRequired: true },
});
cURL
# Get settings
curl http://localhost:8091/tenants/f47ac10b-58cc-4372-a567-0e02b2c3d479/settings \
-H "Authorization: Bearer <access-token>"
# Update settings
curl -X PATCH http://localhost:8091/tenants/f47ac10b-58cc-4372-a567-0e02b2c3d479/settings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"security": {
"mfaRequired": true,
"passwordExpiryDays": 60
}
}'
Settings Validation
Settings are validated on update:
// Invalid request
{
"security": {
"passwordExpiryDays": -1
}
}
// Error response
{
"type": "https://api.cortex.purplelab.ai/errors/validation",
"title": "Validation Error",
"status": 400,
"detail": "passwordExpiryDays must be a non-negative number"
}
Default Settings
When a tenant is created, it receives default settings:
{
"security": {
"mfaRequired": false,
"passwordExpiryDays": 90,
"maxConcurrentSessions": 5,
"allowedIpRanges": []
},
"features": {
"auditLogRetentionDays": 90,
"maxOrganizations": 10,
"maxUsersPerOrganization": 100
},
"branding": {
"primaryColor": "#6366f1",
"logoUrl": null,
"supportEmail": null
}
}