Add flag to block additional audiences from initial access token
Description
Environment
is blocked by
Confluence content
Activity
Henri MikkonenOctober 4, 2024 at 10:31 AMEdited
The access token audience is limited to self when the following conditions are met:
The new profile configuration flag limitInitialAccessTokenToSelf is set to true
The inbound message is TokenRequest with authorization_code grant
The openid scope is involved
If not, a warning is logged that the flag is not respected
Henri MikkonenOctober 3, 2024 at 4:41 PM
Actually, I believe the flag would only be needed for the OAUTH2.Token profile: whenever authorization code grant is not involved, no refresh token will be issued. It then means that in those cases the access token is the only one and it cannot be refreshed, so the audience requested in the authorization request message should be always respected.
The OAuth2 RFC is very strict about it for the implicit grant (section 4.2.2): ”The authorization server MUST NOT issue a refresh token.
”
Similar, but not that strict for the client credentials grant: RFC (section 4.4.3) says “A refresh token SHOULD NOT be included
".
Scott CantorOctober 3, 2024 at 4:17 PM
Fair point, I forgot about the empty case already failing. It works pretty cleanly in the OpenID case but it’s not obvous what to do in the OAuth case.
Originally I was thinking about something more like a list of audiences to include (as a final filtering step), but a flag was simpler so I was reaching for that approach. I also think it’s a bad idea to complicate this too much because it’s such a rare case anyway.
I think I would argue that we should just keep it simple, use a flag, and only bother using it in the OpenID case for the implicit and code grant scenarios. If you did a vanilla OAuth request, I think I’d just punt and keep doing what we’re doing, and include them all normally.
My thought was we’d have the flag on both Authz and Token profiles, and per usual, it gets looked at in whatever situation makes sense (so access token issued front-channel uses the Authz profile, back-channel uses the Token profile), and again, just ignore it if there’s no OpenID scope.
The edge case then is the client_credentials grant, but I think that’s pretty silly anyway since you’re just adding more round trips for no reason, you can just request the specific tokens you want directly (and since the OpenID scope isn’t gonna be there for that case, it should fall out normally via the “ignore the flag” rule).
So that’s my 2 cents.
Henri MikkonenOctober 3, 2024 at 3:59 PM
The current logic is that the client/RP may reduce/limit the additional audience via resource-parameter in the token endpoint too. It only affects the access token: the refresh token (if enabled) may be used for fetching a new access token with different audience. The full audience set from the authorization code grant is included to the refresh token grant.
Technically speaking the flag described in this issue would be equivalent to using empty resource-parameter value in the token endpoint, whenever openid
scope is involved. That scope means that OP will be included in the audience in any case, as the access token needs to be usable in the UserInfo endpoint. Empty resource only works with the openid
scope, as otherwise we wouldn’t have any audience to the access token, and error response with code invalid_target
would be returned.
So, if I’m understanding this correctly, the flag would be used for stripping all the other audiences whenever openid
scope is involved? A flag may be a bit too inflexible though, perhaps a some kind of trade-off between the flag and message handlers (or inbound interceptors or even custom parsers) that allow full request message manipulation.
In discussions about more advanced cases, was noted that it might be good for security reasons to limit the set of audiences that are in the “initial” access token issued from an authz request or via code grant so that token would only be usable with the UserInfo endpoint.
The client could use the refresh token to request additional access tokens with specific subsets of the originally granted audiences as they see fit, so there’d be no token issued up front that could be misused across all the audiences at once.
This mainly comes into play when multiple audiences are requested, and I probably should have defaulted it that way if I’d thought of it.