Why
Replaces #368, filed before #370. Since #370, tenant roles map only onto tenants.* permissions, so anyone holding settings.edit is a platform operator. That operator legitimately edits system scope and any tenant's scope. The real gaps are:
- A tenant owner cannot edit their own tenant's settings.
tenants.settings.manage exists but nothing uses it.
- The platform routes accept any
scope_id for TENANT scope, including ids that are not real tenants.
Scope
- Setting definitions gain a
tenant_overridable flag. Only flagged keys may be written at tenant scope.
GET/PUT/DELETE /api/settings/tenant/current/{key} acts on request.state.tenant_id, never a tenant id from the URL. It is guarded by a new settings.tenant.edit permission mapped onto tenant:owner and tenant:admin through the shared tenant-role vocabulary.
- Platform routes validate TENANT
scope_id against known tenants when tenants is installed.
- Tests: a tenant admin can edit its own tenant's overridable keys, cannot edit another tenant's keys, cannot edit system scope, and cannot edit non-overridable keys.
Setting keeps its explicit (scope, scope_id, key) key, with no mixin.
Why
Replaces #368, filed before #370. Since #370, tenant roles map only onto
tenants.*permissions, so anyone holdingsettings.editis a platform operator. That operator legitimately edits system scope and any tenant's scope. The real gaps are:tenants.settings.manageexists but nothing uses it.scope_idfor TENANT scope, including ids that are not real tenants.Scope
tenant_overridableflag. Only flagged keys may be written at tenant scope.GET/PUT/DELETE /api/settings/tenant/current/{key}acts onrequest.state.tenant_id, never a tenant id from the URL. It is guarded by a newsettings.tenant.editpermission mapped ontotenant:ownerandtenant:adminthrough the shared tenant-role vocabulary.scope_idagainst known tenants whentenantsis installed.Settingkeeps its explicit(scope, scope_id, key)key, with no mixin.