Tenant Settings — Production Guide
Deploy checklist
- Run migrations (adds
type/groupontenant_settings, plustask_digest_deliveriesfor durable daily task digest send state). - Configure object storage: local
FILESYSTEM_DISK=public+php artisan storage:link, or productionFILESYSTEM_DISK=s3. Optional:FILESYSTEM_BRANDING_DISK=publicso tenant branding undertenants/{id}/branding/…stays on local storage (see object-storage.md). - Ensure
settings.list/settings.updateexist inconfig/tenant-permissions.phpand default role maps. New workspaces receive them viaTenantAuthorizationProvisioningServiceduring provisioning. Existing workspaces that need newly added settings permissions receive them via an additive permission data migration — not production seeders and not login-time sync. - Confirm
APP_KEYis stable — SMTP passwords are encrypted with Laravel Crypt. - For daily task digests: scheduler must run (
schedule:runevery minute) and anemailsqueue worker must be listening. Shared cache is required foronOneServer()schedule locks.
Security
| Concern | Control |
|---|---|
| Isolation | Settings scoped by tenant_id; API requires tenancy + tenant auth |
| Cross-tenant | Branding files live under tenants/{uuid}/… |
| Secrets | mail_password encrypted at rest; API returns ******** |
| Central leakage | Tenant API never exposes Central-only keys (registration, maintenance, billing) |
Ops signals
- Unexpected Central branding on a tenant SPA usually means no tenant override + public bootstrap fell back correctly.
- Mail from Central From-address on a tenant that expected custom SMTP → check whether
mail_hostis set for that workspace. - 403 on
/api/tenant/v1/settings→ missingsettings.list/settings.updateon the role.
Rollback
Clearing a tenant override (empty optional branding/mail fields, or deleting the tenant_settings row) restores Central defaults immediately after cache forget (handled by the service).