Auth0 Home Blog Docs

Scopes not respected when creating ID Token

oauth
#1

When creating an ID Token for a user following the spec for Resource Owner Password I’m finding that the “scopes” property of the request is not being respected. In the following snippet, I’d expect the server to return a token with only the requested scope, and instead I’m getting a token with a bunch of extra scopes that I do not want for security reasons.

curl -X "POST" "https://MYDOMAIN.eu.auth0.com/oauth/token" \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "username": "pcifani@domain.com",
  "password": "THE_PASSWORD",
  "client_id": "THE_CLIENT_ID",
  "scope": "openid",
  "realm": "Username-Password-Authentication",
  "grant_type": "http://auth0.com/oauth/grant-type/password-realm"
}'

And this is the response for that request. Please note the extra non-required scopes:

{
   "access_token":"ACCESS_TOKEN",
   "id_token":"ID_TOKEN",
   "scope":"openid profile email address phone",
   "expires_in":86400,
   "token_type":"Bearer"
}

When performing login using a native SDK and using the WebAuth flow, the scopes property works as documented.

Is this expected behaviour? What could I do to remove unnecessary scopes from the returned token?

#2

Be default for resource owner password credentials flow the authorization server issues access tokens with all OIDC scopes granted independently of the exact set of OIDC scopes requested by the client. The OIDC scope parameter is used per OAuth 2.0 rules and from that specification the authorization server may ignore the actual requested scopes and issue scopes according to the server policy and in this particular case it’s what happens.

In other words, when using ROPC, by default the issued OIDC scopes will be all of them; if you really require to issue an access token with a different set of scopes for this grant you may implement a custom rule that sets context.accessToken.scope. For example, context.accessToken.scope = "openid"; would always issue only that scope, however, given rules run for all aplications and end-user login flows you would likely need to wrap this statement under conditional logic.

In addition, an access token may also be requested for a custom API and that API could have their own set of scopes so having a statement like the previous one would also prevent any API custom API scopes from being issued which may not be what you want. In conclusion, if you choose to control scopes through rules you need to be very careful with the conditional and scope setting logic so that you ensure you don’t affect other flows.