Subject: Re: [OAUTH-WG] draft-ietf-oauth-resource-indicators-02

From: Brian Campbell <[email-masked]>
Date: Sat, 2 Mar 2019 07:26:22 -0700

It's not uncommon for a resource server (or API or protected resource) to
have a client id established with the AS. Typically that's used in the
context of the resource server acting as a client (and authenticating with
the AS) when calling the AS for access token introspection.  Using that id
as the audience of an access token is certainly a possibility. But for
other client's to know and use the client id of a resource server as the
value of ‘resource’ parameter seems somewhat awkward and unlikely to work
particularly well. Also the syntax of the values don't quite match up.
n
On Wed, Feb 27, 2019 at 12:46 AM Jaap Francke <jaap.francke=
[email-masked]> wrote:

> Hi all,
>
> I have some questions/thoughts on the new draft for resource indicators.
> I didn’t do an in-depth study but would like to share my thoughts with you
> anyway.
>
> 1. In this draft, the Resource is identified by ‘resource’ parameter. For
> example, when the resource is an API, I would expect that API to validate
> the access_token at the resource server. The protocol for this would be
> based on the API’s client_id, so from that angle using the the client_id
> could be a different way to indicate the intended recipient of the access
> token.
>
> 2. I also think that the ‘resource’ parameter would be closely related to
> the “aud” claim specified by the OpenID Connect specifications. I think it
> is getting more and more common to use the OIDC-protocol “on top of OAuth”,
> so I’m wondering how the resource parameter would relate to that. The
> values of the ‘aud’ parameter are also client_id’s.
>
> Thanks in advance for responding to my views.
> Ciao!
>
> Jaap Francke
>
>
>
> On 26 Feb 2019, at 21:00, [email-masked] wrote:
>
>    draft-ietf-oauth-resource-indicators-02
>
>
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

-- 
_CONFIDENTIALITY NOTICE: This email may contain confidential and privileged 
material for the sole use of the intended recipient(s). Any review, use, 
distribution or disclosure by others is strictly prohibited.  If you have 
received this communication in error, please notify the sender immediately 
by e-mail and delete the message and any file attachments from your 
computer. Thank you._

---

From: Justin Richer <[email-masked]>
Date: Mon, 4 Mar 2019 02:16:56 +0000

There’s a difference in the intended audience of the access token in OAuth vs. the ID token in OpenID Connect. In OIDC, the ID token is read by the client, so the audience of the ID token is the client’s ID. That’s the only party reading that token, in the usual case. In OAuth, the access token goes to the protected resource (or the “API” as you say here). This resource could have an identifier, but it’s not *really* a client ID, since the resource isn’t a “client” in the OAuth sense. As Brian mentioned in his email, due to some unfortunate overlap in functionality, the resource server could be issued its own ID and secret, but these are really *resource* ID and not *client* ID, even though they use the “client_id” parameter for authentication. To confuse things even further, many implementations will store resource servers as “clients” with a special flag. It’s a matter of hindsight that we could have used an abstraction above these two things, some kind of “thing that calls the authorization server” of which instances would include resource servers and clients.

So in the end, the audience of an access token is not a client, and therefore this field isn’t a client ID. Additionally, the ID given to a resource server which could be used in either the “resource” and “audience” field isn’t a client ID either because the resource isn’t a client.

And finally, the “resource” identifier used in this parameter is something that has to be known to the client, so that the client can request it at runtime. A system is unlikely to publish a resource server’s internal identifier in this way, and will instead use a developer-facing name or a URL of some flavor.

Hope this clears things up, as much as it can be. I agree that between “resource”, “audience”, and “scope”, plus the UMA standard’s “permission” structure, things are more than a bit messy now.

— Justin

On Feb 27, 2019, at 2:46 AM, Jaap Francke <jaap.francke=[email-masked]<mailto:jaap.francke=[email-masked]>> wrote:

Hi all,

I have some questions/thoughts on the new draft for resource indicators.
I didn’t do an in-depth study but would like to share my thoughts with you anyway.

1. In this draft, the Resource is identified by ‘resource’ parameter. For example, when the resource is an API, I would expect that API to validate the access_token at the resource server. The protocol for this would be based on the API’s client_id, so from that angle using the the client_id could be a different way to indicate the intended recipient of the access token.

2. I also think that the ‘resource’ parameter would be closely related to the “aud” claim specified by the OpenID Connect specifications. I think it is getting more and more common to use the OIDC-protocol “on top of OAuth”, so I’m wondering how the resource parameter would relate to that. The values of the ‘aud’ parameter are also client_id’s.

Jaap Francke

On 26 Feb 2019, at 21:00, [email-masked]<mailto:[email-masked]> wrote:

_______________________________________________
OAuth mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/oauth

---

From: Vittorio Bertocci <[email-masked]>
Date: Mon, 4 Mar 2019 10:15:15 -0800

To add some color, here there's a concrete scenario where many of those
concepts come together (or collide, if you prefer).
Azure AD implements am early draft of token exchange, largely for
implementing a cloud friendly version of kerberos constrained delegation-
say a native client calls a mid tier API, and the mid tier API turns around
and calls a backend API flowing the identity of the user.
In order to do so, the mid-tier API performs a request to the authorization
server asking for the scopes the backend API requires, and presenting as a
grant the access token it received from the native client. The AS verifies
that the resource owner previously granted consent (as there is no
opportunity to show any UX). Here's the relevant part: *the AS also
verifies whether the audience in the access token (in whatever way it is
expressed) corresponds to the client ID of the requestor, to prevent MITM
attacks to gain an avenue for minting new tokens from arbitrarily captured
ATs*. In other words, the AS needs a mechanism to know that the resource
indicator for the mid tier API and the client ID used by the app
implementing that API to ask for new tokens are in fact pointing to the
same entity.
The AS can always do this on its own, without relying on any standard
guidance, and provide its own mechanism to associate API resource
indicators with client IDs - but this scenario does suggest that it would
be handy to be able to use the mid tier API clientID as an identifier in
the request from the native client to get the bootstrap token.
I agree that doing so today is super confusing, as the developer would use
something with "client" in its name to indicate a resource. To me this is a
consequence of expressing everything in term of clients, which comes from
the OAuth2 heritage of those flows, but doesn't provide a way of modeling
the frequent occurrence in which an application legitimately plays both the
resource (in the most general sense, including web sites) and the client
role.

On Sun, Mar 3, 2019 at 6:17 PM Justin Richer <[email-masked]> wrote:

> There’s a difference in the intended audience of the access token in OAuth
> vs. the ID token in OpenID Connect. In OIDC, the ID token is read by the
> client, so the audience of the ID token is the client’s ID. That’s the only
> party reading that token, in the usual case. In OAuth, the access token
> goes to the protected resource (or the “API” as you say here). This
> resource could have an identifier, but it’s not *really* a client ID, since
> the resource isn’t a “client” in the OAuth sense. As Brian mentioned in his
> email, due to some unfortunate overlap in functionality, the resource
> server could be issued its own ID and secret, but these are really
> *resource* ID and not *client* ID, even though they use the “client_id”
> parameter for authentication. To confuse things even further, many
> implementations will store resource servers as “clients” with a special
> flag. It’s a matter of hindsight that we could have used an abstraction
> above these two things, some kind of “thing that calls the authorization
> server” of which instances would include resource servers and clients.
>
> So in the end, the audience of an access token is not a client, and
> therefore this field isn’t a client ID. Additionally, the ID given to a
> resource server which could be used in either the “resource” and “audience”
> field isn’t a client ID either because the resource isn’t a client.
>
> And finally, the “resource” identifier used in this parameter is something
> that has to be known to the client, so that the client can request it at
> runtime. A system is unlikely to publish a resource server’s internal
> identifier in this way, and will instead use a developer-facing name or a
> URL of some flavor.
>
> Hope this clears things up, as much as it can be. I agree that between
> “resource”, “audience”, and “scope”, plus the UMA standard’s “permission”
> structure, things are more than a bit messy now.
>
> — Justin
>
> On Feb 27, 2019, at 2:46 AM, Jaap Francke <
> jaap.francke=[email-masked]> wrote:
>
> Hi all,
>

---

From: Justin Richer <[email-masked]>
Date: Mon, 4 Mar 2019 21:38:02 +0000

But in this scenario, the “audience” of the token is the resource server’s ID, right? And not the original client’s client id. This is a case where the RS is :also: a client, because of the token exchange bit, but you can’t say the audience is always going to be a client ID because most resource servers out there aren’t also going to be clients in their own right.

— Justin

On Mar 4, 2019, at 1:15 PM, Vittorio Bertocci <[email-masked]<mailto:[email-masked]>> wrote:

To add some color, here there's a concrete scenario where many of those concepts come together (or collide, if you prefer).
Azure AD implements am early draft of token exchange, largely for implementing a cloud friendly version of kerberos constrained delegation- say a native client calls a mid tier API, and the mid tier API turns around and calls a backend API flowing the identity of the user.
In order to do so, the mid-tier API performs a request to the authorization server asking for the scopes the backend API requires, and presenting as a grant the access token it received from the native client. The AS verifies that the resource owner previously granted consent (as there is no opportunity to show any UX). Here's the relevant part: the AS also verifies whether the audience in the access token (in whatever way it is expressed) corresponds to the client ID of the requestor, to prevent MITM attacks to gain an avenue for minting new tokens from arbitrarily captured ATs. In other words, the AS needs a mechanism to know that the resource indicator for the mid tier API and the client ID used by the app implementing that API to ask for new tokens are in fact pointing to the same entity.
The AS can always do this on its own, without relying on any standard guidance, and provide its own mechanism to associate API resource indicators with client IDs - but this scenario does suggest that it would be handy to be able to use the mid tier API clientID as an identifier in the request from the native client to get the bootstrap token.
I agree that doing so today is super confusing, as the developer would use something with "client" in its name to indicate a resource. To me this is a consequence of expressing everything in term of clients, which comes from the OAuth2 heritage of those flows, but doesn't provide a way of modeling the frequent occurrence in which an application legitimately plays both the resource (in the most general sense, including web sites) and the client role.

On Sun, Mar 3, 2019 at 6:17 PM Justin Richer <[email-masked]<mailto:[email-masked]>> wrote:
There’s a difference in the intended audience of the access token in OAuth vs. the ID token in OpenID Connect. In OIDC, the ID token is read by the client, so the audience of the ID token is the client’s ID. That’s the only party reading that token, in the usual case. In OAuth, the access token goes to the protected resource (or the “API” as you say here). This resource could have an identifier, but it’s not *really* a client ID, since the resource isn’t a “client” in the OAuth sense. As Brian mentioned in his email, due to some unfortunate overlap in functionality, the resource server could be issued its own ID and secret, but these are really *resource* ID and not *client* ID, even though they use the “client_id” parameter for authentication. To confuse things even further, many implementations will store resource servers as “clients” with a special flag. It’s a matter of hindsight that we could have used an abstraction above these two things, some kind of “thing that calls the authorization server” of which instances would include resource servers and clients.

— Justin

Hi all,

Jaap Francke