Prevent "upscoping" in the token-exchange workflow
As discussed at the IAM Hackathon (July 2025), following up with a ticket on this topic. The request is to have a way to prevent clients from obtaining additional scopes (upscoping) via the token-exchange workflow.
During the token-exchange, the acting client should not be able to obtain scopes outside of those present in the subject token. This is particularly relevant for FTS, where we are interested in obtaining a refresh token, but purposefully don't change token scopes, as we want to conserve the ones from the initial subject token.
Steps to reproducing
- Obtain the initial (subject) token
$ SUBJECT_TOKEN=$(...)
$ token-decode "${SUBJECT_TOKEN}" | jq .scope
"storage.read:/"
- Perform the token exchange
$ curl -s -u "${CLIENT_ID}:${CLIENT_SECRET}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
--data "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
--data "subject_token=${SUBJECT_TOKEN}" \
--data "scope=storage.read:/ storage.modify:/ offline_access" \
--data "audience=https://wlcg.cern.ch/jwt/v1/any" \
https://dteam-auth.cern.ch/token
- Exchanged token contains additional scopes
$ EXCHANGED_TOKEN=$(..)
$ token-decode "${EXCHANGED_TOKEN}" | jq .scope
"offline_access storage.modify:/ storage.read:/""
Request
The token-exchange should not allow obtaining additional scopes not present in the initial, subject token (with the obvious exception of the offline_access).
I understand this change will not be desirable for all communities, which is why this setting is a good candidate to be a per-client configuration option. At least for WLCG + FTS, we'd prefer upscoping is not allowed, limiting a vulnerable pathway for the FTS usecase.