IDENTITY GOVERNANCE · LAB
Find toxic combinations in tenant administration and test the separations enforced
Write a conflict matrix for tenant permissions, show in a contained step that one person can hold both halves of a sensitive process, detect it, restore, and test the separations your tenant does enforce.
Partly readyUses your lab tenant
The lesson
Builds on: Why access needs governance.
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)
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.
Give Ben both halves of a toxic combination
Recorded as
tenant.users.management_roles.assignsucceeded about[email protected].Ben sets the password on an account he created
Recorded as
tenant.users.credentials.setsucceeded.The account Ben made and armed signs in
Recorded as
account.sign_insucceeded (signed_in).Ben cannot assign a role whose permissions he lacks
Recorded as
tenant.users.management_roles.assignrejected (access_denied) about[email protected].The help desk cannot lock a user with wider permissions
Recorded as
tenant.users.lockrejected (access_denied) about[email protected].Provisioning cannot change that user either
Recorded as
scim.user.patchrejected (protected_user) forlab-provisioningabout[email protected].
Setup
The lesson's billing clerk could create a supplier and approve its payment. In tenant administration, the same shape is creating a person and setting their password: one person could make an account and know how to sign in as it. Everything in this lab stays inside your own tenant and uses temporary accounts and roles.
Open a bash shell and set the variables and helpers from the directory lab.
Make sure Ben holds
Help deskwithtenant.users.lock(added in the leaving lab) and can sign in at$ISSUER/manage.Press Start on the lab page.
In Roles, create
lab-tmp-account-creatorwithtenant.users.readandtenant.users.create, andlab-tmp-credential-setterwithtenant.users.readandtenant.users.credentials.set.
Walkthrough
Write the conflict matrix. In your notes, list conflicting pairs from the permission catalog, each with an owner:
tenant.users.createwithtenant.users.credentials.set: make an account and know its passwordtenant.roles.updatewithtenant.users.management_roles.assignortenant.roles.assign: build a role and hand it outtenant.oauth.clients.createwithtenant.oauth.clients.update: create a client and give it SCIM scopes that write the directorytenant.audit.readwith anything: allowed, because reading the record completes nothing
Why it matters: this is "Toxic combinations". A short list of pairs that would let someone grant themselves access gets attention; a matrix that flags every pair gets ignored.
Preventive check: none. Assign both
lab-tmp-account-creatorandlab-tmp-credential-setterto Ben. The tenant accepts it.One person, start to finish, contained. In a private window, sign in as Ben at
$ISSUER/manage. Create[email protected](Ghost Account) and set its password. Then, in another private window, sign in at$ISSUER/loginas that account. It works. Audit showstenant.users.createandtenant.users.credentials.setby Ben, thenaccount.sign_inwithsigned_in.
Why it matters: this is "One person, start to finish". Every step was authorized, so nothing could have stopped it or noticed it.
Detective check by hand. For each tenant user with management roles, take the union of their roles' permissions from Roles and test it against your matrix. Ben is flagged. Resolve it the cleanest way: the need has ended, so one half goes.
Restore: delete [email protected], and remove lab-tmp-account-creator and lab-tmp-credential-setter from Ben. Ben is back to Help desk only.
Why it matters: this is "Preventing and detecting". A preventive check would have refused step 2; without one, a scan of who holds what is the only thing that finds the combination.
Enforced: nobody grants more than they hold. Give Ben a temporary role
lab-tmp-role-assignerwithtenant.users.readandtenant.users.management_roles.assign. As Ben, try to assignlab-tmp-credential-setterto Ava. Refused withaccess_denied, because Ben does not holdtenant.users.credentials.sethimself.
Restore: remove lab-tmp-role-assigner from Ben.
Why it matters: this is "Separation in administration". Without this limit, anyone who could assign roles could reach any permission by assigning it to an account they control.
Enforced: the help desk cannot touch wider privilege. Create
lab-tmp-auditorwithtenant.audit.readand assign it to Cora. As Ben, whoseHelp deskrole includestenant.users.lock, try to lock Cora: refused withaccess_denied. Then try the provisioning feed:
export CORA=$(scim -G "$SCIM/Users" --data-urlencode 'filter=userName eq "[email protected]"' | jq -r '.Resources[0].id')
jq -n '{schemas:["urn:ietf:params:scim:api:messages:2.0:PatchOp"],Operations:[{op:"replace",path:"active",value:false}]}' \
| scim -X PATCH "$SCIM/Users/$CORA" --data-binary @- | jq .
The answer is 403 with protected_user.
Why it matters: the people who hold permissions beyond a help desk or a feed cannot be quietly disabled or rewritten by them.
Restore: remove lab-tmp-auditor from Cora and delete it.
Not enforced: editing a role you hold. Give Ben
lab-tmp-role-editorwithtenant.roles.readandtenant.roles.update. As Ben, openHelp desk, the role he holds, and addtenant.roles.updateto it. The tenant allows it, because Ben already holds that permission, and everyHelp deskholder now has it too. Try to addtenant.users.unlock, which Ben lacks: refused.
Restore: remove tenant.roles.update from Help desk, then remove lab-tmp-role-editor from Ben and delete it.
Why it matters: the delegation limit keeps this edit from reaching new permissions, but the lesson's stricter rule, nobody edits a role they hold, is a G46 conflict rule the tenant does not have yet.
A compensating control for a small team. Suppose one person must hold both
tenant.users.createandtenant.users.credentials.set. Define the morning check in your notes: in Audit, search that person's actor ID and list everytenant.users.credentials.setfrom the previous day; someone else signs the check by 10:00. Record it as an exception with an owner and an end date.
Why it matters: this is "When a small team cannot split the work". A compensating control reduces the same risk, and its end date forces the decision to be made again.
Planned walkthrough
Once G46 exists, the conflict matrix lives in the tenant.
In Roles > Conflict rules, add the rule "
tenant.users.createconflicts withtenant.users.credentials.set", owner Cora. Audit records the rule change.Repeat step 2. The second assignment is refused with a conflict reason that names the rule, unless an exception exists.
Add an exception for one person with an owner, a compensating control and an end date. The assignment now succeeds and Audit links it to the exception.
A detective scan lists everyone who currently holds both halves of any rule, including combinations created by editing a role.
A rule that forbids editing a role you hold refuses step 7.
Check your work
Press Check my progress. The checks look for, in order:
tenant.users.management_roles.assignsucceeded for Ben (step 2)tenant.users.credentials.setsucceeded (step 3)account.sign_insucceeded withsigned_in(step 3)tenant.users.management_roles.assignrejected withaccess_deniedfor Ava (step 5)tenant.users.lockrejected withaccess_deniedfor Cora (step 6)scim.user.patchrejected withprotected_userfor Cora (step 6)
Cleanup
Confirm every Restore was done:
lab-tmp-ghostis deleted, Ben holds onlyHelp desk, Cora holds no management role, andHelp desklackstenant.roles.update.Delete
lab-tmp-account-creator,lab-tmp-credential-setterand any otherlab-tmp-role left from this lab.
Missing infrastructure
G46: the tenant has no conflict rules. With them, step 2 would be refused or require an exception with an owner, a compensating control and an end date, a scan would list current conflicts, and changes to rules and exceptions would be audited.