skip to content

In OpenID Connect, which scope value must an authorization request include, and what does including it change?

level: juniorimportance: must knowfreq 74%

answer

  1. one value flips the whole request
  2. the identity layer is opt-in
  3. without it, plain delegated authorization
  4. space-delimited, case-sensitive list
  5. openid asks for an ID token

basics

~20 s

An authorization request becomes an OpenID Connect authentication request only when its scope parameter includes the value openid. That value makes the provider issue an ID token; without it the exchange is plain OAuth 2.0 authorization.

solid answer

~40 s

Every OpenID Connect authentication request is an OAuth 2.0 authorization request whose `scope` parameter includes the value `openid`. That single value is the switch. With it, the provider treats the request as a request to authenticate the end user and returns an **ID token** — a signed statement about who signed in, addressed to the client — alongside whatever else the flow delivers. Without it, the identical request is ordinary delegated authorization: the provider may hand back an access token, but nothing in the exchange says who the user is. `scope` is a space-delimited, case-sensitive list, so `openid profile email` asks for three values while `OpenID` asks for none of them. `openid` on its own selects no profile attributes at all; the other identity scope values do that job.

code

http · 6 lines
http
GET /authorize?response_type=code
  &client_id=s6BhdRkqt3
  &scope=openid
  &redirect_uri=https%3A%2F%2Fsightings.example%2Fcb
  &state=af0ifjsldkj HTTP/1.1
Host: idp.example.org

go deeper

for a junior

Remember the one-line rule: no openid scope value, no ID token, and therefore no statement about who signed in. Recall that scope values are separated by spaces and are case-sensitive.

for a middle

Explain that OpenID Connect is a layer over the same authorization request, and that openid is the only thing that distinguishes an authentication request from a plain authorization request. Say what the ID token is for and who it is addressed to.

for a senior

Show that you request openid alone when the application only needs to know who filed a record, and can say what the alternative costs in data you then own. Diagnose an integration that reads identity out of an access token.

for a principal

Frame the choice as a data-minimisation boundary set once, at integration time: which attributes the estate is permitted to hold at all, enforced in the request rather than discovered later in a privacy review.

## Two protocols, one request OAuth 2.0 defines **delegated authorization**: a client asks an authorization server for permission to act on a resource owner's behalf and receives an **access token** it later presents to an API. Nothing in that exchange tells the client who the resource owner is. An access token is addressed to an API, not to the client, and reading identity out of one is the classic beginner's mistake. OpenID Connect supplies the missing statement, and it does so without a new endpoint, a new redirect or a new grant. It reuses the same authorization request and adds one **scope value**: `openid`. A request carrying it is, in the specification's own vocabulary, an **Authentication Request**. A request without it is an ordinary authorization request, however identity-flavoured the other values look. ## What its presence changes | | `scope` without `openid` | `scope` with `openid` | |---|---|---| | What the request is | an OAuth 2.0 authorization request | an OpenID Connect Authentication Request | | ID token | never issued | issued in the token response | | Who the response identifies | nobody | the end user who authenticated | | Identity claim sets | not selectable | selectable with `profile`, `email`, `address`, `phone` | | Applicable rules | RFC 6749 only | RFC 6749 plus OpenID Connect's own | The important half of that table is the second row. The ID token is the artefact the identity layer adds, and the `openid` scope value is what asks for it. ## How the scope parameter is written Three mechanics catch people out, and all three are checkable: - **Values are separated by single spaces.** `scope=openid profile email` is a list of three. Commas, plus signs and semicolons are not separators — a comma-joined list is one meaningless value. - **Values are case-sensitive ASCII strings.** `openid` works; `OpenID` and `OPENID` are different strings and match nothing. - **Order carries no meaning.** `scope=email openid` is the same request as `scope=openid email`. A provider advertises the values it will accept in the `scopes_supported` member of its configuration document, and a conforming OpenID Provider lists `openid` there. ## What `openid` alone does and does not bring back `openid` asks for authentication. It does **not** ask for a profile. On its own it brings back an ID token identifying the end user and no `name`, no `email`, no `picture`. Every attribute beyond identification comes from one of the other scope values or from a claim requested individually by name. That separation is deliberate and it is the whole reason a client can ask for sign-in and nothing else. `profile`, `email`, `address` and `phone` are all OPTIONAL scope values; a provider need not support any of them, and a client that assumes one is present is assuming a deployment detail. ## In a ranger sighting recorder A nature reserve runs a species-sighting recorder. Every record needs a label saying which ranger filed it, and nothing else about that person is any of the application's business. The correct authorization request asks for `scope=openid` and stops. The client gets back an ID token, reads the subject identifier out of it, and stores that as the filer. It never sees a birth date, a postal address or a phone number, so it can never leak one, log one or be asked to delete one. The common failure is the opposite reflex: a developer copies a request that reads `scope=openid profile email`, ships it, and the recorder now receives fourteen profile claims plus an address of record for every ranger in the reserve. Nothing breaks, no error is raised, and nobody notices for a year. That is why this is a data-minimisation question and not a syntax question. ## Where candidates go wrong 1. **Reading identity out of an access token.** An access token is an authorization credential for an API and may be entirely opaque. The identity statement is the ID token. 2. **Expecting an ID token from a request that never asked for one.** No `openid`, no ID token. 3. **Assuming `openid` implies a profile.** It implies exactly one thing: authenticate the end user. 4. **Getting the list syntax wrong.** Spaces, case-sensitive, form-encoded in a query string — `openid%20profile`, not `openid,profile`.

  • If a request omits openid but the provider returns an ID token anyway, what should the client conclude?
    That it is relying on a deployment-specific behaviour, not on the specification. OpenID Connect ties the ID token to the `openid` scope value, so a client written against one provider's extra generosity will break against the next one. Ask for `openid` explicitly, and validate the ID token rather than assuming its presence.
  • Does adding openid to a request change what a resource server will accept?
    No. `openid` governs whether the provider issues an ID token to the client; it says nothing about what an API will accept. The ID token is addressed to the client that requested it and is not an API credential — forwarding one to a resource server is the single most common error on this material.
  • Where does a client find out whether a provider supports a given scope value?
    In the `scopes_supported` member of the provider's configuration document, which lists the values it recognises. Treat it as an advertisement of capability: a value's presence means the provider will accept the request, not that every end user will have a value for every claim behind it.

saying these in an interview costs you the question

  • Thinks an OAuth 2.0 access token says who signed in
  • Believes an ID token arrives without the openid scope value
  • Says scope values are comma-separated
  • Treats scope matching as case-insensitive
  • Assumes openid alone returns name and email
  • Forwards the ID token to an API as a credential