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

Move people between jobs and find the access that stayed behind

Watch the HR Simulator move a person with their groups, move Ava by hand, query for access that no longer matches the job, trace where each grant came from, and end a handover on a date.

Partly readyUses your lab tenant

The lesson

Builds on: Why access needs governance, Sources of truth.

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. The source moves a person to a new department

    Recorded as scim.user.patch succeeded for lab-hr-feed.

  2. The source moves their group membership too

    Recorded as scim.group.patch succeeded for lab-hr-feed.

  3. Move Ava to moderation by hand

    Recorded as scim.user.patch succeeded for lab-provisioning about [email protected].

  4. Remove a group Ava no longer needs

    Recorded as scim.group.patch succeeded for lab-provisioning.

Setup

  1. Open a bash shell and set the variables and helpers from the directory lab, plus HR_ID and HR_SECRET (read -rs) for lab-hr-feed.

  2. Make sure Ava's starting point matches the first governance lab: she is in Print support, Print incident reviews and Photo moderation, the last added by hand. Add any that are missing in Groups. Then record her current department as print support.

export AVA=$(scim -G "$SCIM/Users" --data-urlencode 'filter=userName eq "[email protected]"' | jq -r '.Resources[0].id')
export CORA=$(scim -G "$SCIM/Users" --data-urlencode 'filter=userName eq "[email protected]"' | jq -r '.Resources[0].id')
group_id() { scim -G "$SCIM/Groups" --data-urlencode "filter=displayName eq \"$1\"" | jq -r '.Resources[0].id'; }
export PRINT=$(group_id "Print support") REVIEWS=$(group_id "Print incident reviews") MOD=$(group_id "Photo moderation")
jq -n --arg ent "$ENT" '{schemas:["urn:ietf:params:scim:api:messages:2.0:PatchOp"],Operations:[{op:"replace",path:($ent+":department"),value:"Print support"}]}' \
  | scim -X PATCH "$SCIM/Users/$AVA" --data-binary @- | jq "{id, dept: .\"$ENT\".department}"
  1. Press Start on the lab page.

  2. In the HR Simulator, start a Full lifecycle run: 8 people, movers 25 percent, leavers 25 percent, 30 minutes, initial passwords on. Pause it once the joiner events have succeeded. The leaving lab continues this run.

Walkthrough

  1. Before the move. In the run plan, find a "Mover: change department, title and manager" event and note its person's externalId. Read them.

scim -G "$SCIM/Users" --data-urlencode 'filter=externalId eq "<the mover externalId>"' \
  | jq ".Resources[0] | {id, title, groups: [.groups[]?.display], dept: .\"$ENT\".department, manager: .\"$ENT\".manager.value}"
  1. Let the source move them. Use Advance until the mover event and its "Remove from group" and "Add to group" events succeed. Read the person again: new department, title, manager and group. Search Audit for the correlation ID shown in the event detail: scim.user.patch lists department, title and manager, followed by scim.group.patch events, all by lab-hr-feed.

Why it matters: this is "Recalculating access". When access follows the source, the removal happens in the same change as the addition, without anyone asking for it.

  1. Move Ava the way a help desk would. Change her department and manager as lab-provisioning, and touch nothing else.

jq -n --arg ent "$ENT" --arg cora "$CORA" '{schemas:["urn:ietf:params:scim:api:messages:2.0:PatchOp"],Operations:[
  {op:"replace",path:($ent+":department"),value:"Photo moderation"},{op:"replace",path:($ent+":manager"),value:{value:$cora}}]}' \
  | scim -X PATCH "$SCIM/Users/$AVA" --data-binary @- | jq '{id, groups: [.groups[]?.display]}'

Ava is now in moderation and still holds both print groups.

Why it matters: this is "Adding is easy, removing is not". The new access came from a phone call in the first lab. Nobody will call about the old access.

  1. Find movers who kept old access.

scim -G "$SCIM/Users" --data-urlencode "filter=$ENT:department ne \"Print support\" and (groups[display eq \"Print support\"] or groups[display eq \"Print incident reviews\"])" \
  --data-urlencode 'attributes=displayName,groups' | jq -r '.Resources[].displayName'

Ava comes back.

Why it matters: privilege creep becomes a query: a group that no longer matches the person's job.

  1. Where did each grant come from? For each of Ava's three groups, search Audit for the group ID and read the actor of the change that added her: your BTL account or Ben in the portal (a manual grant), or a client. Fill the lesson's table:

AccessHow Ava got itAfter the move
Print support
Print incident reviews
Photo moderation

Why it matters: access that a source or rule granted recalculates when the job changes. Manual grants have no rule behind them, so they are the ones that stay behind.

  1. A handover with an end. Decide that Ava keeps Print support for two weeks to hand over her print orders, and write the end date in your notes. Remove Print incident reviews now.

jq -n --arg u "$AVA" '{schemas:["urn:ietf:params:scim:api:messages:2.0:PatchOp"],Operations:[{op:"remove",path:("members[value eq \""+$u+"\"]")}]}' \
  | scim -X PATCH "$SCIM/Groups/$REVIEWS" --data-binary @- -o /dev/null -w '%{http_code}\n'

At the end of this lab, standing in for the end date, remove her from Print support the same way with $PRINT.

Why it matters: this is "An overlap with an end". "Keep it for now" becomes permanent unless the end is set at the start. Here the end lives only in your notes, which is the weakness G23 would fix.

  1. Quieter changes. First a name change: replace Mia's name.familyName with Lane-Okoro (find her with filter=externalId eq "E10482"). Read her back: same id, same groups. Then change only Ava's manager, from Cora to Ben (filter=userName eq "[email protected]" gives his ID).

Why it matters: a name change is not a leaver plus a joiner, and a manager change reroutes approvals and reviews even when nothing else moves.

Planned walkthrough

Once G23 and G50 exist, the same move runs without your notes or your script.

  1. In Groups, add Ava to Print support as a time-bound membership: reason "Handover of print orders after moving to moderation", owner Cora, end date two weeks out. Audit records the grant with its reason and end date.

  2. Create an access rule "department eq Print support grants Print support". Step 3's department change then removes Ava's rule-granted membership at once, while the time-bound membership keeps the group until its end date.

  3. On the end date the tenant removes the membership by itself, and Audit records the expiry with the grant it ends.

Break it

  1. Run the step 6 removal again. The answer is still a success and the group is unchanged: this service treats removing a non-member as done. Read the group to confirm, as the lesson recommends, rather than trusting the status alone.

  2. See why replacing a whole member list is avoided. Create a group lab-tmp-scratch in the portal with Ava, Ben and Cora, then replace its members with a list that names only Ava.

export SCRATCH=$(group_id "lab-tmp-scratch")
jq -n --arg u "$AVA" '{schemas:["urn:ietf:params:scim:api:messages:2.0:PatchOp"],Operations:[{op:"replace",path:"members",value:[{value:$u}]}]}' \
  | scim -X PATCH "$SCIM/Groups/$SCRATCH" --data-binary @- -o /dev/null -w '%{http_code}\n'

Ben and Cora are gone, and nobody decided to remove them.

Restore: delete lab-tmp-scratch in Groups.

Check your work

Press Check my progress. The checks look for, in order:

  • scim.user.patch succeeded by lab-hr-feed (step 2)

  • scim.group.patch succeeded by lab-hr-feed (step 2)

  • scim.user.patch succeeded by lab-provisioning on Ava (step 3)

  • scim.group.patch succeeded by lab-provisioning (step 6)

After Cleanup, the step 4 query returns nobody.

Cleanup

  1. Remove Ava from Print support (the end of the handover). She keeps Photo moderation.

  2. Set Mia's family name back to Lane and Ava's manager back to Cora.

  3. Leave the lifecycle run paused for the leaving lab.

Missing infrastructure

  • G23: a time-bound membership with an end date, owner and reason would make step 6's handover end by itself and show up as a labeled exception in reviews.

  • G50: rules that recalculate group membership from department would remove the print groups as soon as step 3 changed Ava's department, as the HR Simulator's own group moves do in step 2.

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