Beta

Create a tenant

A new tenant starts with its own users, OAuth settings, audit history and logs. You are its first Tenant Admin.

BTL Admin

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.

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.

  1. Give Ben both halves of a toxic combination

    Recorded as tenant.users.management_roles.assign succeeded about [email protected].

  2. Ben sets the password on an account he created

    Recorded as tenant.users.credentials.set succeeded.

  3. The account Ben made and armed signs in

    Recorded as account.sign_in succeeded (signed_in).

  4. Ben cannot assign a role whose permissions he lacks

    Recorded as tenant.users.management_roles.assign rejected (access_denied) about [email protected].

  5. The help desk cannot lock a user with wider permissions

    Recorded as tenant.users.lock rejected (access_denied) about [email protected].

  6. Provisioning cannot change that user either

    Recorded as scim.user.patch rejected (protected_user) for lab-provisioning about [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.

  1. Open a bash shell and set the variables and helpers from the directory lab.

  2. Make sure Ben holds Help desk with tenant.users.lock (added in the leaving lab) and can sign in at $ISSUER/manage.

  3. Press Start on the lab page.

  4. In Roles, create lab-tmp-account-creator with tenant.users.read and tenant.users.create, and lab-tmp-credential-setter with tenant.users.read and tenant.users.credentials.set.

Walkthrough

  1. Write the conflict matrix. In your notes, list conflicting pairs from the permission catalog, each with an owner:

    • tenant.users.create with tenant.users.credentials.set: make an account and know its password

    • tenant.roles.update with tenant.users.management_roles.assign or tenant.roles.assign: build a role and hand it out

    • tenant.oauth.clients.create with tenant.oauth.clients.update: create a client and give it SCIM scopes that write the directory

    • tenant.audit.read with 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.

  1. Preventive check: none. Assign both lab-tmp-account-creator and lab-tmp-credential-setter to Ben. The tenant accepts it.

  2. 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/login as that account. It works. Audit shows tenant.users.create and tenant.users.credentials.set by Ben, then account.sign_in with signed_in.

Why it matters: this is "One person, start to finish". Every step was authorized, so nothing could have stopped it or noticed it.

  1. 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.

  1. Enforced: nobody grants more than they hold. Give Ben a temporary role lab-tmp-role-assigner with tenant.users.read and tenant.users.management_roles.assign. As Ben, try to assign lab-tmp-credential-setter to Ava. Refused with access_denied, because Ben does not hold tenant.users.credentials.set himself.

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.

  1. Enforced: the help desk cannot touch wider privilege. Create lab-tmp-auditor with tenant.audit.read and assign it to Cora. As Ben, whose Help desk role includes tenant.users.lock, try to lock Cora: refused with access_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.

  1. Not enforced: editing a role you hold. Give Ben lab-tmp-role-editor with tenant.roles.read and tenant.roles.update. As Ben, open Help desk, the role he holds, and add tenant.roles.update to it. The tenant allows it, because Ben already holds that permission, and every Help desk holder now has it too. Try to add tenant.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.

  1. A compensating control for a small team. Suppose one person must hold both tenant.users.create and tenant.users.credentials.set. Define the morning check in your notes: in Audit, search that person's actor ID and list every tenant.users.credentials.set from 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.

  1. In Roles > Conflict rules, add the rule "tenant.users.create conflicts with tenant.users.credentials.set", owner Cora. Audit records the rule change.

  2. Repeat step 2. The second assignment is refused with a conflict reason that names the rule, unless an exception exists.

  3. 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.

  4. A detective scan lists everyone who currently holds both halves of any rule, including combinations created by editing a role.

  5. 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.assign succeeded for Ben (step 2)

  • tenant.users.credentials.set succeeded (step 3)

  • account.sign_in succeeded with signed_in (step 3)

  • tenant.users.management_roles.assign rejected with access_denied for Ava (step 5)

  • tenant.users.lock rejected with access_denied for Cora (step 6)

  • scim.user.patch rejected with protected_user for Cora (step 6)

Cleanup

  1. Confirm every Restore was done: lab-tmp-ghost is deleted, Ben holds only Help desk, Cora holds no management role, and Help desk lacks tenant.roles.update.

  2. Delete lab-tmp-account-creator, lab-tmp-credential-setter and any other lab-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.

Back to all labs

We value your privacy

We use cookies and similar technologies to enhance your browsing experience, and analytics to understand our traffic. By clicking "Allow All", you consent to optional analytics. Cookie Policy

The Lab