Skip to main content

Tenant Management

Guide for managing tenants in the Burdenoff platform.

Creating a Tenant

Via API

curl -X POST https://api.burdenoff.com/tenants \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corporation",
"domain": "acme.com",
"plan": "enterprise",
"admin_email": "[email protected]"
}'

Via Admin Portal

  1. Login to Workspaces admin portal
  2. Navigate to Tenants
  3. Click "Create Tenant"
  4. Fill in tenant details
  5. Configure initial settings
  6. Assign plan and limits
  7. Create tenant

Tenant Configuration

Basic Settings

{
"name": "Acme Corporation",
"domain": "acme.com",
"status": "active",
"plan_id": "enterprise-plan-id"
}

Branding

{
"branding": {
"logo_url": "https://...",
"primary_color": "#3B82F6",
"secondary_color": "#10B981",
"company_name": "Acme Corp"
}
}

Feature Flags

{
"features": {
"sso": true,
"api_access": true,
"custom_domain": true,
"white_label": false,
"advanced_analytics": true
}
}

Resource Limits

{
"limits": {
"max_users": 100,
"max_storage_gb": 500,
"api_rate_limit": 1000,
"max_projects": 50
}
}

User Management

Adding Users

async def add_user_to_tenant(
tenant_id: str,
email: str,
role: str = "member"
):
user = await create_or_get_user(email)
await db.tenant_users.create({
"tenant_id": tenant_id,
"user_id": user.id,
"role": role
})
await send_invitation_email(user.email, tenant_id)

Roles

  • Owner: Full access, billing, user management
  • Admin: User management, settings
  • Member: Product access, no admin
  • Viewer: Read-only access

Removing Users

async def remove_user_from_tenant(
tenant_id: str,
user_id: str
):
await db.tenant_users.delete({
"tenant_id": tenant_id,
"user_id": user_id
})
await revoke_user_sessions(user_id, tenant_id)

Quota Management

Monitoring Usage

async def get_tenant_usage(tenant_id: str):
return {
"users": await count_tenant_users(tenant_id),
"storage_bytes": await calculate_storage(tenant_id),
"api_calls_today": await count_api_calls(tenant_id),
"active_projects": await count_projects(tenant_id)
}

Enforcing Limits

async def check_quota(tenant_id: str, resource: str):
config = await get_tenant_config(tenant_id)
usage = await get_tenant_usage(tenant_id)

limit = config.limits.get(resource)
current = usage.get(resource)

if current >= limit:
raise QuotaExceededError(
f"{resource} quota exceeded: {current}/{limit}"
)

Quota Alerts

  • 80% threshold: Warning email
  • 95% threshold: Critical alert
  • 100% threshold: Feature disabled

Billing Integration

Subscription Plans

PLANS = {
"free": {
"price": 0,
"limits": {
"users": 5,
"storage_gb": 10,
"api_calls": 1000
}
},
"professional": {
"price": 49,
"limits": {
"users": 50,
"storage_gb": 100,
"api_calls": 10000
}
},
"enterprise": {
"price": 299,
"limits": {
"users": -1, # unlimited
"storage_gb": 1000,
"api_calls": 100000
}
}
}

Usage-Based Billing

async def calculate_monthly_bill(tenant_id: str):
config = await get_tenant_config(tenant_id)
usage = await get_monthly_usage(tenant_id)

base_price = PLANS[config.plan]["price"]

# Overage charges
overage = 0
if usage.storage_gb > config.limits.storage_gb:
overage += (usage.storage_gb - config.limits.storage_gb) * 0.1

return base_price + overage

Tenant Lifecycle

Activation

async def activate_tenant(tenant_id: str):
await db.tenants.update(tenant_id, {
"status": "active",
"activated_at": datetime.utcnow()
})
await provision_tenant_resources(tenant_id)
await send_activation_email(tenant_id)

Suspension

async def suspend_tenant(tenant_id: str, reason: str):
await db.tenants.update(tenant_id, {
"status": "suspended",
"suspension_reason": reason,
"suspended_at": datetime.utcnow()
})
await revoke_all_tenant_sessions(tenant_id)
await send_suspension_email(tenant_id, reason)

Deletion

async def delete_tenant(tenant_id: str):
# Export data
await export_tenant_data(tenant_id)

# Delete user associations
await db.tenant_users.delete_all(tenant_id)

# Delete tenant data
await delete_tenant_resources(tenant_id)

# Soft delete tenant record
await db.tenants.update(tenant_id, {
"status": "deleted",
"deleted_at": datetime.utcnow()
})

Data Migration

Export Tenant Data

async def export_tenant_data(tenant_id: str):
data = {
"tenant": await db.tenants.get(tenant_id),
"users": await db.users.find(tenant_id=tenant_id),
"products": {}
}

for product in PRODUCTS:
data["products"][product] = await export_product_data(
tenant_id, product
)

return data

Import Tenant Data

async def import_tenant_data(tenant_id: str, data: dict):
# Import users
for user_data in data["users"]:
await import_user(tenant_id, user_data)

# Import product data
for product, product_data in data["products"].items():
await import_product_data(tenant_id, product, product_data)

Monitoring & Alerts

Health Checks

async def check_tenant_health(tenant_id: str):
checks = {
"database": await check_database_connection(tenant_id),
"storage": await check_storage_available(tenant_id),
"api": await check_api_responsive(tenant_id)
}
return all(checks.values())

Activity Monitoring

async def monitor_tenant_activity(tenant_id: str):
metrics = {
"active_users": await count_active_users(tenant_id),
"api_calls_per_hour": await count_api_calls(tenant_id, hours=1),
"error_rate": await calculate_error_rate(tenant_id),
"avg_response_time": await calculate_avg_response_time(tenant_id)
}
return metrics

Next Steps