To better understand this, it’s good to point out that OIDC is built on top of OAuth2.
OAuth2 is an authorization delegation protocol, where an application (the “client”) requests access to a protected resource (usually an API) on behalf of the resource owner (the “user”).
Scopes in OAuth2 are used to specify the kind of access that the application is requesting. As an example, think of a user with a Google account. As part of your Google account you own many resources: your profile, email, contacts, calendar, photos, drive, location history, search history, and much more. Now, imagine a calendar application that wants to notify you of upcoming events. It would ask a scope of “read your calendar”, so that you don’t have to give this application the full access to your Google account.
Scopes are defined by each resource server (Google in this case), the OAuth2 does not dictate predefined scopes.
Even though authentication is not the primary objective of OAuth2 (authentication is left to each provider to implement), as different social providers started to implement OAuth2, one of the common uses of it by third parties was to request access to the “user profile” (as a scope). Each OAuth2 authorization server defined the user profile somewhat differently.
OpenID Connect came to standardize all this, giving an authentication layer on top of OAuth2. Thus OIDC uses OAuth2 elements (like scope) to identify what the application is asking for.
From the OIDC spec introduction:
OpenID Connect implements authentication as an extension to the OAuth 2.0 authorization process. Use of this extension is requested by Clients by including the
openid scope value in the Authorization Request. Information about the authentication performed is returned in a JSON Web Token (JWT) [JWT] called an ID Token (see Section 2). […]
openid scope means that you want to use OpenID Connect, so this won’t be just an OAuth2 conversation. There most likely be an ID Token included in the response, and the returned Access Token will allow you to make requests to the userinfo endpoint (
/userinfo in Auth0) to obtain information about the user. The userinfo endpoint is a protected resource, so the client application is essentially using OAuth2 to request access to it using the specific
oidc will just give you a
sub claim about the user (a unique identifier) in the ID Token and in the
/userinfo endpoint. The other scopes (like
email) indicate additional claims that you are requesting about the user. So if the application asks for those (and the authorization server agrees) the application will get all the claims defined for the
offline_access is unrelated to OpenID Connect, it’s used to request a refresh token to renew an expired access token without user intervention).
Trying to answer your questions:
Is specifying ‘openid’ in my scope what enables me to request profile?
This is what enables OpenID Connect (an ID Token in the response, and access to the
/userinfo endpoint with the returned Access Token).
What would happen if I included ‘profile’ but not ‘openid’? Would it return an error because you need ‘openid’ in order to request ‘profile’, or would it return something different for ‘profile’ if I didn’t specify ‘openid’?
Technically, it wouldn’t be a valid OIDC request, and the response is not defined. The OIDC Provider (Auth0 in this case) might try to return something useful anyway for compatibility reasons, but even if it does you shouldn’t rely on this behavior and make a proper request (
openid profile if that’s what you are after).
Hope this helps!