skip to content

In OpenID Connect, what does the claims request parameter let a client ask for that a scope value cannot?

level: seniorimportance: should knowfreq 30%

answer

  1. bundles are coarse, this is fine
  2. the value is JSON, not a list
  3. two top-level members only
  4. essential is a signal, not a promise
  5. claims_parameter_supported defaults to false

basics

~20 s

The claims request parameter asks for individual claims by name, in a JSON value whose top-level members are userinfo and id_token, and can mark one essential. Scope values can only select whole predefined claim sets.

solid answer

~50 s

A scope value selects a fixed bundle; the `claims` request parameter names individual claims. Its value is UTF-8 encoded JSON with two possible top-level members, `userinfo` and `id_token`, each holding the claims being asked for on that side. A claim requested as `null` is **voluntary**; one requested as an object carrying `"essential": true` says the client's task cannot be completed without it, and the object may also pin an expected `value` or a list of acceptable `values`. Two preconditions matter. Support is **OPTIONAL** and is advertised by `claims_parameter_supported`, which defaults to false when the member is absent. And the `userinfo` member only makes sense with a `response_type` that returns an access token. Crucially, `"essential": true` obliges nothing absolute: a provider that cannot release the claim returns the response without it and does not raise an error.

code

json · 10 lines
json
{
  "id_token": {
    "name": { "essential": true },
    "email_verified": null
  },
  "userinfo": {
    "email": { "essential": true },
    "picture": null
  }
}

go deeper

for a junior

Know that the parameter exists and that it asks for individual claims by name rather than whole bundles; the details are not screening material.

for a middle

Describe the JSON value and its two top-level members, and explain the difference between a voluntary null request and an object marked essential.

for a senior

Show that you check claims_parameter_supported before depending on it, that you design a fallback for a missing essential claim, and that you pick between a bundle and a named request on data-minimisation grounds.

for a principal

Decide whether the estate standardises on named-claim requests at all, given that support is optional and varies by provider, and what that means for onboarding a partner's provider that does not implement it.

## Coarse bundles, fine requests OpenID Connect gives a client two ways to ask for attributes about the end user, and they sit at very different grains. - **Scope values** name a **claim set**: `profile` is fourteen claims, `email` is two. The bundle is fixed and cannot be narrowed. - **The `claims` request parameter** names **individual claims**. It is how a client asks for `name` without also being handed `birthdate`, `gender` and `zoneinfo`. Everything that makes the first approach convenient — one short value, the same everywhere — is what makes it blunt. The `claims` parameter is the fine-grained alternative, and it is OPTIONAL: a provider need not support it at all. ## The shape of the value The parameter's value is **UTF-8 encoded JSON** (form-encoded when it travels as a request parameter). At the top level it has two possible members: | Member | Meaning | |---|---| | `id_token` | claims the client is asking to have delivered in the ID token | | `userinfo` | claims the client is asking to have available from the provider's user-information response | Inside each member, a claim name maps either to `null` — meaning "I would like this, voluntarily" — or to an object that qualifies the request. That object may carry: - `"essential": true`, marking the claim as one the client's task depends on; - `"value"`, pinning a single expected value for the claim; - `"values"`, listing the values the client would accept. A claim name mapped to `null` and a claim name mapped to `{}` mean the same voluntary request. ## What `essential` really obliges This is where candidates overstate, and it is the crux of the question. Marking a claim `"essential": true` tells the provider that the client is requesting it to fulfil a specific task, and that failing to return it means the task cannot be completed. The provider may take that into account — for instance in deciding what to ask the end user for. What it does **not** do is compel a result. If the claim is not available, because the end user did not authorise its release or because the provider simply does not hold it, the provider returns the response without it and **must not generate an error** on that account, whether the claim was essential or voluntary, unless the definition of that specific claim says otherwise. An essential claim is a strong hint, not a contract. A client that treats a missing essential claim as impossible will fall over the first time it happens. ## Two preconditions 1. **Provider support.** The `claims_parameter_supported` member of the provider's configuration document says whether the parameter is honoured. When the member is absent the default is false, so a client that sends the parameter without checking may find it silently disregarded — with the same quiet failure shape as an ignored scope value. 2. **A response type that yields an access token.** Claims requested under the `userinfo` member require a `response_type` that returns an access token, because that is the credential by which the user-information side is reached at all. Asking for claims there in a flow that produces no access token asks for something the client cannot then collect. Alongside these, `claims_supported` lists the claim names a provider says it can produce. Read it as an advertisement of capability, not as a promise that any given end user has a value for any given claim. ## In the sighting recorder The nature reserve's recorder wants one human-readable label per ranger and nothing else. With scope values alone the options are bad: `openid` gives no name, `openid profile` gives fourteen claims. With the `claims` parameter the request becomes exactly what the task needs — `name`, marked essential because a record with no filer label is useless, and nothing else. The birth dates, genders and locales are never sent, so they are never stored, never logged and never in scope for a deletion request. The operational caveat stays: the provider may still return no `name`, essential or not, and the recorder needs a defined behaviour for that case — fall back to the subject identifier, say — rather than an exception in a nightly job. ## Why this is a senior question The recall half is easy. The judgment half is knowing that the parameter is optional and therefore not portable across providers; that `essential` is a signal rather than a guarantee; that a request for a claim under `userinfo` carries a response-type precondition; and that choosing between a bundle and a named-claim request is a data-collection decision, not a formatting preference. A candidate who has only wired up a quickstart will not have met the parameter at all, because quickstarts use scope values.

  • A provider omits claims_parameter_supported from its configuration document. What should a client assume?
    That the parameter is not supported: the member's default is false when absent. A client that sends it anyway gets no error and no effect, and will fall back to whatever the scope values selected — which is the failure most likely to be discovered in production rather than in review.
  • What is the difference between requesting a claim as null and as an object with essential true?
    `null` is a voluntary request: nice to have. An object with `"essential": true` says the client's task depends on it, which the provider may weigh when deciding what to release. Neither compels a result, and the response may omit the claim in both cases without an error.
  • Can the claims parameter be used to ask for something no scope value covers?
    Yes — that is much of its value. It addresses claims by name, including deployment-specific claim names outside the four standard sets, provided the provider supports the parameter and will produce that claim. `claims_supported` is where a provider advertises which names it can produce.
  • Does using the claims parameter remove the need for scope values?
    No. `openid` is still what makes the request an OpenID Connect authentication request, and it is required regardless. What the parameter replaces is the need to add wide bundles like `profile` purely to reach one claim inside them.

saying these in an interview costs you the question

  • Thinks essential true forces the provider to return the claim
  • Expects an error when an essential claim is missing
  • Assumes every provider supports the claims parameter
  • Sends the parameter as a space-delimited list
  • Believes the parameter replaces the openid scope value
  • Reads claims_supported as a per-user guarantee