Tenant Administration
Tenant Administration
Section titled “Tenant Administration”Day-to-day management of tenants in Mantis.
Overview
Section titled “Overview”Tenant administration covers ongoing management tasks:
Viewing Tenants
Section titled “Viewing Tenants”List All Tenants
Section titled “List All Tenants”curl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants"Response:
{ "data": [ { "id": "019b937d-4862-84ae-9c2a-6ac230cc4c7e", "name": "Acme Corp", "description": "Enterprise customer", "contact_email": "ops@acme.com", "created_at": "2024-01-15T10:30:00Z" }, { "id": "019b937d-4862-84ae-9c2a-6ac230cc4c80", "name": "Globex Inc", "description": "SMB customer", "contact_email": "admin@globex.com", "created_at": "2024-01-20T14:00:00Z" } ], "meta": { "total": 2, "page": 1, "limit": 20 }}Get Tenant Details
Section titled “Get Tenant Details”curl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID"Response includes relationships:
{ "id": "019b937d-4862-84ae-9c2a-6ac230cc4c7e", "name": "Acme Corp", "description": "Enterprise customer", "contact_email": "ops@acme.com", "logo_url": "https://acme.com/logo.png", "tags": [ { "id": "tag_region", "key": "region", "value": "us-east" }, { "id": "tag_tier", "key": "tier", "value": "enterprise" } ], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-02-01T09:15:00Z"}Updating Tenants
Section titled “Updating Tenants”Update Tenant Details
Section titled “Update Tenant Details”curl -X PUT \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Acme Corporation", "description": "Updated enterprise customer description", "contact_email": "newops@acme.com" }' \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID"Update Fields
Section titled “Update Fields”| Field | Update Behavior |
|---|---|
name | Must remain unique |
description | Set to null to clear |
contact_email | Set to null to clear |
logo_url | Set to null to clear |
Via Lens UI
Section titled “Via Lens UI”- Navigate to Admin → Tenants
- Click on the tenant name
- Click Edit
- Update fields
- Click Save
Managing Entitlements
Section titled “Managing Entitlements”View Current Entitlements
Section titled “View Current Entitlements”# List solutionscurl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/solutions"
# List targetscurl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/targets"
# List environmentscurl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/environments"Add Solution Entitlement
Section titled “Add Solution Entitlement”curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "solution_id": "sol_newfeature", "environment_id": "env_staging" }' \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/solutions"Remove Solution Entitlement
Section titled “Remove Solution Entitlement”curl -X DELETE \ -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/solutions/$SOLUTION_ID/environments/$ENV_ID"Entitlement Matrix
Section titled “Entitlement Matrix”Document tenant entitlements:
| Tenant | Solution | Production | Staging | Development |
|---|---|---|---|---|
| Acme Corp | WebApp | ✓ | ✓ | ✗ |
| Acme Corp | API | ✓ | ✓ | ✗ |
| Globex Inc | WebApp | ✓ | ✗ | ✗ |
Managing Variables
Section titled “Managing Variables”View All Variables
Section titled “View All Variables”curl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/variables"Update Variable
Section titled “Update Variable”# Update existing variable (POST upserts)curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "variable_type": "common", "template_id_or_key": "api_url", "value": "https://api-v2.acme.com", "is_encrypted": false }' \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/variables"Delete Variable
Section titled “Delete Variable”curl -X DELETE \ -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/variables/$VARIABLE_ID?variable_type=common"Rotate Encrypted Variables
Section titled “Rotate Encrypted Variables”For security, rotate sensitive variables periodically:
# Update encrypted variable with new valuecurl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "variable_type": "common", "template_id_or_key": "database_password", "value": "new_secure_password", "is_encrypted": true }' \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/variables"Viewing Deployments
Section titled “Viewing Deployments”List Tenant Deployments
Section titled “List Tenant Deployments”curl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/deployments"Response:
{ "data": [ { "id": "019b937d-4862-8de0-1111-222233334444", "source_type": "solution", "solution_name": "WebApp", "state": "completed", "progress": 1.0, "tenant_name": "Acme Corp", "environment_name": "Production", "created_at": "2024-02-01T10:00:00Z", "completed_at": "2024-02-01T10:05:32Z", "duration_ms": 332000 } ], "meta": { "total": 150, "page": 1, "limit": 20 }}Paginate Deployments
Section titled “Paginate Deployments”# Paginationcurl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID/deployments?page=2&limit=50"State-based filtering is not currently supported on this endpoint. Use the SQL monitoring queries below for status-filtered analysis.
Deployment Statistics
Section titled “Deployment Statistics”Track tenant health with deployment metrics:
SELECT DATE_TRUNC('day', created_at) AS day, COUNT(*) AS total_deployments, SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS successful, SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed, AVG(EXTRACT(EPOCH FROM (completed_at - started_at))) AS avg_duration_secsFROM deployment_historyWHERE tenant_id = $tenant_idAND created_at >= NOW() - INTERVAL '30 days'GROUP BY DATE_TRUNC('day', created_at)ORDER BY day DESC;User Management
Section titled “User Management”List Tenant Users
Section titled “List Tenant Users”curl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/admin/users"System admins see all users; tenant-scoped callers automatically see only users in their tenant, controlled by the caller’s JWT. There is no tenant_id query parameter — filtering is implicit based on the token used.
Add User to Tenant
Section titled “Add User to Tenant”curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "username": "bob", "email": "bob@acme.com", "password": "secure_password", "tenant_id": "019b937d-4862-84ae-9c2a-6ac230cc4c7e", "role_ids": ["role_viewer"] }' \ "https://api.mantis.local/api/v1/admin/users"Move User Between Tenants
Section titled “Move User Between Tenants”curl -X PUT \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "tenant_id": "ten_new_tenant" }' \ "https://api.mantis.local/api/v1/admin/users/$USER_ID"Remove Tenant User
Section titled “Remove Tenant User”Disable rather than delete for audit retention:
curl -X PUT \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"status": "inactive"}' \ "https://api.mantis.local/api/v1/admin/users/$USER_ID"Audit Review
Section titled “Audit Review”View Tenant Audit Logs
Section titled “View Tenant Audit Logs”Audit logs are read from /api/v1/audit/logs. Results are automatically scoped to the
caller’s tenant; an admin with no tenant sees logs across all tenants. There is no
tenant_id query parameter.
curl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/audit/logs"Filter by Category
Section titled “Filter by Category”# Authentication eventscurl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/audit/logs?category=authentication"
# Deployment eventscurl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/audit/logs?category=deployment"
# Security eventscurl -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/audit/logs?severity=security"Export Audit Logs
Section titled “Export Audit Logs”-- Export tenant audit logs for complianceCOPY ( SELECT created_at, event_type, event_category, severity, actor_id, action, outcome, metadata FROM audit_log_entries WHERE tenant_id = $tenant_id AND created_at >= '2024-01-01' AND created_at < '2024-02-01' ORDER BY created_at) TO '/tmp/audit_export.csv' WITH CSV HEADER;Tenant Lifecycle
Section titled “Tenant Lifecycle”Onboarding Checklist
Section titled “Onboarding Checklist”□ Create tenant□ Configure description and contact□ Attach required solutions to environments□ Assign targets□ Set up variables (including encrypted secrets)□ Add tags for organization□ Create initial users□ Configure SSO (if applicable)□ Document tenant configuration□ Notify tenant of accessDeactivation
Section titled “Deactivation”When a tenant needs to be temporarily disabled:
# Remove all solution entitlementsfor SOL_ENV in $(get_tenant_solutions); do curl -X DELETE "$API_URL/tenants/$TENANT_ID/solutions/$SOL_ENV"done
# Disable all tenant users (valid statuses: active, inactive, locked, pending)for USER_ID in $(get_tenant_users); do curl -X PUT -d '{"status": "inactive"}' \ "https://api.mantis.local/api/v1/admin/users/$USER_ID"doneReactivation
Section titled “Reactivation”# Re-enable usersfor USER_ID in $(get_tenant_users); do curl -X PUT -d '{"status": "active"}' \ "https://api.mantis.local/api/v1/admin/users/$USER_ID"done
# Restore entitlementscurl -X POST -d '{"solution_id": "sol_...", "environment_id": "env_..."}' \ "$API_URL/tenants/$TENANT_ID/solutions"Deleting Tenants
Section titled “Deleting Tenants”Prerequisites
Section titled “Prerequisites”Before deletion:
- Export data - Audit logs, deployment history
- Notify stakeholders - Confirm deletion is authorized
- Disable users first - Prevent new activity
- Document decision - For compliance
Deletion Impact
Section titled “Deletion Impact”| Resource | On Tenant Delete |
|---|---|
| Solution-Environment links | Cascade deleted |
| Target assignments | Cascade deleted |
| Tenant variables | Deletion blocked (must be removed first) |
| Common variables | Deletion blocked (must be removed first) |
| Tenant tags | Cascade deleted |
| Users | Not deleted - orphaned |
| Audit logs | Preserved |
| Deployment history | Preserved |
Delete Tenant
Section titled “Delete Tenant”curl -X DELETE \ -H "Authorization: Bearer $TOKEN" \ "https://api.mantis.local/api/v1/tenants/$TENANT_ID"Post-Deletion Cleanup
Section titled “Post-Deletion Cleanup”No manual user cleanup is needed. The users.tenant_id foreign key is
ON DELETE SET NULL, so PostgreSQL automatically clears it when a tenant is
deleted — there are no orphaned users to find afterward. (If you need the list of
affected users, query them BEFORE deleting the tenant.)
Monitoring and Alerts
Section titled “Monitoring and Alerts”Tenant Health Metrics
Section titled “Tenant Health Metrics”Monitor key metrics per tenant:
| Metric | Alert Threshold | Action |
|---|---|---|
| Failed deployments | >3 in 1 hour | Investigate failures |
| Inactive users | >30 days | Review user access |
| Variable changes | Unexpected | Review audit logs |
| Target disconnections | >1 target | Check target health |
SQL Monitoring Queries
Section titled “SQL Monitoring Queries”Failed Deployments by Tenant:
SELECT t.name AS tenant, COUNT(*) AS failed_countFROM deployment_history dhJOIN tenants t ON t.id = dh.tenant_idWHERE dh.status = 'failed'AND dh.created_at >= NOW() - INTERVAL '24 hours'GROUP BY t.nameORDER BY failed_count DESC;Active Users per Tenant:
SELECT t.name AS tenant, COUNT(*) AS active_users, MAX(u.last_login_at) AS latest_loginFROM users uJOIN tenants t ON t.id = u.tenant_idWHERE u.status = 'active'GROUP BY t.name;Bulk Operations
Section titled “Bulk Operations”Batch Update Variables
Section titled “Batch Update Variables”#!/bin/bash# Update variable across all tenants
VARIABLE_KEY="api_version"NEW_VALUE="v2"
for TENANT_ID in $(curl -s "$API_URL/tenants" | jq -r '.data[].id'); do curl -s -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"variable_type\": \"common\", \"template_id_or_key\": \"$VARIABLE_KEY\", \"value\": \"$NEW_VALUE\", \"is_encrypted\": false }" \ "$API_URL/tenants/$TENANT_ID/variables" echo "Updated $TENANT_ID"doneBatch Grant Entitlements
Section titled “Batch Grant Entitlements”#!/bin/bash# Grant new solution to all enterprise tenants
SOLUTION_ID="sol_new_feature"ENVIRONMENT_ID="env_production"
# Get tenants with enterprise tagENTERPRISE_TENANTS=$(curl -s "$API_URL/tenants" | \ jq -r '.data[] | select(.tags[] | .value == "enterprise") | .id')
for TENANT_ID in $ENTERPRISE_TENANTS; do curl -s -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"solution_id\": \"$SOLUTION_ID\", \"environment_id\": \"$ENVIRONMENT_ID\" }" \ "$API_URL/tenants/$TENANT_ID/solutions" echo "Granted to $TENANT_ID"doneTroubleshooting
Section titled “Troubleshooting”Tenant Cannot Deploy
Section titled “Tenant Cannot Deploy”-
Check solution entitlement:
Terminal window curl "$API_URL/tenants/$TENANT_ID/solutions" -
Check target assignment:
Terminal window curl "$API_URL/tenants/$TENANT_ID/targets" -
Verify variables:
Terminal window curl "$API_URL/tenants/$TENANT_ID/variables/resolved?solution_id=$SOL&environment_id=$ENV"
User Cannot Access Tenant
Section titled “User Cannot Access Tenant”-
Verify user’s tenant_id:
SELECT tenant_id FROM users WHERE id = $user_id; -
Check user status:
SELECT status FROM users WHERE id = $user_id; -
Verify tenant exists:
SELECT id, name FROM tenants WHERE id = $tenant_id;
Next Steps
Section titled “Next Steps”- Overview - Multi-tenancy concepts
- Data Isolation - Security model
- Users - User management
- Audit Logs - Audit configuration
