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

Ask your tenant's SCIM service what it supports, and read exactly what you need

Read SCIM discovery, change a tenant setting and watch discovery follow it, read users and groups attribute by attribute, and add a site extension whose value appears only when asked for.

ReadyUses your lab tenant

The lesson

Builds on: Sources of truth.

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.

  1. Read the service's configuration

    Recorded as scim.discovery.read succeeded for lab-provisioning.

  2. Change a provisioning setting that discovery reports

    Recorded as tenant.provisioning.update succeeded.

  3. Add the Site extension

    Recorded as tenant.schemas.create succeeded.

  4. Give Ava a site through the extension

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

  5. A user that names an unknown schema is refused

    Recorded as scim.user.create rejected (invalid_value) for lab-provisioning.

Request console

Requests in this lab can be sent from this page to your tenant: open one and choose Send. Fill in the values below first. They stay in this page's memory and are gone when you leave; secrets are never stored or sent anywhere except the request you send.

Setup

  1. Open a bash shell and set the variables and helpers from the directory lab, and look up Ava: export AVA=$(scim -G "$SCIM/Users" --data-urlencode 'filter=userName eq "[email protected]"' | jq -r '.Resources[0].id').

  2. Press Start on the lab page.

Walkthrough

  1. ServiceProviderConfig. Ask what the service offers.

GET$ISSUER/scim/v2/ServiceProviderConfig Open in console
GET $ISSUER/scim/v2/ServiceProviderConfig HTTP/1.1
Authorization: Bearer $TOKEN
Accept: application/scim+json

Patch is supported; bulk is supported with maxOperations: 100 and maxPayloadSize: 1048576; filter is supported with maxResults: 200; sort and etag are supported; changePassword reflects your tenant; authenticationSchemes says OAuth bearer token.

Why it matters: this is "Asking what a service supports". Each value changes how a client behaves, such as the largest page it should ask for and whether it may send one Bulk request instead of many.

  1. A setting changes discovery. In User Management > Provisioning, turn Accept passwords over SCIM off and save. Read scim "$SCIM/ServiceProviderConfig" | jq .changePassword: supported is now false.

Restore: turn Accept passwords over SCIM back on and save. The HR Simulator's runs with initial passwords need it.

Why it matters: discovery describes this tenant's runtime, not a static brochure, so a client that reads it adapts to the tenant's choices.

  1. ResourceTypes. scim "$SCIM/ResourceTypes/User" | jq '{endpoint, schema, schemaExtensions}' lists the enterprise extension and, if you did the contractors lab, the Workforce extension, each with required: false.

  2. Attribute characteristics. Read the core user schema and pick out three attributes.

scim "$SCIM/Schemas/urn:ietf:params:scim:schemas:core:2.0:User" \
  | jq '.attributes[] | select(.name=="password" or .name=="userName" or .name=="groups") | {name,mutability,returned,uniqueness,required}'

password is writeOnly and returned never. userName is required with uniqueness server. groups is readOnly.

Why it matters: these characteristics explain the mutability refusal from the directory lab, and why no response ever contains a password, even one the HR Simulator set.

  1. Reading a user. Read Ava with scim -i "$SCIM/Users/$AVA" and name each attribute's job: id belongs to the service, userName can change, name is complex, emails is multi-valued, active is the administrative status, and meta.version equals the ETag header. Ava has no externalId, because no client created her. Then read a simulated person: externalId (HRSIM-...) is the HR client's own key, while the enterprise employeeNumber (0003, for example) is a business attribute.

Why it matters: this is "Reading a user". id is what a client stores to address the account later, and externalId is how the client finds it again if it loses the id.

  1. Add the lesson's site extension. In User Management > Schemas, create a schema named Site with the URN urn:example:labphotos:scim:schemas:extension:site:1.0:User and one attribute site: text, allowed values Main, North and South, returned Only when requested. Give Ava a site, then read her twice.

export SITE=urn:example:labphotos:scim:schemas:extension:site:1.0:User
jq -n --arg p "$SITE:site" '{schemas:["urn:ietf:params:scim:api:messages:2.0:PatchOp"],Operations:[{op:"add",path:$p,value:"Main"}]}' \
  | scim -X PATCH "$SCIM/Users/$AVA" --data-binary @- -o /dev/null -w '%{http_code}\n'
scim "$SCIM/Users/$AVA" | jq --arg s "$SITE" '.[$s]'
scim -G "$SCIM/Users/$AVA" --data-urlencode "attributes=$SITE:site" | jq --arg s "$SITE" '.[$s]'

The default read shows no site. The read that names the attribute shows {"site": "Main"}.

Why it matters: this is "Extensions". Extension attributes sit in their own object, named by the URN, so they never collide with core names, and returned: request keeps an attribute out of every default response.

  1. Read only what you need. scim -G "$SCIM/Users/$AVA" --data-urlencode 'attributes=userName,emails' | jq . returns those two, plus id and schemas, which always come back. --data-urlencode 'excludedAttributes=groups' returns everything except groups.

  2. Groups and members, cheaply. List group names without member lists, then read one group in full.

scim -G "$SCIM/Groups" --data-urlencode 'excludedAttributes=members' | jq -r '.Resources[] | [.displayName, .id] | @tsv'
scim -G "$SCIM/Groups" --data-urlencode 'filter=displayName eq "Photo moderation"' | jq '.Resources[0].members'

Each member has a value (the user's id), a $ref and a display name.

Why it matters: this is "Groups and members". Membership is stored on the group, and a client that needs only names should not pull every member list.

Break it

  1. Filter a discovery endpoint: scim -G "$SCIM/Schemas" --data-urlencode 'filter=id pr' | jq .. The answer is 403 with "Discovery endpoints do not support filters", as RFC 7644 recommends. Read the whole list instead.

  2. Create a user whose schemas names urn:example:unknown:1.0:User. The answer is 400 invalidValue: the request names a schema this service does not support.

Check your work

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

  • scim.discovery.read succeeded by lab-provisioning (step 1)

  • tenant.provisioning.update succeeded (step 2)

  • tenant.schemas.create succeeded (step 6)

  • scim.user.patch succeeded for Ava (step 6)

  • scim.user.create rejected with invalid_value (Break it)

Cleanup

  1. Confirm Accept passwords over SCIM is on.

  2. Keep the Site schema, or delete it. Deleting a schema removes its stored values, and Audit records tenant.schemas.delete.

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