AUTHORIZATION AND POLICY · LAB
Delegation limits, keeping an administrator, and removing access
Act as a desk lead who can assign some roles, try both escalation routes, try to remove the last administrator, and take access away mid-session.
Partly readyIncludes a simulationUses your lab tenant
The lesson
Builds on: Designing a role model.
New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.
Partly ready. Most of this lab runs today. Steps that wait on platform features are marked, and Missing infrastructure says what they need.
- G46 Separation-of-duties rules (preventive and detective)
- G47 Specific delegation rejection reasons in Audit (today only `access_denied`)
Your progress
Press Start before you begin. Only events your tenant records after that count, in the order below. Checking reads your tenant's Audit, so you need Audit read access in it.
Sign in to start this lab and check your progress. Log in or create an account.
Cora gives Ben a role she fully holds
Recorded as
tenant.users.management_roles.assignsucceeded about[email protected].Cora tries to give Ben a role she does not fully hold
Recorded as
tenant.users.management_roles.assignrejected about[email protected].Cora tries to add a permission to the role she holds
Recorded as
tenant.roles.updaterejected.Try to remove the last BTL Tenant Admin
Recorded as
tenant.administrators.updaterejected.
Setup
Complete Design task-based custom roles for your tenant first.
In Roles, create
lab-tmp-access-manager, the lesson's desk lead, withtenant.overview.read,tenant.users.read,tenant.roles.read,tenant.roles.update,tenant.users.management_roles.assign, and every permission inHelp desk.Under Users > Cora > Management roles, remove
Auditorand assignlab-tmp-access-manager.Sign Cora in at
$ISSUER/managein her private window.
Walkthrough
As Cora, open Users > Ben > Management roles, remove
Help desk, save, then assign it again and save. Both changes succeed.
Why it matters: Cora holds every permission in Help desk, so she may grant it or take it away. role.assign here is limited to what the assigner holds.
As Cora, try to assign
Auditorto Ben. It is refused.
Why it matters: Cora does not hold tenant.audit.read. The delegation limit stops the assign permission from becoming a route to every permission in the catalog.
The quieter route. As Cora, open
lab-tmp-access-manager, the role she holds, and addtenant.audit.read. The permission is not even offered as a choice. Test the server: in DevTools copy aroles/updaterequest for this role as fetch, addtenant.audit.readto its permissions and use a freshcrypto.randomUUID()forcommand_id. It is refused.
Why it matters: editing a role you hold grants yourself permissions without any assignment, so the same delegation limit applies to role edits.
Read the record. In Audit, both refusals appear as rejected, with Cora as actor and reason
access_denied. Compare with the lesson's record, which namesdelegation_limitand the permission that could not be delegated.
Why it matters: the person refused should get a short answer, but an investigator needs the detail. This tenant records only access_denied today (G47).
Keeping someone in charge. In the portal open Administrators and try to remove
Tenant Adminfrom yourself. It is refused: "Keep at least one active Tenant Admin." Now assignTenant Adminto Cora under Users > Cora > Management roles and try the removal again. It is still refused.
Why it matters: a tenant user never counts toward this protection. At least one active BTL Tenant Admin must remain, because only BTL users can recover a tenant.
Restore: remove Tenant Admin from Cora at once. It was only for this step.
Concurrent changes. Open Roles in two tabs. Save a change to
lab-tmp-access-managerin the first tab, then a different change in the second. The second tab is refused: "Tenant access changed. Refresh before trying again."
Why it matters: every access change checks the version it read, so two changes cannot both pass a check that the other one invalidates, the lesson's two administrators removing each other.
Removal takes effect. With Cora's
$ISSUER/manageopen on Users, removelab-tmp-access-managerfrom her in the portal. Her next action fails, and reloading/managesends her to/account.
Why it matters: the decision reads current assignments on every request, so no cached copy keeps her access alive.
Separation of duties, as a design note.
Simulation. the tenant has no separation-of-duties rules, so nothing can stop one person from holding both lab-tmp-access-manager and Auditor. Write the rules instead of running them.
Write two rules for your tenant in the lesson's style: a static rule that no one holds both an access-changing role and Auditor, and a per-item rule that no one approves their own access change. For each, note where it would be checked: at assignment, including through groups, or at the moment of use.
Why it matters: some risks come from one person doing two things that should check each other, which no single permission can express.
Break it
Steps 2, 3, 5 and 6 are the failures: a refused assignment, a refused role edit, a refused administrator change with reason
last_administrator, and a change refused as a conflict. Each is in Audit with its actor.
Check your work
Press Check my progress. The checks follow Cora's allowed assignment, her refused assignment, her refused self-edit and the refused removal of the last administrator.
Also confirm by hand:
Logs show Cora's
/managerequest after the removal answered with reasonnot_permitted.
Cleanup
Cora:
Auditoronly. Ben:Help desk. Nobody but you holdsTenant Admin.Delete
lab-tmp-access-managerafter it is removed from everyone.
Missing infrastructure
G46, separation-of-duties rules. Declaring conflicting roles, checked at assignment and on every route that could create the conflict, plus per-item rules checked at use, would make step 8 real.
G47, specific delegation reasons. Recording
delegation_limitand the names of the permissions that could not be delegated in tenant Audit, never in the response, would make step 4 match the lesson's record.