IDENTITY FUNDAMENTALS · LAB
Create accounts three ways and trace where each attribute came from
Compare an administrator-created account, a self-registered account with email verification, and a record supplied by a system of record over SCIM, then decide which values the photo app should rely on.
ReadyUses your lab tenant
The lesson
Builds on: What is Identity?.
New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.
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.
Register Mia and confirm her email address
Recorded as
account.registersucceeded (registration_completed).Change Mia's own display name
Recorded as
account.profilesucceeded (profile_updated).See the HR record for Cora refused as a duplicate
Recorded as
scim.user.createrejected (uniqueness).Let the system of record take over Cora's record
Recorded as
scim.user.linksucceeded about[email protected].
Setup
You need an inbox you control for Mia Lane. Use a plus-address of your own, such as [email protected].
On this lab page choose Lab Photos and press Start.
In the shell, set the issuer and Mia's address:
ISSUER=https://tenant-<id>.beyondthelogin.dev
MIA_EMAIL='[email protected]'
SCIM="$ISSUER/scim/v2"
Authentication: turn on Self-service registration and save.
Flow policy: allow the Client credentials grant and save. Provisioning and later labs need it.
Provisioning: turn on the SCIM API. Note the SCIM scope names it shows (
scim-<id6>,scim-<id6>.usersand the other suffixed variants). Confirm that the option for users who already exist is set to Reject, the default.Create the provisioning client with the one-click option on the Provisioning page and name it
lab-provisioning. The secret is shown once. Keep it in the shell:
PROV_ID=<lab-provisioning client ID>
read -rs PROV_SECRET
SCIM_SCOPE=<the SCIM scope that can write users>
Walkthrough
In a private browser window open
$ISSUER/register. Register Mia Lane with$MIA_EMAILand complete the email code or link.
Why it matters: following the link or entering the code proves that someone could read that mailbox at that moment, and nothing more.
Open Users and compare Mia's record with Ava's. Then sign in as Mia through
$ISSUER/token-decoderwithopenid profile email. Mia's ID token has"email_verified": true; Ava's in the previous lab hadfalse.
Why it matters: the same claim, email, carries different evidence depending on how the record was created.
As Mia, open
$ISSUER/accountand change her name toQueen Victoria. Sign in through the Token Decoder again:given_nameis nowQueen.
Why it matters: verification covered the mailbox, never the name. A self-asserted name is fine for a photo caption and useless for anything that needs a legal identity.
Now play the employer's HR system, a system of record. Get a provisioning token:
SCIM_TOKEN=$(curl -s -u "$PROV_ID:$PROV_SECRET" -d grant_type=client_credentials -d scope="$SCIM_SCOPE" "$ISSUER/oauth/token" | jq -r .access_token)
Send Cora's record the way her employer would, with attributes only HR owns:
cat > cora.json <<'EOF'
{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
"userName":"[email protected]","name":{"givenName":"Cora","familyName":"Diaz"},
"emails":[{"value":"[email protected]","primary":true}],"title":"Photo editor","active":true,
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":{"department":"Communications","employeeNumber":"E-1042"}}
EOF
curl -s -X POST "$SCIM/Users" -H "Authorization: Bearer $SCIM_TOKEN" -H "Content-Type: application/scim+json" --data @cora.json | jq
Expected: 409 with "scimType":"uniqueness". Cora already exists because the preset created her by hand.
Why it matters: two sources now claim the same person. With the default setting, the tenant refuses to guess which one is right.
Decide that the HR system is the source for Cora. On Provisioning, set the option for existing users to Link by email and save. Repeat the request from step 5. It succeeds, and Audit shows
scim.user.linkfor Cora instead of a new user.
Why it matters: matching by email is acceptable here only because the SCIM client is an authenticated system of record you configured yourself. Trust across systems returns to why the same shortcut is dangerous when the email comes from somewhere that never checked it.
Restore: set the option for existing users back to Reject and save, so later SCIM requests cannot adopt hand-made records.
Open Cora's View details: her type is now Tenant (SCIM), and Title and Department are filled in. Open the administrator Edit form for Cora and for Ava: it offers name and email only. Open
$ISSUER/accountas Mia: she can edit her own name, but there is no department field.
Why it matters: this is sources of trust in practice. Department and title come only from the system of record; Mia's display name comes only from Mia. Trusting HR for the department does not make it the source for everything.
Compare this table with the real records, then add a last column of your own: should the photo app rely on each value, and for what?
| Account | Name supplied by | Email supplied by | What was checked |
|---|---|---|---|
| Ava | administrator | administrator | nothing |
| Mia | Mia | Mia | mailbox access at registration |
| Cora | HR system | HR system | the HR system's own processes |
Why it matters: this is the lesson's closing question, "who supplied this information, what was checked, and why should this system rely on it?", answered from real records.
Sign Mia out on
$ISSUER/account, then sign in again at$ISSUER/loginwith her email and password.
Why it matters: the tenant recognizes a returning user by the evidence she presents now, not by anything checked at registration. That is authentication, the subject of the next lab.
Break it
Register again at
$ISSUER/registerwith$MIA_EMAIL. The page looks exactly like a first registration, and Mia's inbox receives a notice instead of a second account.
Why it matters: registration must not reveal which addresses already have accounts.
Reuse the verification link or code from step 1. The tenant answers that the code or link is invalid, expired or already used.
Send the SCIM request from step 5 once more. Cora is now a SCIM-managed user, so the result is
409with"scimType":"uniqueness"again.
Check your work
Press Check my progress. It looks for:
account.registersucceeded with reasonregistration_completed.account.profilesucceeded with reasonprofile_updated.scim.user.createrejected with reasonuniqueness.scim.user.linksucceeded for Cora.
Audit also shows tenant.authentication.update, tenant.oauth.policy.update and tenant.provisioning.update from Setup, and tenant.oauth.clients.provision for lab-provisioning.
Cleanup
As Mia, change her name back to
Mia Lane.Authentication: turn Self-service registration off.
Delete
cora.json. Keep the SCIM API,lab-provisioning, the Client credentials grant, Cora and Mia. Later labs use them.