Subject: [Txauth] JSON Schema?

From: Dick Hardt <[email-masked]>
Date: Mon, 6 Jul 2020 12:00:51 -0700

Hey

Does anyone have experience and/or opinions on JSON Schema [1]?

When implementing XAuth [2], I wrote a bunch of hand crafted JSON
validation code. JSON schema looks like it could be a great way to validate
input, and to create automated tests for output. It may also be a great way
to document the Grant Response JSON.

/ Dick

[1] https://json-schema.org/
[2] https://github.com/dickhardt/XAuth-poc

---

From: "Wayne Chang" <[email-masked]>
Date: Mon, 06 Jul 2020 15:12:40 -0400

I've used this approach to provide conformance tests to specifications. Here's a self-contained dir doing that:

https://github.com/decentralized-identity/presentation-exchange/tree/6b1b42338dd5ad96f67b7fee43187d96535b95a9/test/submission-requirements

It can then be run using `yarn run test`, as defined in:
https://github.com/decentralized-identity/presentation-exchange/blob/6b1b42338dd5ad96f67b7fee43187d96535b95a9/package.json#L20

Last note is that I see the v7 version with most supported implementations across different languages, so I've stuck with that one:
https://json-schema.org/draft-07/json-schema-release-notes.html

On Mon, Jul 6, 2020, at 3:00 PM, Dick Hardt wrote:
> When implementing XAuth [2], I wrote a bunch of hand crafted JSON validation code. JSON schema looks like it could be a great way to validate input, and to create automated tests for output. It may also be a great way to document the Grant Response JSON.
> 
> / Dick
> 
> -- 
> Txauth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/txauth
>

---

From: Justin Richer <[email-masked]>
Date: Mon, 6 Jul 2020 15:54:07 -0400

I think it’s potentially ok for defining the specification and its boundaries, but it is not ok if it ends up requiring client and AS developers to use JSON Schema directly to implement anything. In other words, you should be a able to still write a bunch of hand-crafted validation code to make it work, or to use a parser that drops things into structured objects for you (like my Java implementation of XYZ does). Much like my argument against JSONLD, I think anything beyond a JSON parser 

Another aspect that I don’t like about JSON schema is that it makes it difficult to describe things in terms of polymorphic data types. Polymorphism in the protocol is an important part of the XYZ proposal’s design, and as a feature it directly addresses a number of the items you found when doing your XAuth implementation, like parsing OAuth scopes and dealing with the authorization/authorizations mutually-exclusive oddness that you mentioned. I strongly believe that GNAP should make use of a polymorphic protocol structure for these and other reasons. Polymorphism is a built-in feature of the JSON data model, and it’s also fully possible to support under CBOR and other data serialization languages. Even JWT most famously uses polymorphism for the “aud” field, which can be a string or an array of strings depending on context, all with clear semantics. Defining that in JSON schema is not impossible, but it’s not easy.

So overall, I think JSON schema is probably not a good fit here.

 — Justin

> On Jul 6, 2020, at 3:00 PM, Dick Hardt <[email-masked]> wrote:
> 
> Hey
> 
> [1] https://json-schema.org/ <https://json-schema.org/>
> [2] https://github.com/dickhardt/XAuth-poc <https://github.com/dickhardt/XAuth-poc>
> 
> 
> -- 
> Txauth mailing list
> [email-masked]

---

From: Justin Richer <[email-masked]>
Date: Mon, 6 Jul 2020 15:55:52 -0400

> On Jul 6, 2020, at 3:54 PM, Justin Richer <[email-masked]> wrote:
> 

… and generator is too much to ask. (Sorry, hit send too early.)

>> On Jul 6, 2020, at 3:00 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> Hey
>> 
>> [email-masked] <mailto:[email-masked]>

---

From: Dick Hardt <[email-masked]>
Date: Mon, 6 Jul 2020 13:16:27 -0700

Thanks Wayne and Justin.

I agree that we would not want to make it an implementation requirement.

I asked Tim Bray his thoughts (edited the IETF JSON specs, one of XML
creators)

Tim has written a number of blog posts on JSON Schema. TL;DR: he is not a
huge fan.

He pointed out the IETF JSON Type Definition ID [2]. This looks much
simpler and addresses many of the concerns Tim had expressed with JSON
Schema. It also has a more recent draft published on the IETF.
Unfortunately there do not seem to be many implementations, and the website
[3] is missing the promised docs [4]. The latest ID [5] looks to be derived
from CDDL (RFC 8610) [6].

I reached out to the core JSON Schema people, and they are focussed on
making JSON Schema changes to support efforts for the next version of Open
API [7]

My take: I may use Open Schema in my PoC implementation not unlike what
Wayne did, but it does not look like either JSON Schema or JSON Type
Definition is ready for the WG to use at this point.

/Dick

[1]
https://www.google.com/search?as_q=json+schema&hl=en&ie=UTF-8&btnG=Google%2BSearch&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=tbray.org
<https://www.google.com/search?as_q=json+schema&hl=en&ie=UTF-8&btnG=Google%2BSearch&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=tbray.org>

[2] https://datatracker.ietf.org/doc/draft-ucarion-json-type-definition/

[3] https://jsontypedef.com/

[4] https://jsontypedef.com/docs/getting-started/overview

[5] https://tools.ietf.org/html/draft-ucarion-json-type-definition-04

[6] https://tools.ietf.org/html/rfc8610

[7] https://github.com/OAI/OpenAPI-Specification

On Mon, Jul 6, 2020 at 12:55 PM Justin Richer <[email-masked]> wrote:

> I think it’s potentially ok for defining the specification and its
> boundaries, but it is not ok if it ends up requiring client and AS
> developers to use JSON Schema directly to implement anything. In other
> words, you should be a able to still write a bunch of hand-crafted
> validation code to make it work, or to use a parser that drops things into
> structured objects for you (like my Java implementation of XYZ does). Much
> like my argument against JSONLD, I think anything beyond a JSON parser
>
>
> Another aspect that I don’t like about JSON schema is that it makes it
> difficult to describe things in terms of polymorphic data types.
> Polymorphism in the protocol is an important part of the XYZ proposal’s
> design, and as a feature it directly addresses a number of the items you
> found when doing your XAuth implementation, like parsing OAuth scopes and
> dealing with the authorization/authorizations mutually-exclusive oddness
> that you mentioned. I strongly believe that GNAP should make use of a
> polymorphic protocol structure for these and other reasons. Polymorphism is
> a built-in feature of the JSON data model, and it’s also fully possible to
> support under CBOR and other data serialization languages. Even JWT most
> famously uses polymorphism for the “aud” field, which can be a string or an
> array of strings depending on context, all with clear semantics. Defining
> that in JSON schema is not impossible, but it’s not easy.
>

---

From: Justin Richer <[email-masked]>
Date: Mon, 6 Jul 2020 16:30:42 -0400

The best thing about schema languages is that there are so many of them to choose from. :)

I do like Wayne’s idea of using JSON schema (or something similar) in a validation test suite, and that’s something that the group should consider. Formal tools like test suites, use case documents, and formal analysis are all in our toolbox as we build out GNAP, and so we can decide which, if any, make sense.

 — Justin

> On Jul 6, 2020, at 4:16 PM, Dick Hardt <[email-masked]> wrote:
> 
> Thanks Wayne and Justin.
> 
> I asked Tim Bray his thoughts (edited the IETF JSON specs, one of XML creators)
> 
> Tim has written a number of blog posts on JSON Schema. TL;DR: he is not a huge fan. 
> 
> He pointed out the IETF JSON Type Definition ID [2]. This looks much simpler and addresses many of the concerns Tim had expressed with JSON Schema. It also has a more recent draft published on the IETF. Unfortunately there do not seem to be many implementations, and the website [3] is missing the promised docs [4]. The latest ID [5] looks to be derived from CDDL (RFC 8610) [6].
> 
> I reached out to the core JSON Schema people, and they are focussed on making JSON Schema changes to support efforts for the next version of Open API [7]
> 
> My take: I may use Open Schema in my PoC implementation not unlike what Wayne did, but it does not look like either JSON Schema or JSON Type Definition is ready for the WG to use at this point.
> 
> /Dick
> 
> [1] https://www.google.com/search?as_q=json+schema&hl=en&ie=UTF-8&btnG=Google%2BSearch&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=tbray.org <https://www.google.com/search?as_q=json+schema&hl=en&ie=UTF-8&btnG=Google%2BSearch&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=tbray.org>
> [2] https://datatracker.ietf.org/doc/draft-ucarion-json-type-definition/ <https://datatracker.ietf.org/doc/draft-ucarion-json-type-definition/>
> 
> [3] https://jsontypedef.com/ <https://jsontypedef.com/>
> 
> [4] https://jsontypedef.com/docs/getting-started/overview <https://jsontypedef.com/docs/getting-started/overview>
> 
> [5] https://tools.ietf.org/html/draft-ucarion-json-type-definition-04 <https://tools.ietf.org/html/draft-ucarion-json-type-definition-04>
> 
> [6] https://tools.ietf.org/html/rfc8610 <https://tools.ietf.org/html/rfc8610>
> 
> [7] https://github.com/OAI/OpenAPI-Specification <https://github.com/OAI/OpenAPI-Specification>
> 
> 
> On Mon, Jul 6, 2020 at 12:55 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> 
>> On Jul 6, 2020, at 3:54 PM, Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>>> https://www.ietf.org/mailman/listinfo/txauth <https://www.ietf.org/mailman/listinfo/txauth>
>> 
>> -- 
>> Txauth mailing list
>> https://www.ietf.org/mailman/listinfo/txauth <https://www.ietf.org/mailman/listinfo/txauth>
>

---

From: Dick Hardt <[email-masked]>
Date: Mon, 6 Jul 2020 13:41:14 -0700

Responding to Justin's polymorphism comments ...

On Mon, Jul 6, 2020 at 12:54 PM Justin Richer <[email-masked]> wrote:

> array of strings depending on context, all with clear semantics.
>

 I strongly disagree with "GNAP should make use of a polymorphic protocol
structure"

We should use it only if we really need it, and it makes implementations
simpler. I personally don't think it accomplished that in JWT with the
audience. I would bet there is a fair amount of code that does not check if
the 'aud' property is an array, it just assumes it is a string.

wrt. my authorization / authorizations oddness, polymorphism would not
solve it as the contents of both authorization / authorizations in XAuth
are objects.

/Dick

---

From: Justin Richer <[email-masked]>
Date: Mon, 6 Jul 2020 17:15:04 -0400

I once felt that way, too, and the first few iterations of XYZ did not use polymorphism. But I found, through hands-on experience, that it solves many more problems than it creates. I think that JWT didn’t quite do it because there was one limited place in the spec that used the feature — it was the exception, not a core part of the data model. And, JWT implementations that don’t expect an array in “aud” aren’t compliant, after all.

This is obviously an implementation detail for the WG to debate, and I think polymorphism should be one of the tools in consideration from the start. 

 — Justin

> On Jul 6, 2020, at 4:41 PM, Dick Hardt <[email-masked]> wrote:
> 
> 
> On Mon, Jul 6, 2020 at 12:54 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> Polymorphism in the protocol is an important part of the XYZ proposal’s design, and as a feature it directly addresses a number of the items you found when doing your XAuth implementation, like parsing OAuth scopes and dealing with the authorization/authorizations mutually-exclusive oddness that you mentioned. I strongly believe that GNAP should make use of a polymorphic protocol structure for these and other reasons. Polymorphism is a built-in feature of the JSON data model, and it’s also fully possible to support under CBOR and other data serialization languages. Even JWT most famously uses polymorphism for the “aud” field, which can be a string or an array of strings depending on context, all with clear semantics.
> 
>  I strongly disagree with "GNAP should make use of a polymorphic protocol structure"
> 
> We should use it only if we really need it, and it makes implementations simpler. I personally don't think it accomplished that in JWT with the audience. I would bet there is a fair amount of code that does not check if the 'aud' property is an array, it just assumes it is a string.
> 
> wrt. my authorization / authorizations oddness, polymorphism would not solve it as the contents of both authorization / authorizations in XAuth are objects. 
> 
> /Dick
>

---

From: Dick Hardt <[email-masked]>
Date: Mon, 6 Jul 2020 14:18:23 -0700

I agree with:

"I think polymorphism should be one of the tools in consideration from the
start."

I was disagreeing with the 'should' in:

"GNAP should make use of a polymorphic protocol structure"

On Mon, Jul 6, 2020 at 2:15 PM Justin Richer <[email-masked]> wrote:

> I once felt that way, too, and the first few iterations of XYZ did not use
> polymorphism. But I found, through hands-on experience, that it solves many
> more problems than it creates. I think that JWT didn’t quite do it because
> there was one limited place in the spec that used the feature — it was the
> exception, not a core part of the data model. And, JWT implementations that
> don’t expect an array in “aud” aren’t compliant, after all.
>
> This is obviously an implementation detail for the WG to debate, and I
> think polymorphism should be one of the tools in consideration from the
> start.
>
>  — Justin
>

---

From: Benjamin Kaduk <[email-masked]>
Date: Mon, 6 Jul 2020 22:30:48 -0700

> Schema. It also has a more recent draft published on the IETF.

FWIW, draft-ucarion-json-type-definition is in the RFC Editor's queue as a
document published via the ISE stream, as can be seen at
https://www.rfc-editor.org/current_queue.php and
https://datatracker.ietf.org/doc/draft-ucarion-json-type-definition/

It's only been at the RFC Editor for a week or so, and we're running 10
weeks minimum to publication, it will not be an RFC for anouther couple
months at least.

-Ben

---

From: Justin Richer <[email-masked]>
Date: Tue, 7 Jul 2020 06:40:47 -0400

> wrt. my authorization / authorizations oddness, polymorphism would not solve it as the contents of both authorization / authorizations in XAuth are objects. 

It’s not surprising that this is the case, as the XAuth protocol was not designed with polymorphism as a tool to consider. This is exactly the reason that I say we should have polymorphism in the toolbox from the start, as it allows us to avoid this kind of awkwardness in many cases.

The equivalent “resources” structure in XYZ uses an array to convey the scope strings and the rich request objects at the same level. This allows the protocol to have one construct, the “resources” array, that contains items that describe what rights the client is requesting in the resulting access token. An array of items is the natural representation of such a construct in a JSON-based protocol.

The reason for this design is a simple adaptation of OAuth 2. The native data structure underlying the OAuth 2 “scope” parameter is a set, but OAuth 2 had to invent a standard serialization for it (the space-separated single string) in order to convey it across the front channel as a query parameter. I remember we’d considered making it an array in the token endpoint response, but ultimately decided to keep it consistent with the lowest-common-denominator representation, which makes sense. However, we aren’t bound to that limitation of OAuth 2 anymore and so there is no reason to keep the space-separated-string notion around. At the very least, scopes should be a native JSON array of strings. RAR uses a JSON array of objects natively, but encodes it as a URL-encoded string in order to fit into OAuth 2’s front channel and token endpoint push. Should we also keep the encoding part of RAR if we keep the space-separated-string encoding of scope from OAuth 2? It certainly seems silly to argue for that, and  would argue that we need neither string-based encoding and we can use native structures for both.

Since GNAP is also allowing fine-grained requests as well as the more course-grained scope style access, we can also put them together. This would allow us to have a single array of elements, each element being either a single string or an object with multiple dimensions. 

Now: while this is an example of the benefits of polymorphism at the protocol level, how does this help the authorization/authorizations conundrum above? In XYZ, a single access token request is an array of “resource” elements, but a multiple access token request is an object/map, whose values are the same “resource” arrays as a single request. This makes the requests much more consistent to create and parse than having two closely-named and mutually-exclusive properties. 

This isn’t a magic panacea though, and it requires a bit of work to apply the tools well. When I added multiple access tokens to XYZ, I didn’t want to change the format of the single access token, which was already an object. The natural response type of the multiple access tokens was also an object, and so we ended up with — you guessed it — a pair of closely-named and mutually-exclusive properties. I don’t like it, and I think there’s likely a better way around this, but I haven’t gone back to try and design that problem out yet. But it’s something that I think we can likely address in GNAP, especially if we’re willing to step back and change how we look at things.

 — Justin

---

From: Dick Hardt <[email-masked]>
Date: Tue, 7 Jul 2020 16:30:55 -0700

On Tue, Jul 7, 2020 at 3:40 AM Justin Richer <[email-masked]> wrote:

> It’s not surprising that this is the case, as the XAuth protocol was not
> designed with polymorphism as a tool to consider. This is exactly the
> reason that I say we should have polymorphism in the toolbox from the
> start, as it allows us to avoid this kind of awkwardness in many cases.
>

 What evidence do you have to make this statement? "XAuth protocol was not
designed with polymorphism as a tool to consider"

It sounds like you are saying I did not consider polymorphism in the XAuth
protocol design.

I will restate my comment above about polymorphism.

Using different JSON types does not solve the problem, but as I suggest in
my comments, polymorphism of different JSON objects is one solution. An
authorization, or a dictionary of authorizations. It has the restriction
that the string "type" cannot be used as a label in the dictionary. An
example:

{
    "authorizations" {
        "type": "oauth_scope",
        "scope": "read write"
    }
}

{
    "authorizations" {
        "reader": {
            "type": "oauth_scope",
            "scope": "read"
        },
        "writer": {
            "type": "oauth_scope",
            "scope": "write"
        },
    }
}

I am looking at making this change in XAuth and in the implementation.

ᐧ

---

From: Justin Richer <[email-masked]>
Date: Wed, 8 Jul 2020 10:03:38 -0400

I’m glad that you’re looking at polymorphism as a possible solution to this, though I would contend that this particular style of polymorphism is not doing much more than pushing the mutual-exclusivity check down a layer instead of solving it. 

Using multiple types can in fact solve this problem, and several others, as long as you’re willing to let go of the syntax that OAuth 2 invented to solve a problem that we don’t have to solve here (passing an array-type value over the front channel). In XYZ’s syntax, the request for a single access token would look like this:

{
  “resources”: [ “read”, “write” ]
}

And the request for the multiple access tokens would look like this:

{
  “resources": {
     “reader": [ “read” ],
     “writer”: [ “write” ]
  }
}

I find this to be much simpler to parse and generate, as you no longer need to check for a specially-reserved field name (“type”), and you no longer have to do a sub-parse on one of the values to get what you really want (the space-separated scope string into a set). It’s also a lot simpler for the developers that need to write this.

 — Justin

> On Jul 7, 2020, at 7:30 PM, Dick Hardt <[email-masked]> wrote:
> 
> 
> 
> On Tue, Jul 7, 2020 at 3:40 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>  What evidence do you have to make this statement? "XAuth protocol was not designed with polymorphism as a tool to consider"
> 
> It sounds like you are saying I did not consider polymorphism in the XAuth protocol design.
> 
> Using different JSON types does not solve the problem, but as I suggest in my comments, polymorphism of different JSON objects is one solution. An authorization, or a dictionary of authorizations. It has the restriction that the string "type" cannot be used as a label in the dictionary. An example:
> 
> {
>     "authorizations" {
>         "type": "oauth_scope",
>         "scope": "read write"
>     }
> }
> 
> {
>     "authorizations" {
>         "reader": {
>             "type": "oauth_scope",
>             "scope": "read"
>         },
>         "writer": {
>             "type": "oauth_scope",
>             "scope": "write"
>         },
>     }
> }
> 
>

---

From: Dick Hardt <[email-masked]>
Date: Wed, 8 Jul 2020 09:55:02 -0700

Justin: it is disappointing that you deflect from responding to:

Similarly, you deflected responding to your statement:

How are we going to have a productive conversation when you won't
acknowledge mistakes, either intentional, or unintentional?

wrt. your proposal to represent an authorization request as an array of
scopes is overly simplistic. Both XYZ and XAuth represent the request as an
object to enable a request richer than just an array of scopes.

/Dick

On Wed, Jul 8, 2020 at 7:03 AM Justin Richer <[email-masked]> wrote:

> I’m glad that you’re looking at polymorphism as a possible solution to
> this, though I would contend that this particular style of polymorphism is
> not doing much more than pushing the mutual-exclusivity check down a layer
> instead of solving it.
>
> Using multiple types can in fact solve this problem, and several others,
> as long as you’re willing to let go of the syntax that OAuth 2 invented to
> solve a problem that we don’t have to solve here (passing an array-type
> value over the front channel). In XYZ’s syntax, the request for a single
> access token would look like this:
>
> {
> I find this to be much simpler to parse and generate, as you no longer
> need to check for a specially-reserved field name (“type”), and you no
> longer have to do a sub-parse on one of the values to get what you really
> want (the space-separated scope string into a set). It’s also a lot simpler
> for the developers that need to write this.
>
>  — Justin
>

---

From: Tom Jones <[email-masked]>
Date: Wed, 8 Jul 2020 10:10:29 -0700

a somewhat milder response might be.
It seems that justin's proposal is not, in fact, a grant negotiation, but a
generalized token format.
So - what could that mean here?
I have a problem with the whack-a-mole approach of OAuth, with RAR JAR ad
infinitum.
That is a never-ending stream of hacks.
if Justin's proposal is to be considered seriously, it must be at some
higher level that GNAP..
I suggest  that the current approach of xauth txauth authxyz is not really
headed to a convergence.
Perhaps we need to start with an abstract set of goals and data flows.  One
that includes the user/RO.
I do have one for healthcare - but i am short of time right now to
generalize it.
One item I would like to see resolved early is to remove the dependency on
transport layer security. One that includes the handling of key roll-over.
In Kantara we focused first on the legal responsibilities of the token
maker. That problem seems to have consumed FAPI, altho they have multiple
names for it.
In the real world we have legal entities (natural and unnatural) and legal
names (brands) as well as pseudonyms. OAuth just had endpoints with SSL
keys and certs.  How about we start there?
Peace ..tom

On Wed, Jul 8, 2020 at 9:55 AM Dick Hardt <[email-masked]> wrote:

>>  What evidence do you have to make this statement? "XAuth protocol was
>> not designed with polymorphism as a tool to consider"
>>
>> Using different JSON types does not solve the problem, but as I suggest
>> in my comments, polymorphism of different JSON objects is one solution. An

---

From: "Wayne Chang" <[email-masked]>
Date: Wed, 08 Jul 2020 13:39:12 -0400

Shifting to a new thread based on the interesting point Tom made about removing TLS requirements. Justin, I did see that you were careful to specify "TLS or equivalent" in your drafts, and Dick commented "[Editor: too aggressive to mandate HTTP/2 and TLS 1.3?]" in his. Maybe this is a good opportunity to explore the "or equivalent" part.

Some IoT environments do not and will not support HTTP + SSL/TLS, but could benefit from this grant framework. Instead, they may use application protocols like MQTT and more recently in conjunction with single-packet authorization (SPA). https://ieeexplore.ieee.org/document/8930455

>From the DID ecosystem, I can imagine some future interoperability between DIDComm and GNAP. It is not clear that TLS will be used for all DID-to-DID communications, which aim to be transport agnostic. See discussion here: https://github.com/decentralized-identity/didcomm-messaging/issues/38

What other potential non-TLS use cases are worth mentioning?

On Wed, Jul 8, 2020, at 1:10 PM, Tom Jones wrote:
> It seems that justin's proposal is not, in fact, a grant negotiation, but a generalized token format.
> I have a problem with the whack-a-mole approach of OAuth, with RAR JAR ad infinitum.
> if Justin's proposal is to be considered seriously, it must be at some higher level that GNAP..
> I suggest that the current approach of xauth txauth authxyz is not really headed to a convergence.
> Perhaps we need to start with an abstract set of goals and data flows. One that includes the user/RO.
> I do have one for healthcare - but i am short of time right now to generalize it.
> One item I would like to see resolved early is to remove the dependency on transport layer security. One that includes the handling of key roll-over.
> In Kantara we focused first on the legal responsibilities of the token maker. That problem seems to have consumed FAPI, altho they have multiple names for it.
> In the real world we have legal entities (natural and unnatural) and legal names (brands) as well as pseudonyms. OAuth just had endpoints with SSL keys and certs. How about we start there?
> Peace ..tom

---

From: Justin Richer <[email-masked]>
Date: Wed, 8 Jul 2020 13:46:26 -0400

I’m going to clip the personal attack here on the list and focus on the technical discussion, if that’s ok with everyone...

> 
> wrt. your proposal to represent an authorization request as an array of scopes is overly simplistic. Both XYZ and XAuth represent the request as an object to enable a request richer than just an array of scopes. 

I’m not sure why you think it’s overly simplistic: the example I have given is valid XYZ syntax that would exist at the root of the client’s request. Yes, XYZ also allows objects within the same array, to allow for richer requests, but it does not require you do that. This is again one of the values of doing polymorphism in this particular way. It’s as simplistic or as complex as you need it to be, but it’s consistent in its model and presentation for both parsing and generation. So let’s take your example of “read” and “write” scopes. If a client needs to do this, but also needs to do a rich request, it can put them all together like this:

{
  “resources”: [ 
    “read”, 
    “write”,
    {
      "type": "payment_initiation",
      "locations": [
         "https://example.com/payments"
      ],
      "instructedAmount": {
         "currency": "EUR",
         "amount": "123.50"
      },
      "creditorName": "Merchant123",
      "creditorAccount": {
         "iban": "DE02100100109307118603"
      },
      "remittanceInformationUnstructured": "Ref Number Merchant"
   }
  ]
}

Notice that the “resources” element is an array here. The first two elements of the array are strings — scopes. The third element of the array is an object — the multi-dimensional request (this example taken from the RAR spec). But it’s always a “list of things that I want”. Some of those things are references as strings, some of them are multi-dimensional specific rich objects.

This has been in XYZ’s design and implementations for well over a year, and it works well. This is also the basis that I’ve used for implementing XYZ on top of an old OAuth 2 server, which doesn’t speak RAR or any rich requests but knows how to dispatch against scopes. 

 — Justin

> /Dick
> 
> 
> 
> On Wed, Jul 8, 2020 at 7:03 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jul 7, 2020, at 7:30 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> 
>>

---

From: Stephen Moore <[email-masked]>
Date: Wed, 8 Jul 2020 14:09:08 -0400

Hi Dick,
I've looked over your draft, and the emails here. You said you didn't use
polymorphism, and the draft does not appear to use polymorphism. I'd think
it is safe to say that the XAuth protocol was not built with polymorphism
in mind. I don't think that Justin meant to imply you didn't consider it,
but rather that from the discussions (up to that point) and the draft
itself, it doesn't say polymorphism is a tool that can be applied in the
tokens.

As for the "GNAP should make use of a polymorphic protocol structure",
that's just his position on what he thinks GNAP should do. I don't really
see how that is a 'mistake'.
-steve

---

From: Dick Hardt <[email-masked]>
Date: Wed, 8 Jul 2020 11:58:36 -0700

Hi Steve

XAuth does make use of polymorphism, just not with JSON types. The
authorization object has a "type" property that indicates the semantics of
the rest of the authorization properties.

Justin's statement:

"the XAuth protocol was not designed with polymorphism as a tool to
consider"

seemed pretty clear to me that Justin stated that I did not consider
polymorphism in the design of the XAuth protocol, but to confirm, I asked
him to clarify, but have yet to get a response on the list.

Justin has stated:

and then later:

Which statement is his position?

While my comments were personal in nature as I was commenting on Justin's
response, they were not intended as an attack on Justin. In expressing my
disappointment in not getting a response from Justin, my frustration came
through and I apologize to the list and Justin for what I see could be
construed as counter productive.

/Dick

On Wed, Jul 8, 2020 at 11:09 AM Stephen Moore <[email-masked]> wrote:

>>>> > wrt. my authorization / authorizations oddness, polymorphism would
>>>> not solve it as the contents of both authorization / authorizations in
>>>> XAuth are objects.
>>>>
>>>> It’s not surprising that this is the case, as the XAuth protocol was
>>>> not designed with polymorphism as a tool to consider. This is exactly the

---

From: Dick Hardt <[email-masked]>
Date: Wed, 8 Jul 2020 12:16:00 -0700

I think representing the request as an array is simplistic, and complicated
at the same time.

On the simplistic front, as there is no clear mechanism for extending the
request with properties that apply to all of the request.

Using JSON type polymorphism requires the AS to test each member of the
array to determine if it is a string or an object. Only after detecting a
RAR object does the AS know the client is making a RAR request. This also
limits the request to be composed only of scope strings or RAR objects. I
don't see how other strings or objects could be used in the array, so there
is no clear extension point in the "resources" array for other query
mechanisms.

Just as RAR has a "type" property, I propose the "resources"
("authorizations" in XAuth) be an object, where the other properties are
determined by the "type" property. This allows extensions to define new
ways to query for an authorization rather than having to fit into scopes or
RAR.

/Dick

On Wed, Jul 8, 2020 at 10:46 AM Justin Richer <[email-masked]> wrote:

> I’m going to clip the personal attack here on the list and focus on the
> technical discussion, if that’s ok with everyone...
>
>
> I’m not sure why you think it’s overly simplistic: the example I have
> given is valid XYZ syntax that would exist at the root of the client’s
> request. Yes, XYZ *also* allows objects within the same array, to allow
> for richer requests, but it does not require you do that. This is again one
> of the values of doing polymorphism in this particular way. It’s as
> simplistic or as complex as you need it to be, but it’s consistent in its
> model and presentation for both parsing and generation. So let’s take your
> example of “read” and “write” scopes. If a client needs to do this, but
> also needs to do a rich request, it can put them all together like this:
>
> {
>   “resources”: [
>     “read”,
>     “write”,
>     {
> Notice that the “resources” element is an array here. The first two
> elements of the array are strings — scopes. The third element of the array
> is an object — the multi-dimensional request (this example taken from the
> RAR spec). But it’s always a “list of things that I want”. Some of those
> things are references as strings, some of them are multi-dimensional
> specific rich objects.
>
> This has been in XYZ’s design and implementations for well over a year,
> and it works well. This is also the basis that I’ve used for implementing
> XYZ on top of an old OAuth 2 server, which doesn’t speak RAR or any rich
> requests but knows how to dispatch against scopes.
>
>  — Justin
>
>
> /Dick
>
>
>

---

From: Justin Richer <[email-masked]>
Date: Wed, 8 Jul 2020 16:02:11 -0400

On Jul 8, 2020, at 3:16 PM, Dick Hardt <[email-masked]> wrote:
> 
> I think representing the request as an array is simplistic, and complicated at the same time.
> 
> On the simplistic front, as there is no clear mechanism for extending the request with properties that apply to all of the request. 

The elements of the array are taken as a set, to be tied to the same resulting access token. If one of those elements is defined, by the AS and/or the RS’s it’s protecting, to apply across some or all of the other elements, then that’s up to the AS’s policy. Much like the “openid” scope in OIDC, which switches on all sorts of contextual stuff in the request. So to handle something like this, an AS can easily declare that a given scope-style string or a given object property applies to different parts of the request. You don’t need to externalize it here.

Do you have a concrete use case that requires that feature to be done in the way that you describe? I am trying to separate the driving use case from the proposed solutions to see what the differences are. 

> 
> Using JSON type polymorphism requires the AS to test each member of the array to determine if it is a string or an object. Only after detecting a RAR object does the AS know the client is making a RAR request.

That’s correct — but the AS needs to parse the whole resources request in order to figure out what the client is asking for, anyway, whether it’s by strings or objects or whatever else might be defined by an extension. Is there an argument for having an AS do an early dispatch on a request before it’s fully parsed everything?

> This also limits the request to be composed only of scope strings or RAR objects. I don't see how other strings or objects could be used in the array, so there is no clear extension point in the "resources" array for other query mechanisms.

That’s not the case in XYZ since we aren’t declaring that a string has to be an OAuth2-style scope. It can be, but ultimately it’s just a string that the AS can understand. And the objects are just that — objects. If the AS understands what the object is, it can be a RAR object or it can be something completely API-specific with another query language entirely. (Point, though: RAR already pretty much allows this by letting them be extended infinitely, a feature it inherits from XYZ)

I’m proposing that we do the same thing with GNAP: it’s an array of strings or objects and each of those means the same thing, “something the client is asking for”.

> 
> Just as RAR has a "type" property, I propose the "resources" ("authorizations" in XAuth) be an object, where the other properties are determined by the "type" property. This allows extensions to define new ways to query for an authorization rather than having to fit into scopes or RAR.
> 

It’s my stance that this is an unnecessary limitation at this level. The objects within the array should be typed, like RAR, but it doesn’t make sense for the overall request to be typed. Instead, there should be one “type" of query in the core, what XYZ calls the “resources” request. Other query languages should be added as extensions either to the RAR-style objects (by defining a type at that level) or as a separate top-level member.

For example, let’s take the OIDC “claims” query language. My current thought is that this really shouldn’t be a part of the “resources” or “claims” part of the request, but instead as its own top-level member, like it is in the OIDC protocol today. The main reason for this is the nature of the OIDC claims language: it specifies targets for the resulting data, and those targets cross different ways to return things. So it doesn’t actually affect just resources like the UserInfo Endpoint, or the ID Token, but both and potentially others out there. If your system supported such an extension, it could theoretically forego both the built-in “claims” and “resources” parts of the request, and use the “oidc_claims_query” member (or whatever it would be called). This would let such an extension use the OIDC claims processing mechanism as it is today.

To me, this remains much more understandable, extensible, and clean.

 — Justin

> /Dick
> 
> 
> 
> On Wed, Jul 8, 2020 at 10:46 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>          "https://example.com/payments <https://example.com/payments>"
>       ],
>       "instructedAmount": {
>          "currency": "EUR",
>          "amount": "123.50"
>       },

---

From: Dick Hardt <[email-masked]>
Date: Wed, 8 Jul 2020 15:10:33 -0700

On Wed, Jul 8, 2020 at 1:02 PM Justin Richer <[email-masked]> wrote:

> The elements of the array are taken as a set, to be tied to the same
> resulting access token. If one of those elements is defined, by the AS
> and/or the RS’s it’s protecting, to apply across some or all of the other
> elements, then that’s up to the AS’s policy. Much like the “openid” scope
> in OIDC, which switches on all sorts of contextual stuff in the request. So
> to handle something like this, an AS can easily declare that a given
> scope-style string or a given object property applies to different parts of
> the request. You don’t need to externalize it here.
>

I view the "openid" scope as an unfortunate design as OIDC was constrained
by building on top of OAuth. (a problem I hoped to avert by having
"identity" in scope for GNAP) The "openid" scope does not function as
scope per se, and I think it makes OIDC harder to understand as the
"openid" scope causes non-scope behavior.

>
> Do you have a concrete use case that requires that feature to be done in
> the way that you describe? I am trying to separate the driving use case
> from the proposed solutions to see what the differences are.
>

Perhaps the client wants access to be HIPPA compliant? The HIPPA compliance
signal applies to the scopes.

Adding other properties to an object is a well understood extension
mechanism. Adding an additional element to an array that does not act like
the other elements seems like a hack.

> RAR object does the AS know the client is making a RAR request.
>
>
> That’s correct — but the AS needs to parse the whole resources request in
> order to figure out what the client is asking for, anyway, whether it’s by
> strings or objects or whatever else might be defined by an extension. Is
> there an argument for having an AS do an early dispatch on a request before
> it’s fully parsed everything?
>

Let me clarify, the code is looking at the type of object that has been
parsed.

Determining if an item in an array is a scope or a RAR object by looking at
the type being either a string or an object seems less clear than a
property of an object explicitly declaring the type.

>
> This also limits the request to be composed only of scope strings or RAR
> objects. I don't see how other strings or objects could be used in the
> array, so there is no clear extension point in the "resources" array for
> other query mechanisms.
>
>
> That’s not the case in XYZ since we aren’t declaring that a string has to
> be an OAuth2-style scope. It can be, but ultimately it’s just a string that
> the AS can understand. And the objects are just that — objects. If the AS
> understands what the object is, it can be a RAR object or it can be
> something completely API-specific with another query language entirely.
>

But the other query language would need a type that has been reserved in
the RAR name space for there to be interop, so it effectively is a RAR
extension.

There are query languages in other domains that may not fit nicely into RAR
such as a query for medical records.

Yes, the medical records could be yet another top level property, but per
below, I think that is confusing.

> (Point, though: RAR already pretty much allows this by letting them be
> extended infinitely, a feature it inherits from XYZ)
>
> I’m proposing that we do the same thing with GNAP: it’s an array of
> strings or objects and each of those means the same thing, “something the
> client is asking for”.
>
>
> It’s my stance that this is an unnecessary limitation at this level. The
> objects within the array should be typed, like RAR, but it doesn’t make
> sense for the overall request to be typed. Instead, there should be one
> “type" of query in the core, what XYZ calls the “resources” request. Other
> query languages should be added as extensions either to the RAR-style
> objects (by defining a type at that level) or as a separate top-level
> member.
>
> For example, let’s take the OIDC “claims” query language. My current
> thought is that this really shouldn’t be a part of the “resources” or
> “claims” part of the request, but instead as its own top-level member, like
> it is in the OIDC protocol today. The main reason for this is the nature of
> the OIDC claims language: it specifies targets for the resulting data, and
> those targets cross different ways to return things. So it doesn’t actually
> affect just resources like the UserInfo Endpoint, or the ID Token, but both
> and potentially others out there. If your system supported such an
> extension, it could theoretically forego both the built-in “claims” and
> “resources” parts of the request, and use the “oidc_claims_query” member
> (or whatever it would be called). This would let such an extension use the
> OIDC claims processing mechanism as it is today.
>

While this may be more understandable to a developer just porting an app
OIDC that only wants OIDC results, but I think it is more complicated as
soon as the developer wants other results, which is likely what prompted
the developer to use GNAP instead of ODIC.

I think it is easier to understand if all the claims are in one container,
and all the authorizations are in another container.

If a developer wants access to some resources, some claims, and an OpenID
Token, they are having to use "claims", "resources", and
"oidc_claims_query".  Now the claims and access tokens are spread across
multiple containers. There are some claims in the "claims" container, and
some "claims" in the "oidc_claims_query" container. And is the access token
response in "oidc_claims_query" the same as an access token response in
"resources"? It would seem simpler if they were, and if all the access
tokens came back in the same container.

Per Aaron's post that you have referred to, the developer can get sme bare
claims directly in the response in the "claims" object, an ID Token that
has the same or different claims, and if they want, an access token that
they can call a user_info endpoint to get the same, or different claims.

For example, an enterprise app client may want an ID Token with the email
address, bare claims for the user's name and a URI to a profile photo, and
an access token to query which groups a user belongs to.

We are still re-using the OIDC claims, but we are not mixing claims and
authorizations.

/Dick

[1] https://aaronparecki.com/2019/07/18/17/adding-identity-to-xyz
ᐧ

---

From: Justin Richer <[email-masked]>
Date: Wed, 8 Jul 2020 18:25:37 -0400

I’m glad that we can agree that there are a number of things in legacy protocols that are unfortunate side effects of the circumstances in which they were built. Space-separated scope strings, for instance, would fall in that category, as I’ve previously explained.

A key point in the below: the OIDC “claims” request already mixes user claims (returned in an API) and authorization (to fetch user claims from an API), so that ship has sailed if you’re using it. It doesn’t make sense to have it under a “claims” or “authorizations” request, since it’s a query language that affects both. Maybe you’d call this another “unfortunate design”, but the context was about re-using an externally-defined query language that was not made for GNAP.

My scenario was for someone who is already using “claims” and wants to keep using it. (The vast majority of OIDC implementations, in my experience, don’t use that feature, and it’s not even required to be implemented by the AS, but again we’re talking about using this feature as an example of an external query language — and there are others out there.) In GNAP, you should return claims directly in the response, and request specific elements from the APIs protected by the access token. These are separate things, and by design both XAuth and XYZ have put them into separate containers in the request. This is a good design, and so putting something that conflates these two aspects into one or the other of the containers is not a particularly good option, in my opinion. 

Additionally, though this is a bit of an aside and getting into the specifics of identity, the “claims” parameter of ODIC is a query language bound to the full user profile. It is my stated position that the items coming back from the AS should only be identifiers, and not full profile information. The reasoning is pretty simple: the client doesn’t know what profile information it needs until it knows who the user is, so putting that into a protected API like the UserInfo Endpoint makes much more sense than putting it into the immediate response, where it is not needed, because the client already knows it. The AS doesn’t know what the client needs to know, either, so it can’t determine what to fulfill. OIDC’s two-stage model makes sense, and GNAP should really only focus on enabling this.

 — Justin

> On Jul 8, 2020, at 6:10 PM, Dick Hardt <[email-masked]> wrote:
> 
> 
> 
> On Wed, Jul 8, 2020 at 1:02 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> On Jul 8, 2020, at 3:16 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
> I view the "openid" scope as an unfortunate design as OIDC was constrained by building on top of OAuth. (a problem I hoped to avert by having "identity" in scope for GNAP) The "openid" scope does not function as scope per se, and I think it makes OIDC harder to understand as the "openid" scope causes non-scope behavior. 
> 
>  
> 
> Perhaps the client wants access to be HIPPA compliant? The HIPPA compliance signal applies to the scopes.
> 
> Adding other properties to an object is a well understood extension mechanism. Adding an additional element to an array that does not act like the other elements seems like a hack.
> 
>  
> 
>> 
> Let me clarify, the code is looking at the type of object that has been parsed. 
> 
> Determining if an item in an array is a scope or a RAR object by looking at the type being either a string or an object seems less clear than a property of an object explicitly declaring the type.
> 
>  
> 
> That’s not the case in XYZ since we aren’t declaring that a string has to be an OAuth2-style scope. It can be, but ultimately it’s just a string that the AS can understand. And the objects are just that — objects. If the AS understands what the object is, it can be a RAR object or it can be something completely API-specific with another query language entirely.
> 
> But the other query language would need a type that has been reserved in the RAR name space for there to be interop, so it effectively is a RAR extension.
> 
> There are query languages in other domains that may not fit nicely into RAR such as a query for medical records.
> 
> Yes, the medical records could be yet another top level property, but per below, I think that is confusing.
>  
> (Point, though: RAR already pretty much allows this by letting them be extended infinitely, a feature it inherits from XYZ)
> 
> While this may be more understandable to a developer just porting an app OIDC that only wants OIDC results, but I think it is more complicated as soon as the developer wants other results, which is likely what prompted the developer to use GNAP instead of ODIC.
> 
> I think it is easier to understand if all the claims are in one container, and all the authorizations are in another container.
> 
> If a developer wants access to some resources, some claims, and an OpenID Token, they are having to use "claims", "resources", and "oidc_claims_query".  Now the claims and access tokens are spread across multiple containers. There are some claims in the "claims" container, and some "claims" in the "oidc_claims_query" container. And is the access token response in "oidc_claims_query" the same as an access token response in "resources"? It would seem simpler if they were, and if all the access tokens came back in the same container.
> 
> Per Aaron's post that you have referred to, the developer can get sme bare claims directly in the response in the "claims" object, an ID Token that has the same or different claims, and if they want, an access token that they can call a user_info endpoint to get the same, or different claims.
> 
> For example, an enterprise app client may want an ID Token with the email address, bare claims for the user's name and a URI to a profile photo, and an access token to query which groups a user belongs to.
> 
> We are still re-using the OIDC claims, but we are not mixing claims and authorizations.
> 
> /Dick
> 
> 
> [1] https://aaronparecki.com/2019/07/18/17/adding-identity-to-xyz <https://aaronparecki.com/2019/07/18/17/adding-identity-to-xyz>
> ᐧ

---

From: Dick Hardt <[email-masked]>
Date: Wed, 8 Jul 2020 15:55:01 -0700

Hey Justin,

Just because we are using OIDC claims, does not mean we need to mimic the
OIDC request and response.
I was envisioning a grant request could look as the following (using XAuth
syntax):

{
    "authorizations": {
        "type":"oidc",
        "claims": ["name", "picture"]
    },
    "claims":{
        "oidc": {
            "id_token" : {
                "email"          : { "essential" : true },
                "email_verified" : { "essential" : true }
            },
            "userinfo" : {
                "name"           : { "essential" : true },
                "picture"        : null
            }
        }
    }
}

Of course a developer could choose to only ask for a subset of this.

Note the new authorization type of "oidc", that takes "claims" rather than
"scope".

This keeps all the authorizations and claims in their respective request
and response containers.

We had a thread months ago on the OIDC two stage model, and I still fail to
see why forcing that has any advantage.

/Dick

On Wed, Jul 8, 2020 at 3:25 PM Justin Richer <[email-masked]> wrote:

> I’m glad that we can agree that there are a number of things in legacy
> protocols that are unfortunate side effects of the circumstances in which
> they were built. Space-separated scope strings, for instance, would fall in
> that category, as I’ve previously explained.
>
> A key point in the below: the OIDC “claims” request already mixes user
> claims (returned in an API) and authorization (to fetch user claims from an
> API), so that ship has sailed if you’re using it. It doesn’t make sense to
> have it under a “claims” or “authorizations” request, since it’s a query
> language that affects both. Maybe you’d call this another “unfortunate
> design”, but the context was about re-using an externally-defined query
> language that was not made for GNAP.
>
> My scenario was for someone who is already using “claims” and wants to
> keep using it. (The vast majority of OIDC implementations, in my
> experience, don’t use that feature, and it’s not even required to be
> implemented by the AS, but again we’re talking about using this feature as
> an example of an external query language — and there are others out there.)
> In GNAP, you should return claims directly in the response, and request
> specific elements from the APIs protected by the access token. These are
> separate things, and by design both XAuth and XYZ have put them into
> separate containers in the request. This is a good design, and so putting
> something that conflates these two aspects into one or the other of the
> containers is not a particularly good option, in my opinion.
>
> Additionally, though this is a bit of an aside and getting into the
> specifics of identity, the “claims” parameter of ODIC is a query language
> bound to the full user profile. It is my stated position that the items
> coming back from the AS should only be identifiers, and not full profile
> information. The reasoning is pretty simple: the client doesn’t know what
> profile information it needs until it knows who the user is, so putting
> that into a protected API like the UserInfo Endpoint makes much more sense
> than putting it into the immediate response, where it is not needed,
> because the client already knows it. The AS doesn’t know what the client
> needs to know, either, so it can’t determine what to fulfill. OIDC’s
> two-stage model makes sense, and GNAP should really only focus on enabling
> this.
>
>  — Justin
>
> Determining if an item in an array is a scope or a RAR object by looking
> at the type being either a string or an object seems less clear than a

---

From: Dick Hardt <[email-masked]>
Date: Wed, 8 Jul 2020 18:31:00 -0700

I had intended to provide a code sample comparing XYZ request type with
XAuth request type

Let's say an AS only supports OAuth scopes (does not support RAR). Here is
JS code to check:

//XYZ code

var oauth_scope = true;
requests.forEach( item => {
    if (typeof item === "object")
        oauth_scope = false;
});
if (!'oauth_scope') {
    // return error
}

// XAuth code

if ('oauth_scope' != authorizations.type) {
   // return error
}

Here is some JS code that for an AS that supports OAuth scopes, RAR, and
OIDC requests:

// XYZ

if (request) {
    requests.forEach( item => {
        if (typeof item === "object") {
            // process a RAR item
        } else if(typeof item === 'string') {
            // process a scope item
        } else {
            // throw an error
        }
    })
   // process the whole request
}
if (oidc_claims_query) {
    // process oidc request
}

//XAuth

if (authorizations) {
    switch (authorizations?.type) {
        case 'oauth_rar':
            // process authorizations.details - RAR
        case 'oauth_scope':
            // process authorizations.scope
            // process the whole request
            break;
        case 'oidc':
            // process OIDC claims
            break;
        default:
            // error for unknown type
    }
}

Understanding what the code is doing looks much clearer in XAuth to me.

ᐧ

On Wed, Jul 8, 2020 at 3:55 PM Dick Hardt <[email-masked]> wrote:

> We had a thread months ago on the OIDC two stage model, and I still fail
> to see why forcing that has any advantage.
>
> /Dick
>
>
>>> On the simplistic front, as there is no clear mechanism for extending
>>> the request with properties that apply to all of the request.
>>>
>>>
>> I view the "openid" scope as an unfortunate design as OIDC was
>> constrained by building on top of OAuth. (a problem I hoped to avert by
>> having "identity" in scope for GNAP) The "openid" scope does not function
>> as scope per se, and I think it makes OIDC harder to understand as the
>>> That’s correct — but the AS needs to parse the whole resources request
>>> in order to figure out what the client is asking for, anyway, whether it’s
>>> by strings or objects or whatever else might be defined by an extension. Is
>>> That’s not the case in XYZ since we aren’t declaring that a string has
>>> to be an OAuth2-style scope. It can be, but ultimately it’s just a string
>>> that the AS can understand. And the objects are just that — objects. If the
>>> AS understands what the object is, it can be a RAR object or it can be
>> I think it is easier to understand if all the claims are in one
>> container, and all the authorizations are in another container.
>>
>> Per Aaron's post that you have referred to, the developer can get sme
>> bare claims directly in the response in the "claims" object, an ID Token
>> that has the same or different claims, and if they want, an access token
>> that they can call a user_info endpoint to get the same, or different
>> claims.
>>

---

From: Justin Richer <[email-masked]>
Date: Thu, 9 Jul 2020 11:39:21 -0400

Declarations of which code is “easier to understand” are going to be subjective, and I don’t agree with your conclusions even with your examples. Even so, I don’t think that the examples you give are a good comparison. While it is of course possible to implement things like you have below, I think it’s indicative of thinking of things in terms of a “resource request type”. What I’ve been trying to argue is that there shouldn’t be a “type”, that there should just be slightly different ways to do a resource request. So the code is more like:

resourcesRequested = requests.map( item => {
   if (typeof item == ‘object’) {
      return new RarStyleResourceRequest(item);
   } else if (typeof item == “string”) {
     return new StringStyleResourceRequest(item);
   }
});
processResources(resourcesRequested);

Each of these “*ResourceRequest” objects would be something that the AS can use to decide what to put into the access token. Although you’d probably put that complexity into a factory constructor or something instead of a map function, this shows the kind of dispatch you can do based on type if you’re doing it by hand. You collect everything in the array, and turn it into an object that represents “a request for a resource that gets tied to an access token”. And then you process the request based on the collection of resource requests. Each string-based request points to some set of policies, as does each object-based request. You can even imagine that instead of creating a separate string-based request, you use that string to look up a policy in a policy engine to be applied later.

The AS then has to figure out, as it always does, what to do with this collection. And if you want to do an early escape on object style requests, you could just throw an error when you detect that. Or, you just ignore that part of the request. In fact, here’s the code I wrote that handles it exactly that way, while processing the JSON by hand in Java on a legacy OAuth 2 server:

JsonArray resources = json.get("resources").getAsJsonArray();      
Set<String> scopes = StreamSupport.stream(resources.spliterator(), false)
	.filter( e -> e.isJsonPrimitive() ) // filter out anything that's not a handle      
	.map( e -> e.getAsString() )      
	.collect(Collectors.toSet());      
tx.setScope(scopes);

Furthermore, your XAuth example doesn’t go to the same depth as the XYZ example, which leads to a false comparison. In your “process scope” you would need to parse the “scope” string to split on spaces, and then have another loop to process each scope. For the “process details” you’d need to iterate over the array at the root of a RAR-style request and process each piece. In the XYZ code, you’ve got all of that already. If you’re going to compare the complexity of code, they should at least be shown to the same point of the process. 

On top of that, the fall-through case statement below is really limiting. What if the scope processing or RAR objects processing gets combined with something else? This kind of premature optimization is not something we want to encourage developers to do. 

But ultimately, I think the disconnect is down to thinking about this in terms of an explicit “type”, much the way XAuth used to do with the interactions. I’m glad that your thoughts have shifted in that space, and I think you should strongly consider the same set of arguments here. A lot of the promise of GNAP is getting away from this type-field style design, like getting away from OAuth 2’s “grant_type” approach and into something that’s focused on interaction and client models instead. This newer model allows for better flexibility, better consistency, and better clarity throughout. It’s no longer “if I see this flag then I go down this separate code path and nothing else”, it’s now “if I see this item, I go down this code path and then process the next item too”. There’s power in the combinations.

 — Justin

> On Jul 8, 2020, at 9:31 PM, Dick Hardt <[email-masked]> wrote:
> 
> I had intended to provide a code sample comparing XYZ request type with XAuth request type
> 
> Let's say an AS only supports OAuth scopes (does not support RAR). Here is JS code to check:
> 
> //XYZ code
> var oauth_scope = true;
> Here is some JS code that for an AS that supports OAuth scopes, RAR, and OIDC requests:
> 
> // XYZ
> if (request) {
> On Wed, Jul 8, 2020 at 3:55 PM Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
> Hey Justin,
> 
> Just because we are using OIDC claims, does not mean we need to mimic the OIDC request and response.
> I was envisioning a grant request could look as the following (using XAuth syntax):
> 
> {
>     "authorizations": {
>         "type":"oidc",
> Note the new authorization type of "oidc", that takes "claims" rather than "scope". 
> 
> This keeps all the authorizations and claims in their respective request and response containers.
> 
> We had a thread months ago on the OIDC two stage model, and I still fail to see why forcing that has any advantage. 
> 
> /Dick
> 
> 
> On Wed, Jul 8, 2020 at 3:25 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jul 8, 2020, at 6:10 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> 
>>

---

From: Justin Richer <[email-masked]>
Date: Thu, 9 Jul 2020 11:39:22 -0400

But this approach doesn’t keep things in their respective containers — you’ve explicitly got “claims” underneath the “authorizations” header, and you’ve got items that come back as rights associated with the access token (which should be “authorizations”) in the “userinfo” section under the “claims” header. And as far as I can tell, these two sections are redundant to each other. Everything is everywhere. 

Additionally, this approach and syntax makes it difficult to combine different kinds of requests into one. One of OpenID Connect’s biggest draws, as I’m sure you recall, is that it could be combined with a request for non-OIDC resources. This was the real innovation that Twitter and Facebook’s identity APIs brought, access to more than just authentication, and what Google had tried to replicate with the awkward OpenID 2 + OAuth 1 hybrid system. Taking a step back from the existing solutions of OpenID 2 and OAuth 1 let us, as the community, see the value in the pattern that became OIDC on top of OAuth 2. 

Sure, you could say that the “oidc” type also can allow a “scopes” parameter, but what about a RAR style object, then? And what about when someone comes up with some new way to request access rights, or a VC-based query language? Does every “type” need to now know about every other “type” in order for an AS to be able to figure out how they go together? This seems like the protocol definition limiting what combinations the AS can handle, or what an RS might want to use.

My stance is that GNAP should have a way to query for rights in the access token (“authorizations” in xauth parlance) and identifiers for the user (“claims” in xauth parlance), and anything else should be an extension with potentially different models. The AS would process the “authorizations” equivalent (for the access token) alongside any other incoming query and then make a policy decision based on that.

I find it interesting that you are now saying we don’t need to use the OIDC request format when previously you’ve made it clear that you were in favor of pointing at external query languages, including their syntax. I’m glad to see that you’re now looking at things in a more flexible way, but I think it’s important that we be careful and conscientious about how we reference any external query languages in GNAP.

 — Justin

> On Jul 8, 2020, at 6:55 PM, Dick Hardt <[email-masked]> wrote:
> 
> Hey Justin,
>

---

From: Dick Hardt <[email-masked]>
Date: Thu, 9 Jul 2020 11:32:47 -0700

Looks like you missed the point of my code example, as your response is
focussed on the aspects I had in comments, so let me clarify.

This line (which is determining the type of the item in the array):

if (typeof item === string')

is implicitly stating that the item is an oauth scope. Whereas it is
explicit in this statement

if (authorizations.type === 'oauth_scope')

which I think it easier to understand what is happening (in my opinion of
course).

XYZ has types, they are just implicit. RAR has explicit types, and that
does not look to be holding back RAR. I don't understand why you think
having explicit types will hold us back. Do you want to let the string and
object be anything the AS and RS decide they could mean? That would make
GNAP more of a framework than a protocol, and a key aspect of the request
would be undefined.

My thoughts have not shifted on "types" in interactions. I just changed the
name to 'mode'. I did shift my thinking that a negotiation of interaction
modes is useful, and added that.

We still have an unfinished discussion there. When you have a chance, would
you respond to that thread?

/Dick

On Thu, Jul 9, 2020 at 8:39 AM Justin Richer <[email-masked]> wrote:

> Declarations of which code is “easier to understand” are going to be
> subjective, and I don’t agree with your conclusions even with your
> examples. Even so, I don’t think that the examples you give are a good
> comparison. While it is of course possible to implement things like you
> have below, I think it’s indicative of thinking of things in terms of a
> “resource request type”. What I’ve been trying to argue is that there
> shouldn’t be a “type”, that there should just be slightly different ways to
> do a resource request. So the code is more like:
>
> Each of these “*ResourceRequest” objects would be something that the AS
> can use to decide what to put into the access token. Although you’d
> probably put that complexity into a factory constructor or something
> instead of a map function, this shows the kind of dispatch you can do based
> on type if you’re doing it by hand. You collect everything in the array,
> and turn it into an object that represents “a request for a resource that
> gets tied to an access token”. And then you process the request based on
> the collection of resource requests. Each string-based request points to
> some set of policies, as does each object-based request. You can even
> imagine that instead of creating a separate string-based request, you use
> that string to look up a policy in a policy engine to be applied later.
>
> The AS then has to figure out, as it always does, what to do with this
> collection. And if you want to do an early escape on object style requests,
> you could just throw an error when you detect that. Or, you just ignore
> that part of the request. In fact, here’s the code I wrote that handles it
> exactly that way, while processing the JSON by hand in Java on a legacy
> OAuth 2 server:
>
>
> Furthermore, your XAuth example doesn’t go to the same depth as the XYZ
> example, which leads to a false comparison. In your “process scope” you
> would need to parse the “scope” string to split on spaces, and then have
> another loop to process each scope. For the “process details” you’d need to
> iterate over the array at the root of a RAR-style request and process each
> piece. In the XYZ code, you’ve got all of that already. If you’re going to
> compare the complexity of code, they should at least be shown to the same
> point of the process.
>
> On top of that, the fall-through case statement below is really limiting.
> What if the scope processing or RAR objects processing gets combined with
> something else? This kind of premature optimization is not something we
> want to encourage developers to do.
>
> But ultimately, I think the disconnect is down to thinking about this in
> terms of an explicit “type”, much the way XAuth used to do with the
> interactions. I’m glad that your thoughts have shifted in that space, and I
> think you should strongly consider the same set of arguments here. A lot of
> the promise of GNAP is getting away from this type-field style design, like
> getting away from OAuth 2’s “grant_type” approach and into something that’s
> focused on interaction and client models instead. This newer model allows
> for better flexibility, better consistency, and better clarity throughout.
> It’s no longer “if I see this flag then I go down this separate code path
> and nothing else”, it’s now “if I see this item, I go down this code path
> and then process the next item too”. There’s power in the combinations.
>
>  — Justin
>
>>>> Do you have a concrete use case that requires that feature to be done
>>>> in the way that you describe? I am trying to separate the driving use case
>>>> This also limits the request to be composed only of scope strings or
>>>> RAR objects. I don't see how other strings or objects could be used in the
>>>> It’s my stance that this is an unnecessary limitation at this level.
>>>> The objects within the array should be typed, like RAR, but it doesn’t make
>>> If a developer wants access to some resources, some claims, and an
>>> OpenID Token, they are having to use "claims", "resources", and
>>> For example, an enterprise app client may want an ID Token with the
>>> email address, bare claims for the user's name and a URI to a profile
>>> photo, and an access token to query which groups a user belongs to.
>>>

---

From: Dick Hardt <[email-masked]>
Date: Thu, 9 Jul 2020 12:15:21 -0700

You are jumping to many conclusions below. Let me break down the proposal
into some bite size chunks.

The developer would like to get some plain text OIDC claims about the user:

    "claims":{
        "oidc": {
            "userinfo" : {
                "name" : { "essential" : true },
                "photo" : { "essential" : false }
            },

The developer would like to get an OIDC ID Token:

    "claims":{
        "oidc": {
            "id_token" : {

The developer would like to get an access token to acquire OIDC claims:

"authorizations": {
        "type":"oidc",

The developer would like to get an access token to access photos:

"authorizations": {
        "type":"oauth_scope",
        "scope": "read_photos"*
    }

The developer would like to get some VC claims:

"claims" {
        "vc": {
            "some_vc": "query_mechanism"
        }
}

The developer would like to do all of the above at once:

{
    "authorizations": {
        "userinfo": {
            "type":"oidc",
            "claims": ["name", "picture"]
        },
        "photos": {
            "type":"oauth_scope",
            "scope": "read_photos"
        }
    },
    "claims":{
        "oidc": {
            "id_token" : {
                "email"          : { "essential" : true },
                "email_verified" : { "essential" : true }
            },
            "userinfo" : {
                "name" : { "essential" : true },
                "photo" : { "essential" : false }
            }
        },
    "vc": {
        "some_vc": "query_mechanism"
        }
    }
}

In the results, the developer gets claims back in the response claims
object, and access tokens etc. back in the authorizations object. Just
because an access token returns claims, it is still an access token.

Yes, the developer can't get a single access token that can both acquire
OIDC claims, and access photos (there are separate tokens for each), but I
would argue that separating the access is a positive security property, as
a client component accessing the user profile has a token independent of
the client component accessing photos. And at the AS, there is no
requirement for the userinfo endpoint to take the same token as the photo
endpoint.

Somewhat of a tangent, I'm thinking that

    "claims":{
        "oidc": {
            "id_token" : {},
            "userinfo" : {}
        },

is a little verbose, and:

    "claims":{
        "oidc_token": {},
        "oidc_info": {}
    },

works better and makes it easier to distinguish support for ID tokens vs
plain claims.

wrt. my position on reusing OIDC -- it has not changed. I have viewed the
OIDC claims as the "query language". No need to reinvent that. We are
creating a new protocol, so no need to use the OAuth or OIDC protocols.

* OAuth scopes could be a space separates string to be consistent with
OAuth 2, or an array of strings so that it is more JSON like. I have no
strong opinion.

scope.split(' ').forEach()

is not that much more complex than

scope.forEach()

On Thu, Jul 9, 2020 at 8:39 AM Justin Richer <[email-masked]> wrote:

> But this approach doesn’t keep things in their respective containers —
> you’ve explicitly got “claims” underneath the “authorizations” header, and
> you’ve got items that come back as rights associated with the access token
> (which should be “authorizations”) in the “userinfo” section under the
> “claims” header. And as far as I can tell, these two sections are redundant
> to each other. Everything is everywhere.
>
> Additionally, this approach and syntax makes it difficult to combine
> different kinds of requests into one. One of OpenID Connect’s biggest
> draws, as I’m sure you recall, is that it could be combined with a request
> for non-OIDC resources. This was the real innovation that Twitter and
> Facebook’s identity APIs brought, access to more than just authentication,
> and what Google had tried to replicate with the awkward OpenID 2 + OAuth 1
> hybrid system. Taking a step back from the existing solutions of OpenID 2
> and OAuth 1 let us, as the community, see the value in the pattern that
> became OIDC on top of OAuth 2.
>
> Sure, you could say that the “oidc” type also can allow a “scopes”
> parameter, but what about a RAR style object, then? And what about when
> someone comes up with some new way to request access rights, or a VC-based
> query language? Does every “type” need to now know about every other “type”
> in order for an AS to be able to figure out how they go together? This
> seems like the protocol definition limiting what combinations the AS can
> handle, or what an RS might want to use.
>
> My stance is that GNAP should have a way to query for rights in the access
> token (“authorizations” in xauth parlance) and identifiers for the user
> (“claims” in xauth parlance), and anything else should be an extension with
> potentially different models. The AS would process the “authorizations”
> equivalent (for the access token) alongside any other incoming query and
> then make a policy decision based on that.
>
> I find it interesting that you are now saying we don’t need to use the
> OIDC request format when previously you’ve made it clear that you were in
> favor of pointing at external query languages, including their syntax. I’m
> glad to see that you’re now looking at things in a more flexible way, but I
> think it’s important that we be careful and conscientious about how we
> reference any external query languages in GNAP.
>
>  — Justin
>

---

From: Justin Richer <[email-masked]>
Date: Thu, 9 Jul 2020 15:17:44 -0400

On Jul 9, 2020, at 2:32 PM, Dick Hardt <[email-masked]> wrote:
> 
> Looks like you missed the point of my code example, as your response is focussed on the aspects I had in comments, so let me clarify. 

The point seemed to be about the overall complexity and readability, and that’s what I responded to.

> is implicitly stating that the item is an oauth scope.

No, it is not. It is saying that it is a resource request represented as a string. One way to represent a resource request as a string is an OAuth 2 style scope. And if you’re building up from an existing OAuth 2 system, then you could use a scope there. But that’s not the same as stating “the item is a scope”. In my examples, I had been trying to use the terminology that you were using, but I’m afraid that made things more unclear.

> Whereas it is explicit in this statement
> 
> which I think it easier to understand what is happening (in my opinion of course).
> 
> XYZ has types, they are just implicit. RAR has explicit types, and that does not look to be holding back RAR. I don't understand why you think having explicit types will hold us back.

The “type” in RAR is a name spacing device to allow extensibility in different aspects of the request. This is at a lower layer than how they’re being applied here, and it therefore makes more sense at that layer. It’s a way for a particular API to define the dimensions that it cares about in its request. It’s not really an even comparison.

> Do you want to let the string and object be anything the AS and RS decide they could mean?

Yes. Just like the AS can decide that an OAuth scope could mean any number of things.

> That would make GNAP more of a framework than a protocol, and a key aspect of the request would be undefined.

I don’t see how this would make things a framework and not a protocol. We’re not debating the ability to send a set of strings or a set of objects to the AS, which the AS will interpret in the request. We’re debating the syntax for sending those values.

> 
> My thoughts have not shifted on "types" in interactions. I just changed the name to 'mode'. I did shift my thinking that a negotiation of interaction modes is useful, and added that.

The important shift is the removal of a single “type” field that meant you could only send one thing at a time, and now you can send multiple things in various combinations as need allows. That’s the kind of thing that I’m saying is problematic here as well, for many of the same reasons.

> 
> We still have an unfinished discussion there. When you have a chance, would you respond to that thread?

I believe the thread you’re referring to was commented on by several people, including an AD, as not being a helpful conversation for the group. I stopped responding to that thread when that was brought up, in order to respect that position and hopefully move the conversation along. I’m beginning to think that this conversation thread is itself going off the rails in a similar way, since we seem to be repeating things at each other. It’s become a comparison of solutions in detail and not a discussion of what the driving use cases are. I understand that you think your proposal is better, and I disagree and have pointed out what I see as several major flaws in it.

My goal here isn’t to convince you as an individual that I’m right. My goal here is to present my ideas and explain the thought process behind them so that we all, as a group, can make the best decisions going forward based on that. 

 — Justin

> 
> /Dick
> 
> On Thu, Jul 9, 2020 at 8:39 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jul 8, 2020, at 9:31 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>>

---

From: Justin Richer <[email-masked]>
Date: Thu, 9 Jul 2020 15:21:21 -0400

Ah, so you’re saying that the “userinfo” claims would be returned directly? I didn’t realize that you had intended to change how the OIDC claims query language functioned in your examples, and had assumed it would work the same was as the spec you were referencing. Your example of splitting it up makes that more clear. Though I would argue at that point, you’re creating a new query language since you’re not using the top-level functionality from ODIC’s definition.

 — Justin

> On Jul 9, 2020, at 3:15 PM, Dick Hardt <[email-masked]> wrote:
> 
> You are jumping to many conclusions below. Let me break down the proposal into some bite size chunks.
> 
> In the results, the developer gets claims back in the response claims object, and access tokens etc. back in the authorizations object. Just because an access token returns claims, it is still an access token.
> 
> Yes, the developer can't get a single access token that can both acquire OIDC claims, and access photos (there are separate tokens for each), but I would argue that separating the access is a positive security property, as a client component accessing the user profile has a token independent of the client component accessing photos. And at the AS, there is no requirement for the userinfo endpoint to take the same token as the photo endpoint.
> 
> works better and makes it easier to distinguish support for ID tokens vs plain claims.
> 
> wrt. my position on reusing OIDC -- it has not changed. I have viewed the OIDC claims as the "query language". No need to reinvent that. We are creating a new protocol, so no need to use the OAuth or OIDC protocols.
> 
> * OAuth scopes could be a space separates string to be consistent with OAuth 2, or an array of strings so that it is more JSON like. I have no strong opinion. 
> 
>> On Jul 8, 2020, at 6:55 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> Hey Justin,
>>

---

From: Dick Hardt <[email-masked]>
Date: Thu, 9 Jul 2020 12:29:38 -0700

Yes. Which is why I referred to Aaron's post originally which calls out for
returning plain text claims.

I don't really understand what you mean by "OIDC claims query language".
The claims mean the same thing. And I was also reusing the modifiers such
as {"essential": true}. What top level functionality are you referring to?

On Thu, Jul 9, 2020 at 12:21 PM Justin Richer <[email-masked]> wrote:

> Ah, so you’re saying that the “userinfo” claims would be returned
> directly? I didn’t realize that you had intended to change how the OIDC
> claims query language functioned in your examples, and had assumed it would
> work the same was as the spec you were referencing. Your example of
> splitting it up makes that more clear. Though I would argue at that point,
> you’re creating a new query language since you’re not using the top-level
> functionality from ODIC’s definition.
>
>  — Justin
>
>> My stance is that GNAP should have a way to query for rights in the
>> access token (“authorizations” in xauth parlance) and identifiers for the
>> user (“claims” in xauth parlance), and anything else should be an extension
>> with potentially different models. The AS would process the
>> “authorizations” equivalent (for the access token) alongside any other
>> incoming query and then make a policy decision based on that.
>>

---

From: Justin Richer <[email-masked]>
Date: Thu, 9 Jul 2020 16:04:08 -0400

In Aaron’s post he doesn’t talk about how the request would be made, just what the response could look like, and we are talking about how to request that. Aaron’s post specifically calls out that this is just an identifier for the user and states:

If the application needs to know profile information about the user, it can get that from the userinfo endpoint using the access token it just obtained.

And I think that’s a good design pattern to follow. This isn’t “userinfo” being returned alongside the access token. 

The top level functionality of the OIDC claims query language is this:

The top-level members of the Claims request JSON object are:

userinfo
OPTIONAL. Requests that the listed individual Claims be returned from the UserInfo Endpoint. If present, the listed Claims are being requested to be added to any Claims that are being requested using scope values. If not present, the Claims being requested from the UserInfo Endpoint are only those requested using scope values.
When the userinfo member is used, the request MUST also use a response_type value that results in an Access Token being issued to the Client for use at the UserInfo Endpoint.

id_token
OPTIONAL. Requests that the listed individual Claims be returned in the ID Token. If present, the listed Claims are being requested to be added to the default Claims in the ID Token. If not present, the default ID Token Claims are requested, as per the ID Token definition in Section 2 and per the additional per-flow ID Token requirements in Sections 3.1.3.6, 3.2.2.10, 3.3.2.11, and 3.3.3.6.

Since you had re-used the “userinfo” and “id_token” top-level claims, I had assumed that they meant the same thing as in the OIDC spec. It’s clear to me, now, that this isn’t what you meant, but this is why I’m saying you’re not using the whole query language. 

There are proposed extensions to the OIDC claims query that would put returned data into a different place[1], and so it would be possible to use the claims structures to handle this. But at that point if the goal is just to use the internal query format, then I think that we can do better using … polymorphic JSON. :)

My stance is that we allow the client to ask for a small set of identifiers about the user, or even just ask to “identify the user”, and leave everything else to a higher level identity protocol. I do not think that having an identity and profile query/response language at the core of GNAP is a good idea, and it’s certainly not in our charter.

 — Justin

[1] https://mattrglobal.github.io/oidc-client-bound-assertions-spec/ <https://mattrglobal.github.io/oidc-client-bound-assertions-spec/> defines a “credential’ target.

> On Jul 9, 2020, at 3:29 PM, Dick Hardt <[email-masked]> wrote:
> 
> Yes. Which is why I referred to Aaron's post originally which calls out for returning plain text claims.
> 
> I don't really understand what you mean by "OIDC claims query language". The claims mean the same thing. And I was also reusing the modifiers such as {"essential": true}. What top level functionality are you referring to?
> 
> On Thu, Jul 9, 2020 at 12:21 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jul 9, 2020, at 3:15 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>>

---

From: Dick Hardt <[email-masked]>
Date: Thu, 9 Jul 2020 14:55:46 -0700

Thanks for the clarifications. I had chatted to Aaron about his post, and
my understanding is not what is in the post on a closer read. My takeaway
was why make the developer parse the ID_Token, why not give them the
information directly.

I have interpreted the userinfo and id_token top level elements to be how
the client wanted the query results, not part of the query. I had thought
my example and definition of a Grant Response in XAuth [1] would have
clearly communicated what I meant, but I see that I should call out that
userinfo in XAuth returns the claims, rather than userinfo in OIDC returns
an access token for the claims. Given GNAP is more expressive, and learning
from the past, I'm proposing we offer the developer (and AS) a choice in
how to acquire the claims.

While acquiring user information through an API at any time is appropriate
in some use cases, in others why not give the client the info it needs
right away rather than having to make another API call to get it? This
would be appropriate when the user is making a purchase and wanting to
provide shipping information. The user does not want to authorize the
client to fetch their shipping address in the future.

I'm surprised by your stance:

My stance is that we allow the client to ask for a small set of identifiers
about the user, or even just ask to “identify the user”, and leave
everything else to a higher level identity protocol. I do not think that
having an identity and profile query/response language at the core of GNAP
is a good idea, and it’s certainly not in our charter.

Since the charter states:

The group is chartered to develop mechanisms for conveying identity
information
within the protocol including existing identifiers (such as email addresses,
phone numbers, usernames, and subject identifiers) and assertions (such as
OpenID Connect ID Tokens, SAML Assertions, and Verifiable Credentials). The
group is not chartered to develop new formats for identifiers or assertions,
nor is the group chartered to develop schemas for user information,
profiles,
or other identity attributes.

More than identifiers about the user are clearly in scope of the WG
charter, as are mechanisms for conveying identity information. Your stance
and the charter look in conflict to me. What am I missing?

/Dick

[1] https://tools.ietf.org/html/draft-hardt-xauth-protocol-11#section-4.1

On Thu, Jul 9, 2020 at 1:04 PM Justin Richer <[email-masked]> wrote:

> In Aaron’s post he doesn’t talk about how the request would be made, just
> what the response could look like, and we are talking about how to request
> that. Aaron’s post specifically calls out that this is just an identifier
> for the user and states:
>
> If the application needs to know profile information about the user,
> it can get that from the userinfo endpoint using the access token it
> just obtained.
>
>
> And I think that’s a good design pattern to follow. This isn’t “userinfo”
> being returned alongside the access token.
>
> OPTIONAL. Requests that the listed individual Claims *be returned from
> the UserInfo Endpoint*. If present, the listed Claims are being requested
> to be added to any Claims that are being requested using scope values. If
> not present, the Claims being requested from the UserInfo Endpoint are
> only those requested using scope values.
> When the userinfo member is used, the request MUST also use
> a response_type value that results in an *Access Token being issued to
> the Client for use at the UserInfo Endpoint*.
>
> id_token
> OPTIONAL. Requests that the listed individual Claims be returned in the
> ID Token. If present, the listed Claims are being requested to be added
> to the default Claims in the ID Token. If not present, the default ID Token
> Claims are requested, as per the ID Token definition in Section 2 and per
> the additional per-flow ID Token requirements in
> Sections 3.1.3.6, 3.2.2.10, 3.3.2.11, and 3.3.3.6.
>
>
> Since you had re-used the “userinfo” and “id_token” top-level claims, I
> had assumed that they meant the same thing as in the OIDC spec. It’s clear
> to me, now, that this isn’t what you meant, but this is why I’m saying
> you’re not using the whole query language.
>
> There are proposed extensions to the OIDC claims query that would put
> returned data into a different place[1], and so it would be possible to use
> the claims structures to handle this. But at that point if the goal is just
> to use the internal query format, then I think that we can do better using
> … polymorphic JSON. :)
>
> My stance is that we allow the client to ask for a small set of
> identifiers about the user, or even just ask to “identify the user”, and
> leave everything else to a higher level identity protocol. I do not think
> that having an identity and profile query/response language at the core of
> GNAP is a good idea, and it’s certainly not in our charter.
>
>  — Justin
>
> [1] https://mattrglobal.github.io/oidc-client-bound-assertions-spec/ defines
> a “credential’ target.
>
>>>>> Using JSON type polymorphism requires the AS to test each member of
>>>>> the array to determine if it is a string or an object. Only after detecting
>>>>> a RAR object does the AS know the client is making a RAR request.
>>>>>
>>>>>
>>>> Determining if an item in an array is a scope or a RAR object by
>>>> looking at the type being either a string or an object seems less clear
>>>> than a property of an object explicitly declaring the type.
>>>>
>>>>
>>>>
>>>>>
>>>> But the other query language would need a type that has been reserved
>>>> in the RAR name space for there to be interop, so it effectively is a RAR
>>>> extension.
>>>>
>>>> While this may be more understandable to a developer just porting an
>>>> app OIDC that only wants OIDC results, but I think it is more complicated
>>>> as soon as the developer wants other results, which is likely what prompted

---

From: Dick Hardt <[email-masked]>
Date: Thu, 9 Jul 2020 15:50:29 -0700

> that’s what I responded to.

It was about the complexity and readability -- of those specific lines of
code.

I've used JS type polymorphism to provide a cleaner API. For example,
making an HTTP request. If I'm good with all the defaults, I can just
provide the URI as a string, if I want to change a default, I provide an
object and the URI is now a property of the object. Polymorphism allows the
caller to have a simpler interface when it is a simple operation.

Do you have any examples of JSON polymorphism used in other protocols
besides in a JWT?

> No, it is not. It is saying that it is a resource request represented as a
> string. One way to represent a resource request as a string is an OAuth 2
> style scope. And if you’re building up from an existing OAuth 2 system,
> then you could use a scope there. But that’s not the same as stating “the
> item is a scope”. In my examples, I had been trying to use the terminology
> that you were using, but I’m afraid that made things more unclear.
>

We are comparing how to do it in XYZ vs XAuth -- so to make it apples and
apples, the string is a scope, since that is the use case we are looking at.

> having explicit types will hold us back.
>
>
> The “type” in RAR is a name spacing device to allow extensibility in
> different aspects of the request. This is at a lower layer than how they’re
> being applied here, and it therefore makes more sense at that layer. It’s a
> way for a particular API to define the dimensions that it cares about in
> its request. It’s not really an even comparison.
>

And the type in XAuth authorizations is different schemas for making a
request. "oauth_scope", "oauth_rar", and now "oidc". I would expect that
there may be more in the future, and we have a clear way of adding schemas,
and for the client and AS to know they are talking the same "language".

> Yes. Just like the AS can decide that an OAuth scope could mean any number

That was what I was afraid of. While an OAuth scope could mean whatever the
AS decides it wants to be, the Client and AS know it is an OAuth scope.

> I don’t see how this would make things a framework and not a protocol.
> We’re not debating the ability to send a set of strings or a set of objects
> to the AS, which the AS will interpret in the request. We’re debating the
> syntax for sending those values.
>

>
>
> My thoughts have not shifted on "types" in interactions. I just changed
> the name to 'mode'. I did shift my thinking that a negotiation of
> interaction modes is useful, and added that.
>
>
> The important shift is the removal of a single “type” field that meant you
> could only send one thing at a time, and now you can send multiple things
> in various combinations as need allows. That’s the kind of thing that I’m
> saying is problematic here as well, for many of the same reasons.
>
>
> I believe the thread you’re referring to was commented on by several
> people, including an AD, as not being a helpful conversation for the group.
> I stopped responding to that thread when that was brought up, in order to
> respect that position and hopefully move the conversation along.
>

This is the thread I am referring to:

https://mailarchive.ietf.org/arch/msg/txauth/ECfShOtiN1WA1QiI77CBId4_VXg/

And I don't think Ben was saying the conversation was not helpful, but
wanted to clarify the goal:

https://mailarchive.ietf.org/arch/msg/txauth/qOF5Wl3uYQ9rdzEz7ORftYAAHc4/

> I’m beginning to think that this conversation thread is itself going off
> the rails in a similar way, since we seem to be repeating things at each
> other.
>

Seems later messages in this thread indicate otherwise as there seems to be
some additional understanding.

> It’s become a comparison of solutions in detail and not a discussion of
> what the driving use cases are. I understand that you think your proposal
> is better, and I disagree and have pointed out what I see as several major
> flaws in it.
>

Would you list those for me so I have a better idea of what they are? What
aspect of the XAuth authorizations could you not live with?

>
> My goal here isn’t to convince you as an individual that I’m right. My
> goal here is to present my ideas and explain the thought process behind
> them so that we all, as a group, can make the best decisions going forward
> based on that.
>

Well it seems we have different goals. I'm trying to get a better
understanding of your proposals, explain my concerns, and offer a solution
to arrive at some rough consensus. You only want to present your ideas.

 /Dick

---

From: Justin Richer <[email-masked]>
Date: Thu, 9 Jul 2020 20:44:28 -0400

Yes, the core idea is to not have to parse an assertion to get back the core authentication information, which consists of an identifier (iss/sub pair in OIDC, but could be a number of things). Sometimes the client is going to want the rest of the identity information, but If the user’s logged into the client before, the client has likely cached that info and probably won’t need it, and sending it would be a violation of privacy principles.. The client would want the info pretty much just in these cases:

 1. The client has never seen the user before. 
 2. The user’s information has been updated since the last time the client saw it.

Now for case (1), how would the client know if it wants to request the user’s profile info or not, since it doesn’t know who the user is? And the AS won’t know if client is going to want the profile info, since the AS won’t know if the client has the user’s info or not. Sure, the AS might have seen that client and that user combo previously, but it doesn’t know if the client needs an update.

And for (2), the client won’t know if the user’s info has been updated or not because it doesn’t know who the user is yet. If the AS can provide some time of updated stamp to the client, the client can pull the new info when it needs it.

If you ignore both of these cases and put all the user information inline with the main request/response, you end up in a situation where the client always requests everything and the server always provides everything, since you can’t be sure you’re not in situation (1) or (2) ahead of time.

This is really what I mean about the two-stage identity protocol. In the first stage, you push the bare minimum of what you need to get the user known to the client. In the second stage, the client uses its access token to call an API to get whatever else it needs to know about the user. This API could be an OIDC UserInfoEndpoint, a SCIM resource, a FHIR resource, or any number of other user APIs, and standardizing that information is not what GNAP should be focused on. OIDC does a really good job of letting developers log people in using this kind of protocol. While it’s possible to cram everything into an ID token on every request, there’s no need for it, and it’s likely a bad pattern to follow.

I’m sorry that you are surprised by my stance, but it hasn’t changed since I helped write the section of the charter that you quoted below. A big reason that I chose that wording was to support this use case but not to go in depth with an identity protocol, which I never really wanted us to do. However, it seems as soon as “identity” was brought up previously, people immediately jumped into talking about a full stack of user attributes and profile information. That wasn’t my intent in talking about identity, and I don’t think it’s something GNAP ought to do, at least not on its own. 

I do think there’s room for us to provide identifiers alongside the access token, so that’s there. There was stated interest in providing signed assertions as well, so I made sure that was enumerated for those who want to do such work. And I think it makes sense for us to provide a way to describe what kinds of things I want to get from an access token by defining a general purpose syntax for describing those things (notably, as a combination of reference strings and multi-dimensional objects). With these two, we can get most of what we need for a basic login system. Anything beyond that is going to need user profiles, authentication contexts, session control, and a lot of other identity-protocol stuff that GNAP shouldn’t be focusing on. We should keep it in mind as we build GNAP, but I think that like OIDC all that important extra stuff should be built separately. To me, that’s what not defining schemas and formats means. 

I don’t see any conflict with the charter here, and I’m surprised that you do.

 — Justin

> On Jul 9, 2020, at 5:55 PM, Dick Hardt <[email-masked]> wrote:
> 
> Thanks for the clarifications. I had chatted to Aaron about his post, and my understanding is not what is in the post on a closer read. My takeaway was why make the developer parse the ID_Token, why not give them the information directly.
> 
> I have interpreted the userinfo and id_token top level elements to be how the client wanted the query results, not part of the query. I had thought my example and definition of a Grant Response in XAuth [1] would have clearly communicated what I meant, but I see that I should call out that userinfo in XAuth returns the claims, rather than userinfo in OIDC returns an access token for the claims. Given GNAP is more expressive, and learning from the past, I'm proposing we offer the developer (and AS) a choice in how to acquire the claims.
> 
> While acquiring user information through an API at any time is appropriate in some use cases, in others why not give the client the info it needs right away rather than having to make another API call to get it? This would be appropriate when the user is making a purchase and wanting to provide shipping information. The user does not want to authorize the client to fetch their shipping address in the future. 
> 
> The group is chartered to develop mechanisms for conveying identity information
> nor is the group chartered to develop schemas for user information, profiles,
> More than identifiers about the user are clearly in scope of the WG charter, as are mechanisms for conveying identity information. Your stance and the charter look in conflict to me. What am I missing?
> 
> /Dick
> 
> [1] https://tools.ietf.org/html/draft-hardt-xauth-protocol-11#section-4.1 <https://tools.ietf.org/html/draft-hardt-xauth-protocol-11#section-4.1>
> 
> 
> 
> On Thu, Jul 9, 2020 at 1:04 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jul 9, 2020, at 3:29 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>>

---

From: Justin Richer <[email-masked]>
Date: Thu, 9 Jul 2020 20:46:36 -0400

> On Jul 9, 2020, at 6:50 PM, Dick Hardt <[email-masked]> wrote:
> 
> 
> 
> On Thu, Jul 9, 2020 at 12:17 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> On Jul 9, 2020, at 2:32 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
> It was about the complexity and readability -- of those specific lines of code.

But it’s not just about those lines, it’s about the context that those lines are in and the follow-on code paths that they cause. A lot of what you had “in comments” for the XAuth example would have repeated what was already included in the XYZ example, as I pointed out.

> 
> I've used JS type polymorphism to provide a cleaner API. For example, making an HTTP request. If I'm good with all the defaults, I can just provide the URI as a string, if I want to change a default, I provide an object and the URI is now a property of the object. Polymorphism allows the caller to have a simpler interface when it is a simple operation.
> 
> Do you have any examples of JSON polymorphism used in other protocols besides in a JWT?

Sounds to me like you’re describing exactly the kind of polymorphism that I’m talking about here. Use a string where it makes sense and an object where it makes sense, and there’s no ambiguity in calling the function. As you say, it's all about providing a cleaner API for the caller, and making things consistent in the model that the caller and provider are using. It takes a little bit of extra effort on the part of the API provider, but that’s where the complexity cost should be paid.

> We are comparing how to do it in XYZ vs XAuth -- so to make it apples and apples, the string is a scope, since that is the use case we are looking at.

You can use a scope as the string, and if you want to think of all string values in this request as all being “scopes", that’s fine, but only if you can concede that the scope can mean whatever the AS wants. I think that perhaps you’re putting a certain amount of semantic weight to “scope” that I’m missing, though.

> And the type in XAuth authorizations is different schemas for making a request. "oauth_scope", "oauth_rar", and now "oidc". I would expect that there may be more in the future, and we have a clear way of adding schemas, and for the client and AS to know they are talking the same "language".

And I’m saying that additional “schemas” for requesting information should be defined separately from the GNAP schema. We disagree on this topic and we’re repeating ourselves. 

> That was what I was afraid of. While an OAuth scope could mean whatever the AS decides it wants to be, the Client and AS know it is an OAuth scope.

How is that any different? I’m confused as to why you think it’s important to call this item a “scope” so that you “know what it is”, but then you’re OK with “scope” meaning literally anything.

> I believe the thread you’re referring to was commented on by several people, including an AD, as not being a helpful conversation for the group. I stopped responding to that thread when that was brought up, in order to respect that position and hopefully move the conversation along.
> 
> https://mailarchive.ietf.org/arch/msg/txauth/ECfShOtiN1WA1QiI77CBId4_VXg/ <https://mailarchive.ietf.org/arch/msg/txauth/ECfShOtiN1WA1QiI77CBId4_VXg/>
> 
> And I don't think Ben was saying the conversation was not helpful, but wanted to clarify the goal:
> 
> https://mailarchive.ietf.org/arch/msg/txauth/qOF5Wl3uYQ9rdzEz7ORftYAAHc4/ <https://mailarchive.ietf.org/arch/msg/txauth/qOF5Wl3uYQ9rdzEz7ORftYAAHc4/>
>  
> I’m beginning to think that this conversation thread is itself going off the rails in a similar way, since we seem to be repeating things at each other. 
> 
> Seems later messages in this thread indicate otherwise as there seems to be some additional understanding.
>  
> It’s become a comparison of solutions in detail and not a discussion of what the driving use cases are. I understand that you think your proposal is better, and I disagree and have pointed out what I see as several major flaws in it.
> 
> Would you list those for me so I have a better idea of what they are? What aspect of the XAuth authorizations could you not live with?

Haven’t we been talking about them all along in all of these threads? Isn’t that what this conversation is largely about? I think I’ve been pretty clear, but my concerns include, but are not limited to, the following:

 - Use of a ’type’ field to indicate sub-schemas to be parsed and understood
 - Separation of string-style “scope” parameters from object-style “rich’ parameters
 - Lack of ability to cleanly define combinations of different approaches
 - Outsourcing of query schema to external specs, specifically reliance on OAuth 2 technologies that come with OAuth 2 limitations
 - Overly verbose and awkward syntax to specify simple requests
 - Larger possibility of error conditions based on syntax alone (for example per the recent update, if someone asks for a multi-token response named “type”, that’s a class of error; if someone puts a “claims” field in an “oauth_scope” typed request, that’s an error, etc)

I have talked about all of these concerns, asked for clarification and detail on them, and provided alternatives for all of them. I’ve got concerns with other parts of the Xauth proposal as well, as I know you’ve got concerns with many parts of the XYZ proposal. But ours aren’t the only opinions that matter, and they’re not even the most important ones as we are both too close to our own solutions to see the truth. That’s the reason I originally brought my work into a standards body, and why I have such high hopes for GNAP even now.

> Well it seems we have different goals. I'm trying to get a better understanding of your proposals, explain my concerns, and offer a solution to arrive at some rough consensus. You only want to present your ideas.

Wow, that’s a really bold accusation, and it ignores the end of the sentence: "so that we all, as a group, can make the best decisions going forward”. I’ve been doing everything you claim to be doing as well — understanding your proposal, explaining my concerns, and offering solutions to those concerns. 

But it worries me that these threads have time and again devolved into just the two of us talking past each other, and not gathering consensus within the group. Ultimately, the group doesn’t have to pick either approach, but we aren’t really seeing input from others at this time. I would love to get away from this back and forth explanation and onto the real work of deciding what this protocol needs to do and how it needs to do it.

I’m not here to attack your proposal, but I will continue to make the best technical arguments I can for good design and engineering so that we can make GNAP the best protocol that it can be. I truly believe that it is possible we are building the next revolution in security protocols here, and that’s going to require a lot of hard engineering work.

 — Justin

---

From: Denis <[email-masked]>
Date: Fri, 10 Jul 2020 16:04:59 +0200

Hi Justin,

I dare to jump into this dialogue. I have two closely related questions:

    1) What kind of polymorphism do you intent to support ?
    2) What are the basic reasons for supporting "polymorphism" ?

Some help: Wikipedia states 
(https://en.wikipedia.org/wiki/Polymorphism_(computer_science)) :

    In programming languages and type theory, polymorphism is the
    provision of a single interface to entities of different types
    or the use of a single symbol to represent multiple different types.

    The most commonly recognized major classes of polymorphism are:

      *      Ad hoc polymorphism: defines a common interface for an
        arbitrary set of individually specified types.
      *      Parametric polymorphism: when one or more types are not
        specified by name but by abstract symbols that can represent any
        type.
      *      Subtyping (also called subtype polymorphism or inclusion
        polymorphism): when a name denotes instances of many different
        classes
             related by some common superclass.

Before answering to these two questions, please consider the following 
observations that follow.

> Yes, the core idea is to not have to parse an assertion to get back 
> the core authentication information, which consists of an identifier
> (iss/sub pair in OIDC, but could be a number of things). Sometimes the 
> client is going to want the rest of the identity information,
> but If the user’s logged into the client before, the client has likely 
> cached that info and probably won’t need it, and sending it would be
> a violation of privacy principles.. The client would want the info 
> pretty much just in these cases:
>
> Now for case (1), how would the client know if it wants to request the 
> user’s profile info or not, since it doesn’t know who the user is? And 
> the AS won’t know
> if client is going to want the profile info, since the AS won’t know 
> if the client has the user’s info or not. Sure, the AS might have seen 
> that client and that
> user combo previously, but it doesn’t know if the client needs an update.

For cases (1) and (2), as long as the user has not yet decided to 
attempt to reach a RS, the client has nothing to do.

  * When the user selects a RS and if FIDO is supported, the client
    should check whether the user has a FIDO account with that RS.
    If he does, it should connect transparently to the RS.  If he does
    not have a FIDO account with that RS, the client should check
    whether the RS supports FIDO or some attributes from some AS are
    requested. If FIDO is supported by the RS, it should propose
    to the user to create a FIDO account. If some attributes from some
    AS are requested, it should check whether the user has
    an account with one or more of these ASs. If he has, the user should
    select the appropriate AS and after his consent the client
    should contact that AS to obtain the requested attributes in order
    to get them inside an access token. Finally the client should send
    the access token to the RS. What happens next depends upon what the
    user is willing to do.

  * When the user selects a RS and if FIDO is NOT supported, the client
    should connect to the RS and the RS should report to the client
    the means of authentication that it supports. This may be FIDO
    and/or some access tokens with specific attributes from specific ASs.
    If the user believes that the requested authentication means is
    adequate according to what he wants to do on the RS, he may then /
    locally /choose the most appropriate means.

>
> And for (2), the client won’t know if the user’s info has been updated 
> or not because it doesn’t know who the user is yet.
> If the AS can provide some time of updated stamp to the client, the 
> client can pull the new info when it needs it.
>
> If you ignore both of these cases and put all the user information 
> inline with the main request/response, you end up in a situation
> where the client always requests everything and the server always 
> provides everything, since you can’t be sure you’re not in situation
> (1) or (2) ahead of time.

The RS should inform the client about what it needs to present, at 
latest at the time of the first access attempt.
As long as the client has not yet attempted to reach a RS, the client 
has nothing to do.

> This is really what I mean about the two-stage identity protocol.
> In the first stage, you push the bare minimum of what you need to get 
> the user known to the client.
> In the second stage, the client uses its access token to call an API 
> to get whatever else it needs to know about the user.

Since the RS is not yet identified, the AS(s) that is/are trusted by the 
RS is/are still unknown.
The client should not contact any AS before it knows which RS the user 
is willing to access.

Last questions:

Since these two stages should not happen, why is "polymorphism" really 
or still needed ? If yes, for which purpose(s) ?

Denis

> This API could be an OIDC UserInfoEndpoint, a SCIM resource, a FHIR 
> resource, or any number of other user APIs, and standardizing that 
> information is not what GNAP should be focused on. OIDC does a really 
> good job of letting developers log people in using this kind of 
> protocol. While it’s possible to cram everything into an ID token on 
> every request, there’s no need for it, and it’s likely a bad pattern 
> to follow.
>
> I’m sorry that you are surprised by my stance, but it hasn’t changed 
> since I helped write the section of the charter that you quoted below. 
> A big reason that I chose that wording was to support this use case 
> but not to go in depth with an identity protocol, which I never really 
> wanted us to do. However, it seems as soon as “identity” was brought 
> up previously, people immediately jumped into talking about a full 
> stack of user attributes and profile information. That wasn’t my 
> intent in talking about identity, and I don’t think it’s something 
> GNAP ought to do, at least not on its own.
>
> I do think there’s room for us to provide identifiers alongside the 
> access token, so that’s there. There was stated interest in providing 
> signed assertions as well, so I made sure that was enumerated for 
> those who want to do such work. And I think it makes sense for us to 
> provide a way to describe what kinds of things I want to get from an 
> access token by defining a general purpose syntax for describing those 
> things (notably, as a combination of reference strings and 
> multi-dimensional objects). With these two, we can get most of what we 
> need for a basic login system. Anything beyond that is going to need 
> user profiles, authentication contexts, session control, and a lot of 
> other identity-protocol stuff that GNAP shouldn’t be focusing on. We 
> should keep it in mind as we build GNAP, but I think that like OIDC 
> all that important extra stuff should be built separately. To me, 
> that’s what not defining schemas and formats means.
>
>> On Jul 9, 2020, at 5:55 PM, Dick Hardt <[email-masked] 
>> <mailto:[email-masked]>> wrote:
>>
>> Thanks for the clarifications. I had chatted to Aaron about his post, 
>> and my understanding is not what is in the post on a closer read. My 
>> takeaway was why make the developer parse the ID_Token, why not give 
>> them the information directly.
>>
>> I have interpreted the userinfo and id_token top level elements to be 
>> how the client wanted the query results, not part of the query. I had 
>> thought my example and definition of a Grant Response in XAuth [1] 
>> would have clearly communicated what I meant, but I see that I should 
>> call out that userinfo in XAuth returns the claims, rather than 
>> userinfo in OIDC returns an access token for the claims. Given GNAP 
>> is more expressive, and learning from the past, I'm proposing we 
>> offer the developer (and AS) a choice in how to acquire the claims.
>>
>> While acquiring user information through an API at any time is 
>> appropriate in some use cases, in others why not give the client the 
>> info it needs right away rather than having to make another API call 
>> to get it? This would be appropriate when the user is making a 
>> purchase and wanting to provide shipping information. The user does 
>> not want to authorize the client to fetch their shipping address in 
>> the future.
>>
>>     identifiers about the user, or even just ask to “identify the
>>     user”, and leave everything else to a higher level identity
>>     protocol. I do not think that having an identity and profile
>>     query/response language at the core of GNAP is a good idea, and
>>     it’s certainly not in our charter.
>>
>>
>> charter, as are mechanisms for conveying identity information. Your 
>> stance and the charter look in conflict to me. What am I missing?
>>
>> /Dick
>>
>>     In Aaron’s post he doesn’t talk about how the request would be
>>     made, just what the response could look like, and we are talking
>>     about how to request that. Aaron’s post specifically calls out
>>     that this is just an identifier for the user and states:
>>
>>         If the application needs to know profile information about
>>         the user, it can get that from the userinfo endpoint using
>>         the access token it just obtained.
>>
>>
>>     And I think that’s a good design pattern to follow. This isn’t
>>     “userinfo” being returned alongside the access token.
>>
>>         OPTIONAL. Requests that the listed individual Claims *be
>>         returned from the UserInfo Endpoint*. If present, the listed
>>         Claims are being requested to be added to any Claims that are
>>         being requested using scope values. If not present, the
>>         Claims being requested from the UserInfo Endpoint are
>>         a response_type value that results in an *Access Token being
>>         issued to the Client for use at the UserInfo Endpoint*.
>>
>>         id_token
>>         OPTIONAL. Requests that the listed individual Claims be
>>         returned in the ID Token. If present, the listed Claims are
>>         being requested to be added to the default Claims in the ID
>>         Token. If not present, the default ID Token Claims are
>>         requested, as per the ID Token definition in Section 2 and
>>         per the additional per-flow ID Token requirements in
>>         Sections 3.1.3.6, 3.2.2.10, 3.3.2.11, and 3.3.3.6..
>>
>>
>>     Since you had re-used the “userinfo” and “id_token” top-level
>>     claims, I had assumed that they meant the same thing as in the
>>     OIDC spec. It’s clear to me, now, that this isn’t what you meant,
>>     but this is why I’m saying you’re not using the whole query
>>     language.
>>
>>     There are proposed extensions to the OIDC claims query that would
>>     put returned data into a different place[1], and so it would be
>>     possible to use the claims structures to handle this. But at that
>>     point if the goal is just to use the internal query format, then
>>     I think that we can do better using … polymorphic JSON. :)
>>
>>     identifiers about the user, or even just ask to “identify the
>>     user”, and leave everything else to a higher level identity
>>     protocol. I do not think that having an identity and profile
>>     query/response language at the core of GNAP is a good idea, and
>>     it’s certainly not in our charter.
>>
>>      — Justin
>>
>>     [1]
>>     https://mattrglobal.github.io/oidc-client-bound-assertions-spec/ defines
>>     a “credential’ target.
>>
>>>     Yes. Which is why I referred to Aaron's post originally which
>>>     calls out for returning plain text claims.
>>>
>>>     I don't really understand what you mean by "OIDC claims query
>>>     language". The claims mean the same thing. And I was also
>>>     reusing the modifiers such as {"essential": true}. What top
>>>     level functionality are you referring to?
>>>
>>>         Ah, so you’re saying that the “userinfo” claims would be
>>>         returned directly? I didn’t realize that you had intended to
>>>         change how the OIDC claims query language functioned in your
>>>         examples, and had assumed it would work the same was as the
>>>         spec you were referencing. Your example of splitting it up
>>>         makes that more clear. Though I would argue at that point,
>>>         you’re creating a new query language since you’re not using
>>>         the top-level functionality from ODIC’s definition.
>>>
>>>          — Justin
>>>
>>>>         On Jul 9, 2020, at 3:15 PM, Dick Hardt
>>>>         <[email-masked] <mailto:[email-masked]>> wrote:
>>>>
>>>>         You are jumping to many conclusions below. Let me break
>>>>         down the proposal into some bite size chunks.
>>>>
>>>>         In the results, the developer gets claims back in the
>>>>         response claims object, and access tokens etc. back in the
>>>>         authorizations object. Just because an access token returns
>>>>         claims, it is still an access token.
>>>>
>>>>         Yes, the developer can't get a single access token that can
>>>>         both acquire OIDC claims, and access photos (there are
>>>>         separate tokens for each), but I would argue that
>>>>         separating the access is a positive security property, as a
>>>>         client component accessing the user profile has a token
>>>>         independent of the client component accessing photos. And
>>>>         at the AS, there is no requirement for the userinfo
>>>>         endpoint to take the same token as the photo endpoint.
>>>>
>>>>         wrt. my position on reusing OIDC -- it has not changed. I
>>>>         have viewed the OIDC claims as the "query language". No
>>>>         need to reinvent that. We are creating a new protocol, so
>>>>         no need to use the OAuth or OIDC protocols.
>>>>
>>>>         * OAuth scopes could be a space separates string to be
>>>>         consistent with OAuth 2, or an array of strings so that it
>>>>         is more JSON like. I have no strong opinion.
>>>>
>>>>         On Thu, Jul 9, 2020 at 8:39 AM Justin Richer
>>>>         <[email-masked] <mailto:[email-masked]>> wrote:
>>>>
>>>>             But this approach doesn’t keep things in their
>>>>             respective containers — you’ve explicitly got “claims”
>>>>             underneath the “authorizations” header, and you’ve got
>>>>             items that come back as rights associated with the
>>>>             access token (which should be “authorizations”) in the
>>>>             “userinfo” section under the “claims” header. And as
>>>>             far as I can tell, these two sections are redundant to
>>>>             each other. Everything is everywhere.
>>>>
>>>>             Additionally, this approach and syntax makes it
>>>>             difficult to combine different kinds of requests into
>>>>             one. One of OpenID Connect’s biggest draws, as I’m sure
>>>>             you recall, is that it could be combined with a request
>>>>             for non-OIDC resources. This was the real innovation
>>>>             that Twitter and Facebook’s identity APIs brought,
>>>>             access to more than just authentication, and what
>>>>             Google had tried to replicate with the awkward OpenID 2
>>>>             + OAuth 1 hybrid system. Taking a step back from the
>>>>             existing solutions of OpenID 2 and OAuth 1 let us, as
>>>>             the community, see the value in the pattern that became
>>>>             OIDC on top of OAuth 2.
>>>>
>>>>             Sure, you could say that the “oidc” type also can allow
>>>>             a “scopes” parameter, but what about a RAR style
>>>>             object, then? And what about when someone comes up with
>>>>             some new way to request access rights, or a VC-based
>>>>             query language? Does every “type” need to now know
>>>>             about every other “type” in order for an AS to be able
>>>>             to figure out how they go together? This seems like the
>>>>             protocol definition limiting what combinations the AS
>>>>             can handle, or what an RS might want to use.
>>>>
>>>>             My stance is that GNAP should have a way to query for
>>>>             rights in the access token (“authorizations” in xauth
>>>>             parlance) and identifiers for the user (“claims” in
>>>>             xauth parlance), and anything else should be an
>>>>             extension with potentially different models. The AS
>>>>             would process the “authorizations” equivalent (for the
>>>>             access token) alongside any other incoming query and
>>>>             I find it interesting that you are now saying we don’t
>>>>             need to use the OIDC request format when previously
>>>>             you’ve made it clear that you were in favor of pointing
>>>>             at external query languages, including their syntax.
>>>>             I’m glad to see that you’re now looking at things in a
>>>>             more flexible way, but I think it’s important that we
>>>>             be careful and conscientious about how we reference any
>>>>             external query languages in GNAP.
>>>>
>>>>              — Justin
>>>>
>>>>>             On Jul 8, 2020, at 6:55 PM, Dick Hardt
>>>>>             <[email-masked] <mailto:[email-masked]>>
>>>>>             wrote:
>>>>>
>>>>>             Hey Justin,
>>>>>
>>>>>             Just because we are using OIDC claims, does not mean
>>>>>             we need to mimic the OIDC request and response.
>>>>>             This keeps all the authorizations and claims in their
>>>>>             respective request and response containers.
>>>>>
>>>>>             We had a thread months ago on the OIDC two stage
>>>>>             model, and I still fail to see why forcing that has
>>>>>             any advantage.
>>>>>
>>>>>             /Dick
>>>>>
>>>>>
>>>>>             On Wed, Jul 8, 2020 at 3:25 PM Justin Richer
>>>>>             <[email-masked] <mailto:[email-masked]>> wrote:
>>>>>
>>>>>                 I’m glad that we can agree that there are a number
>>>>>                 of things in legacy protocols that are unfortunate
>>>>>                 side effects of the circumstances in which they
>>>>>                 were built. Space-separated scope strings, for
>>>>>                 instance, would fall in that category, as I’ve
>>>>>                 previously explained.
>>>>>
>>>>>                 A key point in the below: the OIDC “claims”
>>>>>                 request already mixes user claims (returned in an
>>>>>                 API) and authorization (to fetch user claims from
>>>>>                 an API), so that ship has sailed if you’re using
>>>>>                 it. It doesn’t make sense to have it under a
>>>>>                 “claims” or “authorizations” request, since it’s a
>>>>>                 query language that affects both. Maybe you’d call
>>>>>                 this another “unfortunate design”, but the context
>>>>>                 was about re-using an externally-defined query
>>>>>                 My scenario was for someone who is already using
>>>>>                 “claims” and wants to keep using it. (The vast
>>>>>                 majority of OIDC implementations, in my
>>>>>                 experience, don’t use that feature, and it’s not
>>>>>                 even required to be implemented by the AS, but
>>>>>                 again we’re talking about using this feature as an
>>>>>                 example of an external query language — and there
>>>>>                 are others out there.) In GNAP, you should return
>>>>>                 claims directly in the response, and request
>>>>>                 specific elements from the APIs protected by the
>>>>>                 access token. These are separate things, and by
>>>>>                 design both XAuth and XYZ have put them into
>>>>>                 separate containers in the request. This is a good
>>>>>                 design, and so putting something that conflates
>>>>>                 these two aspects into one or the other of the
>>>>>                 Additionally, though this is a bit of an aside and
>>>>>                 getting into the specifics of identity, the
>>>>>                 “claims” parameter of ODIC is a query language
>>>>>                 bound to the full user profile. It is my stated
>>>>>                 position that the items coming back from the AS
>>>>>                 should only be identifiers, and not full profile
>>>>>                 information. The reasoning is pretty simple: the
>>>>>                 client doesn’t know what profile information it
>>>>>                 needs until it knows who the user is, so putting
>>>>>                 that into a protected API like the UserInfo
>>>>>                 Endpoint makes much more sense than putting it
>>>>>                 into the immediate response, where it is not
>>>>>                 needed, because the client already knows it. The
>>>>>                 AS doesn’t know what the client needs to know,
>>>>>                 either, so it can’t determine what to fulfill.
>>>>>                 OIDC’s two-stage model makes sense, and GNAP
>>>>>                 should really only focus on enabling this.
>>>>>
>>>>>                  — Justin
>>>>>
>>>>>>                 On Jul 8, 2020, at 6:10 PM, Dick Hardt
>>>>>>                 <[email-masked]
>>>>>>                 <mailto:[email-masked]>> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>                 On Wed, Jul 8, 2020 at 1:02 PM Justin Richer
>>>>>>                 <[email-masked] <mailto:[email-masked]>> wrote:
>>>>>>
>>>>>>                     On Jul 8, 2020, at 3:16 PM, Dick Hardt
>>>>>>                     <[email-masked]
>>>>>>                     <mailto:[email-masked]>> wrote:
>>>>>>>
>>>>>>>                     I think representing the request as an array
>>>>>>>                     is simplistic, and complicated at the same
>>>>>>>                     time.
>>>>>>>
>>>>>>>                     On the simplistic front, as there is no
>>>>>>>                     clear mechanism for extending the request
>>>>>>>                     with properties that apply to all of the
>>>>>>>                     request.
>>>>>>
>>>>>>                     The elements of the array are taken as a set,
>>>>>>                     to be tied to the same resulting access
>>>>>>                     token. If one of those elements is defined,
>>>>>>                     by the AS and/or the RS’s it’s protecting, to
>>>>>>                     apply across some or all of the other
>>>>>>                     elements, then that’s up to the AS’s policy.
>>>>>>                     Much like the “openid” scope in OIDC, which
>>>>>>                     switches on all sorts of contextual stuff in
>>>>>>                     the request. So to handle something like
>>>>>>                     this, an AS can easily declare that a given
>>>>>>                     scope-style string or a given object property
>>>>>>                     applies to different parts of the request.
>>>>>>                     You don’t need to externalize it here.
>>>>>>
>>>>>>
>>>>>>                 I view the "openid" scope as an unfortunate
>>>>>>                 design as OIDC was constrained by building on top
>>>>>>                 of OAuth. (a problem I hoped to avert by having
>>>>>>                 "identity" in scope for GNAP) The "openid" scope
>>>>>>                 does not function as scope per se, and I think it
>>>>>>                 makes OIDC harder to understand as the "openid"
>>>>>>                 scope causes non-scope behavior.
>>>>>>
>>>>>>
>>>>>>                     Do you have a concrete use case that requires
>>>>>>                     that feature to be done in the way that you
>>>>>>                     describe? I am trying to separate the driving
>>>>>>                     use case from the proposed solutions to see
>>>>>>                     what the differences are.
>>>>>>
>>>>>>
>>>>>>                 Perhaps the client wants access to be HIPPA
>>>>>>                 compliant? The HIPPA compliance signal applies to
>>>>>>                 the scopes.
>>>>>>
>>>>>>                 Adding other properties to an object is a well
>>>>>>                 understood extension mechanism. Adding an
>>>>>>                 additional element to an array that does not act
>>>>>>                 like the other elements seems like a hack.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>                     Using JSON type polymorphism requires the AS
>>>>>>>                     to test each member of the array to
>>>>>>>                     determine if it is a string or an object.
>>>>>>>                     Only after detecting a RAR object does the
>>>>>>>                     AS know the client is making a RAR request.
>>>>>>
>>>>>>                     That’s correct — but the AS needs to parse
>>>>>>                     the whole resources request in order to
>>>>>>                     figure out what the client is asking for,
>>>>>>                     anyway, whether it’s by strings or objects or
>>>>>>                     whatever else might be defined by an
>>>>>>                     extension. Is there an argument for having an
>>>>>>                     AS do an early dispatch on a request before
>>>>>>                 Determining if an item in an array is a scope or
>>>>>>                 a RAR object by looking at the type being either
>>>>>>                 a string or an object seems less clear than a
>>>>>>>                     This also limits the request to be composed
>>>>>>>                     only of scope strings or RAR objects. I
>>>>>>>                     don't see how other strings or objects could
>>>>>>>                     be used in the array, so there is no clear
>>>>>>>                     extension point in the "resources" array for
>>>>>>>                     other query mechanisms.
>>>>>>
>>>>>>                     That’s not the case in XYZ since we aren’t
>>>>>>                     declaring that a string has to be an
>>>>>>                     OAuth2-style scope. It can be, but ultimately
>>>>>>                     it’s just a string that the AS can
>>>>>>                     understand. And the objects are just that —
>>>>>>                     objects. If the AS understands what the
>>>>>>                     object is, it can be a RAR object or it can
>>>>>>                     be something completely API-specific with
>>>>>>                     another query language entirely.
>>>>>>
>>>>>>
>>>>>>                 But the other query language would need a type
>>>>>>                 that has been reserved in the RAR name space for
>>>>>>                 there to be interop, so it effectively is a RAR
>>>>>>                 extension.
>>>>>>
>>>>>>                 There are query languages in other domains that
>>>>>>                 may not fit nicely into RAR such as a query for
>>>>>>                 medical records.
>>>>>>
>>>>>>                 Yes, the medical records could be yet another top
>>>>>>                 level property, but per below, I think that is
>>>>>>                 confusing.
>>>>>>
>>>>>>                     (Point, though: RAR already pretty much
>>>>>>                     allows this by letting them be extended
>>>>>>                     infinitely, a feature it inherits from XYZ)
>>>>>>
>>>>>>                     I’m proposing that we do the same thing with
>>>>>>                     GNAP: it’s an array of strings or objects and
>>>>>>                     each of those means the same thing,
>>>>>>                     “something the client is asking for”.
>>>>>>
>>>>>>>
>>>>>>>                     Just as RAR has a "type" property, I propose
>>>>>>>                     the "resources" ("authorizations" in XAuth)
>>>>>>>                     be an object, where the other properties are
>>>>>>>                     determined by the "type" property. This
>>>>>>>                     allows extensions to define new ways to
>>>>>>>                     query for an authorization rather than
>>>>>>>                     having to fit into scopes or RAR.
>>>>>>>
>>>>>>
>>>>>>                     It’s my stance that this is an unnecessary
>>>>>>                     limitation at this level. The objects within
>>>>>>                     the array should be typed, like RAR, but it
>>>>>>                     doesn’t make sense for the overall request to
>>>>>>                     be typed. Instead, there should be one “type"
>>>>>>                     of query in the core, what XYZ calls the
>>>>>>                     “resources” request. Other query languages
>>>>>>                     should be added as extensions either to the
>>>>>>                     RAR-style objects (by defining a type at that
>>>>>>                     level) or as a separate top-level member.
>>>>>>
>>>>>>                     For example, let’s take the OIDC “claims”
>>>>>>                     query language. My current thought is that
>>>>>>                     this really shouldn’t be a part of the
>>>>>>                     “resources” or “claims” part of the request,
>>>>>>                     but instead as its own top-level member, like
>>>>>>                     it is in the OIDC protocol today. The main
>>>>>>                     reason for this is the nature of the OIDC
>>>>>>                     claims language: it specifies targets for the
>>>>>>                     resulting data, and those targets cross
>>>>>>                     different ways to return things. So it
>>>>>>                     doesn’t actually affect just resources like
>>>>>>                     the UserInfo Endpoint, or the ID Token, but
>>>>>>                     both and potentially others out there. If
>>>>>>                     your system supported such an extension, it
>>>>>>                     could theoretically forego both the built-in
>>>>>>                     “claims” and “resources” parts of the
>>>>>>                     request, and use the “oidc_claims_query”
>>>>>>                     member (or whatever it would be called). This
>>>>>>                     would let such an extension use the OIDC
>>>>>>                     claims processing mechanism as it is today.
>>>>>>
>>>>>>                 While this may be more understandable to a
>>>>>>                 developer just porting an app OIDC that only
>>>>>>                 wants OIDC results, but I think it is more
>>>>>>                 complicated as soon as the developer wants other
>>>>>>                 results, which is likely what prompted the
>>>>>>                 developer to use GNAP instead of ODIC.
>>>>>>
>>>>>>                 I think it is easier to understand if all the
>>>>>>                 claims are in one container, and all the
>>>>>>                 authorizations are in another container.
>>>>>>
>>>>>>                 If a developer wants access to some resources,
>>>>>>                 some claims, and an OpenID Token, they are having
>>>>>>                 to use "claims", "resources", and
>>>>>>                 "oidc_claims_query". Now the claims and access
>>>>>>                 tokens are spread across multiple containers.
>>>>>>                 There are some claims in the "claims" container,
>>>>>>                 and some "claims" in the "oidc_claims_query"
>>>>>>                 container. And is the access token response
>>>>>>                 in "oidc_claims_query" the same as an access
>>>>>>                 token response in "resources"? It would seem
>>>>>>                 simpler if they were, and if all the access
>>>>>>                 Per Aaron's post that you have referred to, the
>>>>>>                 developer can get sme bare claims directly in the
>>>>>>                 response in the "claims" object, an ID Token that
>>>>>>                 has the same or different claims, and if they
>>>>>>                 want, an access token that they can call a
>>>>>>                 user_info endpoint to get the same, or different
>>>>>>                 claims.
>>>>>>
>>>>>>                 For example, an enterprise app client may want an
>>>>>>                 ID Token with the email address, bare claims for
>>>>>>                 the user's name and a URI to a profile photo, and
>>>>>>                 https://aaronparecki.com/2019/07/18/17/adding-identity-to-xyz
>>>>>>                 ᐧ
>>>>>
>>>>>             ᐧ
>>>>
>>>>         ᐧ
>>>
>>>     ᐧ
>>
>
>

---

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 10:39:13 -0700

On Thu, Jul 9, 2020 at 5:46 PM Justin Richer <[email-masked]> wrote:

> But it’s not just about those lines, it’s about the context that those
> lines are in and the follow-on code paths that they cause. A lot of what
> you had “in comments” for the XAuth example would have repeated what was
> already included in the XYZ example, as I pointed out.
>

The context between those lines is pretty much the same. Yes, the XAuth
example would have had to loop over each scope and RAR object, which is not
that different than XYZ looping over each item, and the deciding how to
process each item. My point is that checking the object type to decide what
to do is an opaque decision vs checking an explicit type.

> Sounds to me like you’re describing exactly the kind of polymorphism that
> I’m talking about here. Use a string where it makes sense and an object
> where it makes sense, and there’s no ambiguity in calling the function. As
> you say, it's all about providing a cleaner API for the caller, and making
> things consistent in the model that the caller and provider are using. It
> takes a little bit of extra effort on the part of the API provider, but
> that’s where the complexity cost should be paid.
>

My examples are not the same at all. The caller has a simpler version of
passing the same object. XYZ is passing two different types, where a string
means one thing, and an object means something else. The string is not a
shorthand for the object.

In polymorphic APIs, it makes the code cleaner to pass a singular item when
the API takes an array, or the API takes a string for the common property
of the object which is the parameter. Here are some code examples for both:

// passing a singular item, a simpler version of foo(['string'])
foo('string')
// passing a plurality of the same item
foo(['string1','string2','string3'])

// implementation

foo = ( param ) => {
    var a = []
    if (typeof param === 'string') {
        a[0] = param;
    } else if (typeof param === 'array') {
        a = param;
    }
    // process array a
}

// pass a uri as string and accept all defaults, a simpler version of
bar({uri:'uri'})
bar('uri')
// pass an object with uri and method
bar({uri: 'uri', method: 'POST'})

// implementation
bar = ( param ) => {
    var p = DEFAULT_OBJ;
    if (typeof param === 'string') {
        p.uri = param;
    } else if (typeof param === 'object') {
        Object.keys(param).forEach( item => {
            p[item] = param[item];
        });
    }
    // process p object
}

In GNAP, we could take a string rather than an array for a scope parameter,
for example:

"scope": "read"

instead of

"scope": ["read"]

OIDC uses the latter polymorphism for

{
  "name": {"essential": true},
  "photo": null
}

as being shorthand for

{
  "name": {"essential": true},
  "photo": {"essential": false}
}

>> No, it is not. It is saying that it is a resource request represented as
>> a string. One way to represent a resource request as a string is an OAuth 2
> You can use a scope as the string, and if you want to think of all string
> values in this request as all being “scopes", that’s fine, but only if you
> can concede that the scope can mean whatever the AS wants. I think that
> perhaps you’re putting a certain amount of semantic weight to “scope” that
> I’m missing, though.
>

The string could be a scope, or it could be a claim such as in my "oidc"
type example. The AS could support both scope and claims, and they could
have overlapping string values.

> And I’m saying that additional “schemas” for requesting information should
> be defined separately from the GNAP schema. We disagree on this topic and
> we’re repeating ourselves.
>

The charter is pretty clear that GNAP should not define schemas, so I don't
know what you mean by the "the GNAP schema"

> That was what I was afraid of. While an OAuth scope could mean whatever
> the AS decides it wants to be, the Client and AS know it is an OAuth scope.
>
>
> How is that any different? I’m confused as to why you think it’s important
> to call this item a “scope” so that you “know what it is”, but then you’re
> OK with “scope” meaning literally anything.
>

A scope string is one of a set of strings defined by the AS.

The AS may use strings to define a different schema, such as which claims
to return from a userinfo endpoint.

 I'm going to separate the my other responses into separate threads as they
are different topics.

/Dick

---

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 10:58:42 -0700

Thanks for listing what you consider flaws in XAuth. It simplifies having a
disussion on them, and I hope to get a better idea of your concerns
On Thu, Jul 9, 2020 at 5:46 PM Justin Richer <[email-masked]> wrote:

>
> Haven’t we been talking about them all along in all of these threads?
> Isn’t that what this conversation is largely about? I think I’ve been
> pretty clear, but my concerns include, but are not limited to, the
> following:
>

What is your concern with this? What use case does it prevent you from
doing?

>  - Separation of string-style “scope” parameters from object-style “rich’

Do you mean that they are not in the same array? Both of these parameters
are in the "oauth_rich" type, but are in their own
"array"

>  - Lack of ability to cleanly define combinations of different approaches

This is too vague. Would you provide more clarity?

>  - Outsourcing of query schema to external specs, specifically reliance on
> OAuth 2 technologies that come with OAuth 2 limitations
>

Outsourcing schemas is in the charter. OAuth 2 is just one of those
schemas. If other domains have their own schema, they can use it in GNAP as
well.

>  - Overly verbose and awkward syntax to specify simple requests

There is a balance between clarity and brevity. What use case does this
prevent you from solving? This sounds like a stylistic concerns rather than
a "flaw".

>  - Larger possibility of error conditions based on syntax alone (for
> example per the recent update,
>

"larger possibility"? Have you done an analysis of the error conditions in
both?

> if someone asks for a multi-token response named “type”, that’s a class of
> error;
>

Agreed. And it is a compromise doing that, but looked like the best of the
options.

It is a visible error that the client will get immediately in response to
the request. I think an error message specifically about this error would
be really useful.

> if someone puts a “claims” field in an “oauth_scope” typed request, that’s
> an error, etc)
>

Are you saying putting an ignored property in an object? I don't know what
you mean with this one.

/Dick
ᐧ

---

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 11:15:46 -0700

inline ...

On Thu, Jul 9, 2020 at 5:44 PM Justin Richer <[email-masked]> wrote:

> Yes, the core idea is to not have to parse an assertion to get back the
> core authentication information, which consists of an identifier (iss/sub
> pair in OIDC, but could be a number of things). Sometimes the client is
> going to want the rest of the identity information, but If the user’s
> logged into the client before, the client has likely cached that info and
> probably won’t need it, and sending it would be a violation of privacy
> principles.. The client would want the info pretty much just in these cases:
>

Agreed

> user’s profile info or not, since it doesn’t know who the user is?
>

But the client could know who the user is. The client may have used a
different AS to authenticate the user. The User may have self identified to
the client. The client may have a cookie saying who the user was and the
user said that was them. While the latter cases are really a strong hint,
they are likely right most of the time and can lead to a user experience
basde on that hint

> And the AS won’t know if client is going to want the profile info, since
> the AS won’t know if the client has the user’s info or not. Sure, the AS
> might have seen that client and that user combo previously, but it doesn’t
> know if the client needs an update.
>

The client can share with the AS the user it knows or thinks it is dealing
with, which could let the AS respond if the information was new. This could
be the case for an AS that is providing claims, but not authentication, and
could happen silently. The user would only interact if the user information
had changed, and the client wanted the updated information.

>
> And for (2), the client won’t know if the user’s info has been updated or
> not because it doesn’t know who the user is yet. If the AS can provide some
> time of updated stamp to the client, the client can pull the new info when
> it needs it.
>

See above.

>
> If you ignore both of these cases and put all the user information inline
> with the main request/response, you end up in a situation where the client
> always requests everything and the server always provides everything, since
> you can’t be sure you’re not in situation (1) or (2) ahead of time.
>

See above. There are a number of other states the client could be in.

For example, the client could be stateless about user information, so it
knows it is ALWAYS in state 1.

> This is really what I mean about the two-stage identity protocol.

I know what it is. Per above, GNAP lets us support a wider set of use
cases. Why limit ourselves to what OIDC supported?

> In the first stage, you push the bare minimum of what you need to get the
> user known to the client. In the second stage, the client uses its access
> token to call an API to get whatever else it needs to know about the user.
>

>From a privacy perspective in non-enterprise use cases, I think the user
should give consent to any updated personal information to a client. In
general, the client should not be able to get the latest information about
a user whenever it wants.

/Dick
ᐧ

---

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 11:33:24 -0700

Justin, your stance is surprising for the following reasons:

1) Both XYZ and XAuth use the term claims, rather than identifiers. "A
claim is a statement that one subject, such as a person or organization,
makes about itself or another subject."[1]. A claim is clearly more than an
identifier.

2) XAuth has had non-identifier claims in the examples since -01 (name,
photo).

3) The charter does not state that ONLY identifiers will be returned,
identifiers are one of the examples, as are OIDC ID Tokens, SAML
assertions, and Verifiable Credentials. All of these often bind
non-identifiers to one or more identifiers.

[1] https://en.wikipedia.org/wiki/Claims-based_identity#Identity_and_claims

Justin's stance earlier in the discussion:

<snip>

> I’m sorry that you are surprised by my stance, but it hasn’t changed since
> I helped write the section of the charter that you quoted below. A big
> reason that I chose that wording was to support this use case but not to go
> in depth with an identity protocol, which I never really wanted us to do.
> However, it seems as soon as “identity” was brought up previously, people
> immediately jumped into talking about a full stack of user attributes and
> profile information. That wasn’t my intent in talking about identity, and I
> don’t think it’s something GNAP ought to do, at least not on its own.
>
> I do think there’s room for us to provide identifiers alongside the access
> token, so that’s there. There was stated interest in providing signed
> assertions as well, so I made sure that was enumerated for those who want
> to do such work. And I think it makes sense for us to provide a way to
> describe what kinds of things I want to get from an access token by
> defining a general purpose syntax for describing those things (notably, as
> a combination of reference strings and multi-dimensional objects). With
> these two, we can get most of what we need for a basic login system.
> Anything beyond that is going to need user profiles, authentication
> contexts, session control, and a lot of other identity-protocol stuff that
> GNAP shouldn’t be focusing on. We should keep it in mind as we build GNAP,
> but I think that like OIDC all that important extra stuff should be built
> separately. To me, that’s what not defining schemas and formats means.
>

---

From: Justin Richer <[email-masked]>
Date: Fri, 10 Jul 2020 16:09:31 -0400

> On Jul 10, 2020, at 1:39 PM, Dick Hardt <[email-masked]> wrote:
> 
> 
> 
> On Thu, Jul 9, 2020 at 5:46 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> 
> 
>> On Jul 9, 2020, at 6:50 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> 
>> 
> The context between those lines is pretty much the same. Yes, the XAuth example would have had to loop over each scope and RAR object, which is not that different than XYZ looping over each item, and the deciding how to process each item. My point is that checking the object type to decide what to do is an opaque decision vs checking an explicit type.

The context is really not the same though, as you actually  point out here, and calling one style of type checking “opaque” vs. “explicit” is stylistic and not a helpful comparison. I’m not surprised to find that you think the way you did it is easier, especially given the disconnect we have of what the components of the array represent. I started with some of the type-field-based structures in early versions of XYZ and moved away from them after having bad experiences with building it. There are still a few parts of the XYZ protocol that have that style (the “user” section, for example) that I think need to be changed. I think that the data-type based style of polymorphism, coupled with using the left-hand-side value of object members to indicate type or identifier, is significantly simpler in design and implementation.

Instead, I realized that we could get a cleaner protocol and better underlying code by dispatching based on the type within the protocol itself. I’ve gotten comments from a number of implementers that they like this design aspect, and I really like it myself.

> My examples are not the same at all. The caller has a simpler version of passing the same object. XYZ is passing two different types, where a string means one thing, and an object means something else. The string is not a shorthand for the object.

The string is, semantically, a shorthand for the object. That’s what I’ve been saying from the beginning, and I’ve put into several examples so far. There are two ways to add rights to an access token resulting from the request. So:

{
  “resources”: [ “photo” ]
}

Can really be thought of as a shorthand, for example it could expand to this:

{
  “resources”: [
   {
     “datatypes”: [ “pohoto” ],
     “actions”: [ “read” ],
     “locations”: [ “https://server/photoapi/ <https://server/photoapi/>“ ]
   }
}

In this straw man, if the client wants write access to the API, it needs to use the object-style request to do so.

It’s up to the AS, or really the API that it’s protecting, to figure out what that expansion really looks like, and how much of the more complex policy to expose. My example of processing only string-based resource requests was for the case where the AS only gives the shorthand version, and doesn’t allow detailed access into its protection policies. It’s not a different kind of request, it’s a shorthand, much like passing an identifier in lieu of a key to identify the client software instance making the call.

But really, the point is that in both cases the string and the object both represent the same kind of thing: a piece of access rights that the client is requesting at the AS which gets put into the access token. Thus, having them together in a single array and processing them together makes sense to me. If you are thinking of strings and objects as completely different from each other,  you’d expect them to be handled separately, but I don’t think they are actually different because they both represent a view of the same underlying thing.

> 
> In polymorphic APIs, it makes the code cleaner to pass a singular item when the API takes an array, or the API takes a string for the common property of the object which is the parameter.

Yes, those are two examples of why it can be good. There are other reasons to apply it, like having an array with differently typed items that represent the same kind of thing underneath.

> Here are some code examples for both:
> 
> // pass a uri as string and accept all defaults, a simpler version of bar({uri:'uri'})
> bar('uri')
> In GNAP, we could take a string rather than an array for a scope parameter, for example:
> 
> "scope": "read"
> 
> instead of 
> 
> "scope": ["read"]
> 

All of these are great examples of why object-type-based polymorphism is a good and powerful thing, and that’s the approach I’m saying we should use within the GNAP protocol. I would argue that the last one isn’t polymorphism so much as a default based on a null value (often taken as a special class of an “object” value anyway), but that’s splitting hairs.

> The string could be a scope, or it could be a claim such as in my "oidc" type example. The AS could support both scope and claims, and they could have overlapping string values. 

Both would represent “things that the client wants back in the access token”, and therefore the AS would need to differentiate. In that case I think it actually makes a lot more sense for the AS to define a more rich mechanism to request user information. In XYZ it could look like this:

{
   “resources”: [
     {
        “type”: “oidc_userinfo”,
        “datatypes”: [ “email”, “phone”, “address”, “profile.photo" ]
     }
   ]
}

But defining the details of that kind of query is clearly outside the scope of GNAP (see below), and I think better suited to an identity protocol built on top of GNAP.

> The charter is pretty clear that GNAP should not define schemas, so I don't know what you mean by the "the GNAP schema"
>  

That’s not true. The charter is clear that "nor is the group chartered to develop schemas for user information, profiles, or other identity attributes”, but not that it’s not defining schemas for the other parts of the protocol. I’ve been clear on the other thread that we shouldn’t be defining a user schema, for attachment either to the access token or non-identifier items returned directly as plaintext or in assertions. 

By my read, we are fully within our charter to define schemas for authorization requests and responses, including both coarse and fine-grained access. I understand that it’s your stance that we should simply re-use OAuth 2’s “scope” parameter for this, and I disagree with that. My proposed approach is to have a place within the GNAP protocol to plug in a “scope” value if you have one, and for the AS to interpret it, but not to have that value always be a “scope”. 

> The AS may use strings to define a different schema, such as which claims to return from a userinfo endpoint.
> 

Exactly. A scope is a string that represents access to something controlled by the AS. The object also represents that same thing, but in multiple, more specific dimensions. 

>  I'm going to separate the my other responses into separate threads as they are different topics.
> 
> /Dick
> 
> ᐧ

 - Justin

---

From: Justin Richer <[email-masked]>
Date: Fri, 10 Jul 2020 16:09:36 -0400

> On Jul 10, 2020, at 2:15 PM, Dick Hardt <[email-masked]> wrote:
> 
> 
> inline ... 
> 
> On Thu, Jul 9, 2020 at 5:44 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> Now for case (1), how would the client know if it wants to request the user’s profile info or not, since it doesn’t know who the user is?
> 
> But the client could know who the user is. The client may have used a different AS to authenticate the user.

In these cases, the client is not going to be requesting identity information from the AS to log the user in, so it’s not relevant to the use case. The client will have an opportunity to push that information to the AS.

> The User may have self identified to the client. The client may have a cookie saying who the user was and the user said that was them. While the latter cases are really a strong hint, they are likely right most of the time and can lead to a user experience basde on that hint

In these cases, the AS might be able to guess if the client has info about the user already, but probably not. And the assumptions fall apart if it’s in fact a different user that ends up logging in, which is of course possible (the hint you gave doesn’t match the identity of the current user after the AS validates them). This possibility leads to clients always asking for everything every time and the server providing everything every time. That’s a pattern I think we should avoid in an ultimate solution — but ultimately, I don’t think that this kind of protocol decision is inside of GNAP.

>  
> And the AS won’t know if client is going to want the profile info, since the AS won’t know if the client has the user’s info or not. Sure, the AS might have seen that client and that user combo previously, but it doesn’t know if the client needs an update.
> 
> The client can share with the AS the user it knows or thinks it is dealing with, which could let the AS respond if the information was new. This could be the case for an AS that is providing claims, but not authentication, and could happen silently. The user would only interact if the user information had changed, and the client wanted the updated information.
>  

See above.

See above.

> For example, the client could be stateless about user information, so it knows it is ALWAYS in state 1.

A stateless client would need to fetch appropriate user information every time, then. But that’s an optimization for a very specific case.

> I know what it is. Per above, GNAP lets us support a wider set of use cases. Why limit ourselves to what OIDC supported?

We aren’t limiting the protocol, but instead limiting the scope of what we define internal to the GNAP protocol. There’s a lot of room for innovation on top of it.

>  
> In the first stage, you push the bare minimum of what you need to get the user known to the client. In the second stage, the client uses its access token to call an API to get whatever else it needs to know about the user.
> 
> From a privacy perspective in non-enterprise use cases, I think the user should give consent to any updated personal information to a client. In general, the client should not be able to get the latest information about a user whenever it wants.

This is about the rights associated with the access token, then. And an access token doesn’t have to keep working if the AS has a policy that says it won’t. The AS/RS could easily decide that a particular access token will only return data that hasn’t been changed. Maybe it stops working after the data changes, or it just returns old data, or any number of things. This is for the AS/RS to decide and this is pretty standard interpretation of the token, nothing special here because we’re dealing with identity.

 — Justin

---

From: Justin Richer <[email-masked]>
Date: Fri, 10 Jul 2020 16:09:40 -0400

It seems to be pretty clear that you and I are interpreting the charter text differently, so I’d like to hear what the chairs think the best approach will be when we finally get to defining what’s included in GNAP. This should perhaps be a discussion point for the group in the upcoming meeting. Until then, I can hopefully expand on what I interpret.

The charter uses the term “identity information within the protocol including existing identifiers ... and assertions” and not “claims”, which I think is more precise and that GNAP should use language instead of “claims” for this reason. I think the XYZ use of the term “claims” is a mistake and it should change because it’s confusing.

The only time “claims” are mentioned in the charter is in the section about not making assumptions about the client and having a protocol “allowing for … Approval of AS attestation to identifiers and other identity claims”. To me, this does not say that the protocol should have room for more advanced identity stuff, not that GNAP should specify how it’s requested or returned.

There are use cases for getting signed assertions back from the AS as well, and so the protocol should allow for that. While assertions can often contain non-identifier claims, it’s not up to GNAP to define what those claims are, how they’re requested, or how they’re returned. There are also lots of valid use cases for the client requesting a specific set of non-identifier claims about the user. The question is, how much of that detail should we be solving directly here in GNAP? I think it’s pretty clear that the answer is “not much at all”.

My original XYZ proposal didn’t have any identity information in it, much like OAuth 2. After talking with Aaron and a few others, I was convinced that we could have a very small delta to let the client know who the user is. When writing the charter text, that’s what I originally had in mind by the “identity” language throughout. Several people spoke up and said that they would like space left to return signed assertions as well, and there seemed to be enough support to have that as an option in the charter so it was added. What I did not see support for, and in fact saw explicit pushback against, was defining ways to return additional user information in the GNAP response, at least as defined internally by GNAP. That seems to be what you’re arguing for doing here.

I think there will be room, and need, for a protocol on top of GNAP to define identity schemas, assertions, session handling, authentication contexts, and identity-based APIs in a standard way. It’s my understanding that all of this is outside of GNAP’s core focus, but that GNAP should keep this kind of work in mind in its design. So that, for instance, we don’t accidentally design a protocol that prevents an AS from tying both identity information and 

I realize that Xauth had non-identifier claims since early drafts, and I disagree with their inclusion. I think that the group is going to have to decide how far down this identity road we really want to go with GNAP, and I don’t think that’s an answered question yet. 

 — Justin

> On Jul 10, 2020, at 2:33 PM, Dick Hardt <[email-masked]> wrote:
> 
> 1) Both XYZ and XAuth use the term claims, rather than identifiers. "A claim is a statement that one subject, such as a person or organization, makes about itself or another subject."[1]. A claim is clearly more than an identifier.
> 
> 2) XAuth has had non-identifier claims in the examples since -01 (name, photo).
> 
> 3) The charter does not state that ONLY identifiers will be returned, identifiers are one of the examples, as are OIDC ID Tokens, SAML assertions, and Verifiable Credentials. All of these often bind non-identifiers to one or more identifiers.  
> 
> [1] https://en.wikipedia.org/wiki/Claims-based_identity#Identity_and_claims <https://en.wikipedia.org/wiki/Claims-based_identity#Identity_and_claims>
>

---

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 13:32:28 -0700

My interpretation is pretty straight forward:

1) GNAP should be able to return ANY claim, not just identifiers.

2) GNAP should not define any claim schema, contrary to what XZY does

The pushback in the group, which I am pretty familiar with having been a
BoF chair at the time, and I personally worked to resolve, was that
"identity" was too broad, and there was concern the scope included defining
new schemas. The revised charter made that clarification. I don't recall
ANY discussion that GNAP should only return identifiers. The charter reads
that identifiers are included in what could be returned.

If you did not agree with non-identifier claims being in XAuth since the
beginning, why did you not say anything? I have not agreed with XYZ
defining a new schema, and have voiced that concern a number of times.

The above reasons are why I was surprised to suddenly learn your position.

On Fri, Jul 10, 2020 at 1:09 PM Justin Richer <[email-masked]> wrote:

> It seems to be pretty clear that you and I are interpreting the charter
> text differently, so I’d like to hear what the chairs think the best
> approach will be when we finally get to defining what’s included in GNAP.
> This should perhaps be a discussion point for the group in the upcoming
> meeting. Until then, I can hopefully expand on what I interpret.
>
> The charter uses the term “identity information within the protocol
> including existing identifiers ... and assertions” and not “claims”, which
> I think is more precise and that GNAP should use language instead of
> “claims” for this reason. I think the XYZ use of the term “claims” is a
> mistake and it should change because it’s confusing.
>
> The only time “claims” are mentioned in the charter is in the section
> about not making assumptions about the client and having a protocol
> “allowing for … Approval of AS attestation to identifiers and other
> identity claims”. To me, this does not say that the protocol should have
> room for more advanced identity stuff, not that GNAP should specify how
> it’s requested or returned.
>
> There are use cases for getting signed assertions back from the AS as
> well, and so the protocol should allow for that. While assertions can often
> contain non-identifier claims, it’s not up to GNAP to define what those
> claims are, how they’re requested, or how they’re returned. There are also
> lots of valid use cases for the client requesting a specific set of
> non-identifier claims about the user. The question is, how much of that
> detail should we be solving directly here in GNAP? I think it’s pretty
> clear that the answer is “not much at all”.
>
> My original XYZ proposal didn’t have any identity information in it, much
> like OAuth 2. After talking with Aaron and a few others, I was convinced
> that we could have a very small delta to let the client know who the user
> is. When writing the charter text, that’s what I originally had in mind by
> the “identity” language throughout. Several people spoke up and said that
> they would like space left to return signed assertions as well, and there
> seemed to be enough support to have that as an option in the charter so it
> was added. What I did not see support for, and in fact saw explicit
> pushback against, was defining ways to return additional user information
> in the GNAP response, at least as defined internally by GNAP. That seems to
> be what you’re arguing for doing here.
>
> I think there will be room, and need, for a protocol on top of GNAP to
> define identity schemas, assertions, session handling, authentication
> contexts, and identity-based APIs in a standard way. It’s my understanding
> that all of this is outside of GNAP’s core focus, but that GNAP should keep
> this kind of work in mind in its design. So that, for instance, we don’t
> accidentally design a protocol that prevents an AS from tying both identity
> information and
>
> I realize that Xauth had non-identifier claims since early drafts, and I
> disagree with their inclusion. I think that the group is going to have to
> decide how far down this identity road we really want to go with GNAP, and
> I don’t think that’s an answered question yet.
>
>  — Justin
>
>
> https://en.wikipedia.org/wiki/Claims-based_identity#Identity_and_claims
>
>> since I helped write the section of the charter that you quoted below. A
>> big reason that I chose that wording was to support this use case but not
>> to go in depth with an identity protocol, which I never really wanted us to
>> do. However, it seems as soon as “identity” was brought up previously,
>> people immediately jumped into talking about a full stack of user
>> attributes and profile information. That wasn’t my intent in talking about
>> identity, and I don’t think it’s something GNAP ought to do, at least not
>> on its own.
>>
>> signed assertions as well, so I made sure that was enumerated for those who
>> want to do such work. And I think it makes sense for us to provide a way to

---

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 13:53:37 -0700

Now that you are saying that the scope string is short hand for the object,
the polymorphism makes sense. There is only one type in the array, and a
string is shorthand for it. In this thread, you have talked about them
being separate things.

I just reread XYZ-08 section on resources, and there is no mention of
polymorphism, or an example of it. Given your comments that XAuth should
support both scopes and RAR, and that your proposed schema was based on
RAR, that scopes and RAR objects were different things.

Now it is clear that you are proposing that GNAP have a brand new schema
for authorization queries. And on closer inspection of your examples in
XYZ, there is no "type" in the property in the object.

So now I see the choice being:

A) reinvent a new, GNAP specific schema for requesting access to resources
(XYZ)
B) reuse the RAR and OAuth scope schemas (XAuth)

If and when another resource requesting schemas is developed, you propose
that it be a new, top level object. I'm proposing it be a new type in the
authorizations container.

Have I captured this accurately?

/Dick

On Fri, Jul 10, 2020 at 1:09 PM Justin Richer <[email-masked]> wrote:

> The context is really not the same though, as you actually  point out
> here, and calling one style of type checking “opaque” vs. “explicit” is
> stylistic and not a helpful comparison. I’m not surprised to find that you
> think the way you did it is easier, especially given the disconnect we have
> of what the components of the array represent. I started with some of the
> type-field-based structures in early versions of XYZ and moved away from
> them after having bad experiences with building it. There are still a few
> parts of the XYZ protocol that have that style (the “user” section, for
> example) that I think need to be changed. I think that the data-type based
> style of polymorphism, coupled with using the left-hand-side value of
> object members to indicate type or identifier, is significantly simpler in
> design and implementation.
>
> Instead, I realized that we could get a cleaner protocol and better
> underlying code by dispatching based on the type within the protocol
> itself. I’ve gotten comments from a number of implementers that they like
> this design aspect, and I really like it myself.
>
>
>
>>
>>
> The string is, semantically, a shorthand for the object. That’s what I’ve
> been saying from the beginning, and I’ve put into several examples so far.
> There are two ways to add rights to an access token resulting from the
> request. So:
>
> {
>   “resources”: [ “photo” ]
> }
>
>      “locations”: [ “https://server/photoapi/“ ]
>    }
> }
>
> In this straw man, if the client wants write access to the API, it needs
> to use the object-style request to do so.
>
> It’s up to the AS, or really the API that it’s protecting, to figure out
> what that expansion really looks like, and how much of the more complex
> policy to expose. My example of processing only string-based resource
> requests was for the case where the AS only gives the shorthand version,
> and doesn’t allow detailed access into its protection policies. It’s not a
> different kind of request, it’s a shorthand, much like passing an
> identifier in lieu of a key to identify the client software instance making
> the call.
>
> But really, the point is that in both cases the string and the object *both
> represent the same kind of thing*: *a piece of access rights that the
> client is requesting at the AS which gets put into the access token.*
> Thus, having them together in a single array and processing them together
> makes sense to me. If you are thinking of strings and objects as completely
> different from each other,  you’d expect them to be handled separately, but
> I don’t think they are actually different because they both represent a
> view of the same underlying thing.
>
>
>
> In polymorphic APIs, it makes the code cleaner to pass a singular item
> when the API takes an array, or the API takes a string for the common
> property of the object which is the parameter.
>
>
> Yes, those are two examples of why it can be good. There are other reasons
> to apply it, like having an array with differently typed items that
> represent the same kind of thing underneath.
>
> All of these are great examples of why object-type-based polymorphism is a
> good and powerful thing, and that’s the approach I’m saying we should use
> within the GNAP protocol. I would argue that the last one isn’t
> polymorphism so much as a default based on a null value (often taken as a
> special class of an “object” value anyway), but that’s splitting hairs.
>
>
>
>>
>>
>>
>>>
>>>
> Both would represent “things that the client wants back in the access
> token”, and therefore the AS would need to differentiate. In that case I
> think it actually makes a lot more sense for the AS to define a more rich
> mechanism to request user information. In XYZ it could look like this:
>
> {
>    “resources”: [
>      {
>         “type”: “oidc_userinfo”,
> But defining the details of that kind of query is clearly outside the
> scope of GNAP (see below), and I think better suited to an identity
> protocol built on top of GNAP.
>
>
>
>
>>
>>
>>
>>>
>> And I’m saying that additional “schemas” for requesting information
>> should be defined separately from the GNAP schema. We disagree on this
>> topic and we’re repeating ourselves.
>>
>
> The charter is pretty clear that GNAP should not define schemas, so I
> don't know what you mean by the "the GNAP schema"
>
>
>
> That’s not true. The charter is clear that "nor is the group chartered to
> develop schemas for user information, profiles, or other identity
> attributes”, but not that it’s not defining schemas for the other parts of
> the protocol. I’ve been clear on the other thread that we shouldn’t be
> defining a user schema, for attachment either to the access token or
> non-identifier items returned directly as plaintext or in assertions.
>
> By my read, we are fully within our charter to define schemas for
> authorization requests and responses, including both coarse and
> fine-grained access. I understand that it’s your stance that we should
> simply re-use OAuth 2’s “scope” parameter for this, and I disagree with
> that. My proposed approach is to have a place within the GNAP protocol to
> plug in a “scope” value if you have one, and for the AS to interpret it,
> but not to have that value always be a “scope”.
>
>
>>
>>
>>>
>> How is that any different? I’m confused as to why you think it’s
>> important to call this item a “scope” so that you “know what it is”, but
>> then you’re OK with “scope” meaning literally anything.
>>
>
> Exactly. A scope is a string that represents access to something
> controlled by the AS. The object also represents that same thing, but in
> multiple, more specific dimensions.
>

---

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 14:00:00 -0700

It looks to me that our different views of what is in scope for GNAP are
the differences below.

Per the subject line, I'm looking at how the client acquires claims about
the user. You don't think that is in scope, and that a different layer will
solve that.

I think we should learn from OIDC being on top of OAuth, and GNAP should be
able return ANY claim, not just identifier claims. There are use cases that
may be difficult to support if we do not have that functionality in scope,
such as some of the ones I list below, and it seems pretty straightforward
to support ANY claim if we are supporting identifiers.

/Dick

On Fri, Jul 10, 2020 at 1:09 PM Justin Richer <[email-masked]> wrote:

> different AS to authenticate the user.
>
>
> In these cases, the client is not going to be requesting identity
> information from the AS to log the user in, so it’s not relevant to the use
> case. The client will have an opportunity to push that information to the
> AS.
>
> The User may have self identified to the client. The client may have a
> cookie saying who the user was and the user said that was them. While the
> latter cases are really a strong hint, they are likely right most of the
> time and can lead to a user experience basde on that hint
>
>
> In these cases, the AS might be able to guess if the client has info about
> the user already, but probably not. And the assumptions fall apart if it’s
> in fact a different user that ends up logging in, which is of course
> possible (the hint you gave doesn’t match the identity of the current user
> after the AS validates them). This possibility leads to clients always
> asking for everything every time and the server providing everything every
> time. That’s a pattern I think we should avoid in an ultimate solution —
> but ultimately, I don’t think that this kind of protocol decision is inside
> of GNAP.
>
>
>
> A stateless client would need to fetch appropriate user information every
> time, then. But that’s an optimization for a very specific case.
>
>
>
>>
> We aren’t limiting the protocol, but instead limiting the scope of what we
> define internal to the GNAP protocol. There’s a lot of room for innovation
> on top of it.
>
>
>
> This is about the rights associated with the access token, then. And an
> access token doesn’t have to keep working if the AS has a policy that says
> it won’t. The AS/RS could easily decide that a particular access token will
> only return data that hasn’t been changed. Maybe it stops working after the
> data changes, or it just returns old data, or any number of things. This is
> for the AS/RS to decide and this is pretty standard interpretation of the
> token, nothing special here because we’re dealing with identity.
>
>  — Justin
>
>
> /Dick
> ᐧ
>
>
>

---

From: Yaron Sheffer <[email-masked]>
Date: Sat, 11 Jul 2020 21:11:08 +0300

As far as I can see JSON Schema is the clear winner, from an industry point of view. There's lots of implementations on their web site, although sadly with varying support for different versions. It's actually an IETF miss that this technology is not being standardized here yet. Tim is obviously the expert here, but JSON Schema has the "running code".

The JSON Schema folks tried to bring it into IETF and didn't like the reaction they received (though I looked at the mail archive and it was nothing out of the ordinary). So they took a step back. I talked to them recently and tried to have them re-engage, they may be ready to do that now.

Thanks,
	Yaron

On 7/7/20, 08:31, "Txauth on behalf of Benjamin Kaduk" <[email-masked] on behalf of [email-masked]> wrote:

    -Ben

---

From: Justin Richer <[email-masked]>
Date: Mon, 13 Jul 2020 09:52:20 -0400

An important data-point: RAR is a back-port of the functionality in XYZ to OAuth 2, and Torsten and I intended from the outset that the internal structure be kept in synch. In an ideal world, GNAP’s request data structure would be finished already and RAR would refer to it.

So I am actually proposing:

C) GNAP create a GNAP-specific schema for requesting resources (that allows expression in objects and strings), and that this be developed in concert with RAR in OAuth2 so that data structures that fit into a RAR query will also fit into a GNAP query.

The GNAP query should be a proper superset of OAuth scope and OAuth RAR.

Similarly how an OAuth “scope” string should fit into a GNAP query, an OAuth “RAR” object should fit into a GNAP query. But that doesn’t mean that a GNAP query has to live with all of the limitations and contexts of those. For example, the string values in a GNAP query should be allowed to include spaces. OAuth scopes can’t have spaces because of an unfortunate limitation caused by the encoding in a query parameter, and they also can’t have non-ASCII characters without being encoded. We shouldn’t inherit those limitations here, and any JSON String should be allowed. Similarly, RAR objects need to make sense in the context of the OAuth “resource” parameter, but that constraints doesn’t apply to GNAP.

And yes, if a new query language is developed, I am saying it should be in a top-level parameter, as we should not be placing limitations on what that query language can affect. The GNAP language for requesting things in the access token should be scoped (pun intended) exactly to the access token(s) that it creates. A new query language could affect non-access-token responses as well, and that should be allowed. Combining these is obviously going to be tricky, but that happens any time you cross query languages. Putting them all into a lower-level bucket doesn’t make that go away.

 — Justin

> On Jul 10, 2020, at 4:53 PM, Dick Hardt <[email-masked]> wrote:
> 
> Now that you are saying that the scope string is short hand for the object, the polymorphism makes sense. There is only one type in the array, and a string is shorthand for it. In this thread, you have talked about them being separate things.
> 
> I just reread XYZ-08 section on resources, and there is no mention of polymorphism, or an example of it. Given your comments that XAuth should support both scopes and RAR, and that your proposed schema was based on RAR, that scopes and RAR objects were different things.
> 
> Now it is clear that you are proposing that GNAP have a brand new schema for authorization queries. And on closer inspection of your examples in XYZ, there is no "type" in the property in the object.
> 
> A) reinvent a new, GNAP specific schema for requesting access to resources (XYZ)
> If and when another resource requesting schemas is developed, you propose that it be a new, top level object. I'm proposing it be a new type in the authorizations container.
> 
> On Fri, Jul 10, 2020 at 1:09 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> 
> 
>> On Jul 10, 2020, at 1:39 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> 
>>

---

From: Justin Richer <[email-masked]>
Date: Mon, 13 Jul 2020 10:16:39 -0400

One thing I think we should learn from OIDC is that returning claims from an API, and not just an assertion or direct response, is a powerful and useful pattern. We have an opportunity to separate these cleanly, where OIDC didn’t have the opportunity in defining the “claims” request parameter.

As an alternative to the current XYZ and XAuth syntaxes, over the weekend I’ve been playing with something that would look like this strawman in the request:

{
   subject: {
      id: [ “account”, “email”, “iss-sub”],
      assertion: [ “odic_id_token”, “verifiable_credential”, “saml" ]
   }
}

This request says that I’d like some subset of these identifiers (as plain text in the response) and some subset of signed assertions in the given formats. Each one would have an associated space in the return. I’m not picturing that the “id” field values would affect the contents of the assertions: so I could ask for an email address identifier but get back an ID token that had only the subject identifier. Maybe that’s not the right model? But it’s at least simple and deterministic this way, and it’s something to play with.

Note: The “id” names are taken from https://tools.ietf.org/id/draft-ietf-secevent-subject-identifiers-05.html <https://tools.ietf.org/id/draft-ietf-secevent-subject-identifiers-05.html>, the “assertion” names are made up as I didn’t see a source that collected them. If you wanted specific bundles of claims about the user from a UserInfoEndpoint, for example, you’d have something like:

{
   subject: {
      id: [ “account”, “email”, “iss-sub”],
      assertion: [ “odic_id_token”, “verifiable_credential”, “saml" ]
   },
   resources: [{
       type: “userinfo”,
       datatypes: [ “openid”, “profile”, “phone”, “email” ]
  }]
}

This is an example for a specific kind of resource, and I don’t think that GNAP should define the “userinfo” schema here, or the datatype values therein. That should be work outside of GNAP, probably for the OIDF.

This approach is extensible in several ways, each of them for a specific reason that I think is clear:

 - new values in the “id” field to give new identifiers
 - new values in the “assertion” field to give new assertion formats
 - new fields under the “subject” heading 
 - new resource types besides “userinfo” (like “scim-v1” or “facebook-profile” for instance)
 - new datatypes within the “userinfo” resource type
 - new top-level request parameters

As per the other thread, if you wanted to use the OIDC query language, you’d package it separately as a top-level request parameter since it can include both the ID token response and the access token response and we shouldn’t be encouraging mixing these things together.

 — Justin

> On Jul 10, 2020, at 5:00 PM, Dick Hardt <[email-masked]> wrote:
> 
> It looks to me that our different views of what is in scope for GNAP are the differences below.
> 
> Per the subject line, I'm looking at how the client acquires claims about the user. You don't think that is in scope, and that a different layer will solve that.
> 
> I think we should learn from OIDC being on top of OAuth, and GNAP should be able return ANY claim, not just identifier claims. There are use cases that may be difficult to support if we do not have that functionality in scope, such as some of the ones I list below, and it seems pretty straightforward to support ANY claim if we are supporting identifiers.
> 
> /Dick
> 
> 
>> On Jul 10, 2020, at 2:15 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> 
>> inline ... 
>>

---

From: Dick Hardt <[email-masked]>
Date: Mon, 13 Jul 2020 11:12:06 -0700

I agree that an API to return claims is useful. I think we have agreed on
that.

Using the SubjectIdentifiers schema is another schema that would be useful
for GNAP to support.

I disagree that GNAP should be limited to identifier claims.

ᐧ

On Mon, Jul 13, 2020 at 7:16 AM Justin Richer <[email-masked]> wrote:

> One thing I think we should learn from OIDC is that returning claims from
> an API, and not just an assertion or direct response, is a powerful and
> useful pattern. We have an opportunity to separate these cleanly, where
> OIDC didn’t have the opportunity in defining the “claims” request parameter.
>
> As an alternative to the current XYZ and XAuth syntaxes, over the weekend
> I’ve been playing with something that would look like this strawman in the
> request:
>
>
> {
>    subject: {
> This request says that I’d like some subset of these identifiers (as plain
> text in the response) and some subset of signed assertions in the given
> formats. Each one would have an associated space in the return. I’m not
> picturing that the “id” field values would affect the contents of the
> assertions: so I could ask for an email address identifier but get back an
> ID token that had only the subject identifier. Maybe that’s not the right
> model? But it’s at least simple and deterministic this way, and it’s
> something to play with.
>
> Note: The “id” names are taken from
> https://tools.ietf.org/id/draft-ietf-secevent-subject-identifiers-05.html,
> the “assertion” names are made up as I didn’t see a source that collected
> them. If you wanted specific bundles of claims about the user from a
> UserInfoEndpoint, for example, you’d have something like:
>
> {
>    subject: {
> This is an example for a specific kind of resource, and I don’t think that
> GNAP should define the “userinfo” schema here, or the datatype values
> therein. That should be work outside of GNAP, probably for the OIDF.
>
> As per the other thread, if you wanted to use the OIDC query language,
> you’d package it separately as a top-level request parameter since it can
> include both the ID token response and the access token response and we
> shouldn’t be encouraging mixing these things together.
>
>  — Justin
>
> I think we should learn from OIDC being on top of OAuth, and GNAP should
> be able return ANY claim, not just identifier claims. There are use cases
> that may be difficult to support if we do not have that functionality in
> scope, such as some of the ones I list below, and it seems pretty
> straightforward to support ANY claim if we are supporting identifiers.
>
> /Dick
>
>
>> In these cases, the AS might be able to guess if the client has info
>> about the user already, but probably not. And the assumptions fall apart if
>> it’s in fact a different user that ends up logging in, which is of course
>> The client can share with the AS the user it knows or thinks it is
>> dealing with, which could let the AS respond if the information was new.
>> This could be the case for an AS that is providing claims, but not
>> authentication, and could happen silently. The user would only interact if
>> the user information had changed, and the client wanted the updated
>> information.
>>
>>
>>
>> See above.
>>
>>
>>> or not because it doesn’t know who the user is yet. If the AS can provide
>>> some time of updated stamp to the client, the client can pull the new info
>>> when it needs it.
>>>
>>
>> See above.
>>
>>
>> See above.
>>
>>
>>
>>>
>>> inline with the main request/response, you end up in a situation where the
>>> client always requests everything and the server always provides
>>> everything, since you can’t be sure you’re not in situation (1) or (2)
>>> ahead of time.
>>>
>>
>> We aren’t limiting the protocol, but instead limiting the scope of what
>> we define internal to the GNAP protocol. There’s a lot of room for
>> innovation on top of it.
>>
>>
>>
>>> the user known to the client. In the second stage, the client uses its
>>> access token to call an API to get whatever else it needs to know about the
>>> user.
>>>
>>

---

From: Justin Richer <[email-masked]>
Date: Mon, 13 Jul 2020 14:51:22 -0400

I am saying that GNAP, it its definition within this working group, should be limited to identifier claims. Other claims can come from other protocols properly layered on top of GNAP. GNAP shouldn’t stop them from being built, but in my opinion we shouldn’t be defining those here. See the discussion below on the extensibility avenues of this approach.

 — Justin

> On Jul 13, 2020, at 2:12 PM, Dick Hardt <[email-masked]> wrote:
> 
> I agree that an API to return claims is useful. I think we have agreed on that. 
> 
> Using the SubjectIdentifiers schema is another schema that would be useful for GNAP to support. 
> 
> On Mon, Jul 13, 2020 at 7:16 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jul 10, 2020, at 5:00 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>>

---

From: Justin Richer <[email-masked]>
Date: Mon, 13 Jul 2020 15:31:16 -0400

A quick note, as my choice of language below seems to have been confusing. First there is a typo, where the word “it” should have been “in” to read:

> I am saying that GNAP, in its definition within this working group, should be limited to identifier claims.

And second, there seems to be confusion around whether I’m trying to argue about the scope “allowed” by the charter by saying “its definition within this working group” here. 

To be clear, we as the working group are defining GNAP the protocol. It has not yet been defined, and that’s why were all here. The charter doesn’t define it. The input specs don’t define it. The working group defines it, and my stance as a contributor to this WG is that we should focus on a delegation protocol with some basic identifier query support and leave the full fledged identity protocol to different work. 

We’ve already got our hands full here without taking all of that on, especially since I do believe we need to build GNAP in such a way as to facilitate its extension in several known directions, including a full identity protocol. If we do things right here, we can see GNAP as the basis of a large number of things out there in the world. 

So my stance in what we should do, as we define GNAP as a protocol, is focus on this one, limited slice of the identity space and not spiral into others.

 — Justin

> On Jul 13, 2020, at 2:51 PM, Justin Richer <[email-masked]> wrote:
> 
>> On Jul 13, 2020, at 2:12 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>>

---

From: Denis <[email-masked]>
Date: Mon, 13 Jul 2020 21:36:14 +0200

Justin,

Since the "sub" claim has been "diverted" from it original semantics, we 
will need to define four types of identifiers for a user,whether it is:

    (1) temporarily unique,
    (2) unique to the resource server,
    (3) unique to the authorization server (this was the original
    semantics of the "sub" claim) or
    (4) globally unique (e.g. a distinguished name or an email address).

In terms of privacy, for each of them, the consequences are quite different.

Denis

> I am saying that GNAP, it its definition within this working group, 
> should be limited to identifier claims. Other claims can come from 
> other protocols properly layered on top of GNAP. GNAP shouldn’t stop 
> them from being built, but in my opinion we shouldn’t be defining 
> those here. See the discussion below on the extensibility avenues of 
> this approach.
>
>  — Justin
>
>>     One thing I think we should learn from OIDC is that returning
>>     claims from an API, and not just an assertion or direct response,
>>     is a powerful and useful pattern. We have an opportunity to
>>     separate these cleanly, where OIDC didn’t have the opportunity in
>>     defining the “claims” request parameter.
>>
>>     As an alternative to the current XYZ and XAuth syntaxes, over the
>>     weekend I’ve been playing with something that would look like
>>     this strawman in the request:
>>
>>
>>         {
>>            subject: {
>>     This request says that I’d like some subset of these identifiers
>>     (as plain text in the response) and some subset of signed
>>     assertions in the given formats. Each one would have an
>>     associated space in the return. I’m not picturing that the “id”
>>     field values would affect the contents of the assertions: so I
>>     could ask for an email address identifier but get back an ID
>>     token that had only the subject identifier. Maybe that’s not the
>>     right model? But it’s at least simple and deterministic this way,
>>     and it’s something to play with.
>>
>>     the “assertion” names are made up as I didn’t see a source that
>>     collected them. If you wanted specific bundles of claims about
>>     the user from a UserInfoEndpoint, for example, you’d have
>>     something like:
>>
>>         {
>>            subject: {
>>     This is an example for a specific kind of resource, and I don’t
>>     think that GNAP should define the “userinfo” schema here, or the
>>     datatype values therein. That should be work outside of GNAP,
>>     probably for the OIDF.
>>
>>     As per the other thread, if you wanted to use the OIDC query
>>     language, you’d package it separately as a top-level request
>>     parameter since it can include both the ID token response and the
>>     access token response and we shouldn’t be encouraging mixing
>>     these things together.
>>
>>      — Justin
>>
>>>     Per the subject line, I'm looking at how the client acquires
>>>     claims about the user. You don't think that is in scope, and
>>>     that a different layer will solve that.
>>>
>>>     I think we should learn from OIDC being on top of OAuth, and
>>>     GNAP should be able return ANY claim, not just identifier
>>>     claims. There are use cases that may be difficult to support if
>>>     we do not have that functionality in scope, such as some of the
>>>     ones I list below, and it seems pretty straightforward to
>>>     support ANY claim if we are supporting identifiers.
>>>
>>>     /Dick
>>>
>>>
>>>>         On Jul 10, 2020, at 2:15 PM, Dick Hardt
>>>>         On Thu, Jul 9, 2020 at 5:44 PM Justin Richer
>>>>             Yes, the core idea is to not have to parse an assertion
>>>>             to get back the core authentication information, which
>>>>             consists of an identifier (iss/sub pair in OIDC, but
>>>>             could be a number of things). Sometimes the client is
>>>>             going to want the rest of the identity information,
>>>>             but If the user’s logged into the client before, the
>>>>             client has likely cached that info and probably won’t
>>>>             need it, and sending it would be a violation of privacy
>>>>             Now for case (1), how would the client know if it wants
>>>>             to request the user’s profile info or not, since it
>>>>             doesn’t know who the user is?
>>>>
>>>>
>>>>         But the client could know who the user is. The client may
>>>>         have used a different AS to authenticate the user.
>>>
>>>         In these cases, the client is not going to be requesting
>>>         identity information from the AS to log the user in, so it’s
>>>         not relevant to the use case. The client will have an
>>>         opportunity to push that information to the AS.
>>>
>>>>         The User may have self identified to the client. The client
>>>>         may have a cookie saying who the user was and the user said
>>>>         that was them. While the latter cases are really a strong
>>>>         hint, they are likely right most of the time and can lead
>>>>         to a user experience basde on that hint
>>>
>>>         In these cases, the AS might be able to guess if the client
>>>         has info about the user already, but probably not. And the
>>>         assumptions fall apart if it’s in fact a different user that
>>>         ends up logging in, which is of course possible (the hint
>>>         you gave doesn’t match the identity of the current user
>>>         after the AS validates them). This possibility leads to
>>>         clients always asking for everything every time and the
>>>         server providing everything every time. That’s a pattern I
>>>         think we should avoid in an ultimate solution — but
>>>         ultimately, I don’t think that this kind of protocol
>>>         decision is inside of GNAP.
>>>
>>>>             And the AS won’t know if client is going to want the
>>>>             profile info, since the AS won’t know if the client has
>>>>             the user’s info or not. Sure, the AS might have seen
>>>>             that client and that user combo previously, but it
>>>>             doesn’t know if the client needs an update.
>>>>
>>>>
>>>>         The client can share with the AS the user it knows or
>>>>         thinks it is dealing with, which could let the AS respond
>>>>         if the information was new. This could be the case for an
>>>>         AS that is providing claims, but not authentication, and
>>>>         could happen silently. The user would only interact if the
>>>>         user information had changed, and the client wanted the
>>>>         updated information.
>>>
>>>         See above.
>>>
>>>>
>>>>             And for (2), the client won’t know if the user’s info
>>>>             has been updated or not because it doesn’t know who the
>>>>             user is yet. If the AS can provide some time of updated
>>>>             stamp to the client, the client can pull the new info
>>>>             when it needs it.
>>>>
>>>>
>>>>         See above.
>>>
>>>         See above.
>>>
>>>>
>>>>             If you ignore both of these cases and put all the user
>>>>             information inline with the main request/response, you
>>>>             end up in a situation where the client always requests
>>>>             everything and the server always provides everything,
>>>>             since you can’t be sure you’re not in situation (1) or
>>>>             (2) ahead of time.
>>>>
>>>>
>>>>         For example, the client could be stateless about user
>>>>         information, so it knows it is ALWAYS in state 1.
>>>
>>>         A stateless client would need to fetch appropriate user
>>>         information every time, then. But that’s an optimization for
>>>         a very specific case.
>>>
>>>>
>>>>         I know what it is. Per above, GNAP lets us support a wider
>>>>         set of use cases. Why limit ourselves to what OIDC supported?
>>>
>>>         We aren’t limiting the protocol, but instead limiting the
>>>         scope of what we define internal to the GNAP protocol.
>>>         There’s a lot of room for innovation on top of it.
>>>
>>>>             In the first stage, you push the bare minimum of what
>>>>             you need to get the user known to the client. In the
>>>>             second stage, the client uses its access token to call
>>>>             an API to get whatever else it needs to know about the
>>>>             user.
>>>>
>>>>
>>>>         From a privacy perspective in non-enterprise use cases, I
>>>>         think the user should give consent to any updated personal
>>>>         information to a client. In general, the client should not
>>>>         be able to get the latest information about a user whenever
>>>>         it wants.
>>>
>>>         This is about the rights associated with the access token,
>>>         then. And an access token doesn’t have to keep working if
>>>         the AS has a policy that says it won’t. The AS/RS could
>>>         easily decide that a particular access token will only
>>>         return data that hasn’t been changed. Maybe it stops working
>>>         after the data changes, or it just returns old data, or any
>>>         number of things. This is for the AS/RS to decide and this
>>>         is pretty standard interpretation of the token, nothing
>>>         special here because we’re dealing with identity.
>>>
>>>          — Justin
>>>
>>>>         /Dick
>>>>         ᐧ
>>>
>>
>
>

---

From: Leif Johansson <[email-masked]>
Date: Tue, 14 Jul 2020 01:46:51 +0200

On 2020-07-10 22:09, Justin Richer wrote:
> It seems to be pretty clear that you and I are interpreting the charter text differently, so I’d like to hear what the chairs think the best approach will be when we finally get to defining what’s
> included in GNAP. This should perhaps be a discussion point for the group in the upcoming meeting. Until then, I can hopefully expand on what I interpret.

Mostly thats a question of WG consensus and not what the chairs think.

I suspect the WG is currently (like me) trying to catch up and isn't really in a position to
form consensus around anything.

We clearly need that to change. Forming consensus is what the IETF does and that can't
happen in the current environment.

Following the various threads that typically involve Justin and Dick I am scratching my
head trying to fathom how it is that two of the most experienced, intelligent and deeply
technical persons in the IETF are able to consistently and repeatedly missunderstand each
other so often.

Whatever the reason I am sure (again as chair) this *has to change* for the WG to get back
on target.

	Cheers Leif

---

From: Tom Jones <[email-masked]>
Date: Sat, 18 Jul 2020 09:56:28 -0700

I agree with Justin's comment " what we should do, as we define GNAP as a
protocol, is focus on this one, limited slice of the identity space and not
spiral into others."
The title "Authorization" should rule the purposes of this group above all
else.

The earlier statement that the client should know who the user is - is just
plain WRONG. The client should only know the information the user is
willing to share with the client.
It is now the law in California that the client cannot demand identity
information that is not required for a legitimate business purpose.
There are some clients that act as fiduciaries for the user (financial and
healthcare come to mind), but as a general rule the "client" is not to be
trusted by the user.
I understand most of the people on this list are paid by the client's of
the world, but you are still bound by the laws that apply to those clients.

Peace ..tom

On Mon, Jul 13, 2020 at 12:31 PM Justin Richer <[email-masked]> wrote:

> A quick note, as my choice of language below seems to have been confusing.
> First there is a typo, where the word “it” should have been “in” to read:
>
> I am saying that GNAP, *in* its definition within this working group,
> should be limited to identifier claims.
>
>
> And second, there seems to be confusion around whether I’m trying to argue
> about the scope “allowed” by the charter by saying “its definition within
> this working group” here.
>
> To be clear, we as the working group are *defining* GNAP the protocol. It
> has not yet been defined, and that’s why were all here. The charter doesn’t
> define it. The input specs don’t define it. The working group defines it,
> and my stance as a contributor to this WG is that we should focus on a
> delegation protocol with some basic identifier query support and leave the
> full fledged identity protocol to different work.
>
> We’ve already got our hands full here without taking all of that on,
> especially since I do believe we need to build GNAP in such a way as to
> facilitate its extension in several known directions, including a full
> identity protocol. If we do things right here, we can see GNAP as the basis
> of a large number of things out there in the world.
>
> So my stance in what we should do, as we define GNAP as a protocol, is
> focus on this one, limited slice of the identity space and not spiral into
> others.
>
>  — Justin
>
> I am saying that GNAP, it its definition within this working group, should
> be limited to identifier claims. Other claims can come from other protocols
> properly layered on top of GNAP. GNAP shouldn’t stop them from being built,
> but in my opinion we shouldn’t be defining those here. See the discussion
> below on the extensibility avenues of this approach.
>
>  — Justin
>
>> This request says that I’d like some subset of these identifiers (as
>> plain text in the response) and some subset of signed assertions in the
>> given formats. Each one would have an associated space in the return. I’m
>> not picturing that the “id” field values would affect the contents of the
>> This is an example for a specific kind of resource, and I don’t think
>> that GNAP should define the “userinfo” schema here, or the datatype values
>>>> And the AS won’t know if client is going to want the profile info,
>>>> since the AS won’t know if the client has the user’s info or not. Sure, the
>>>> AS might have seen that client and that user combo previously, but it
>>> A stateless client would need to fetch appropriate user information
>>> every time, then. But that’s an optimization for a very specific case.
>>>
>>>
>>>
>>>>

---

From: Dick Hardt <[email-masked]>
Date: Sat, 18 Jul 2020 17:58:16 -0700

Hey Tom

While I think defining claims is out of scope of the WG, I think enabling a
client to obtain claims about a user is in scope.
Would you consider authorization for the release of claims to be part of
the purpose of this WG?

I'm concerned about the XYZ shift to subject identifiers from claims, and
pushing claims to a higher layer, as it may indicate to developers that
they can ONLY ask for a user identifier.

When I think of a claim, I include any and all identifiers, but I also
include user attributes such as under-13, over-21,
student-at-an-accredited-school, resident of city/state/province/country.

GNAP can enable a client to ask for only the claims it needs, preserving
user privacy, and compliance with many privacy regulations.

Would you agree?

/Dick

On Sat, Jul 18, 2020 at 9:56 AM Tom Jones <[email-masked]>
wrote:

> The earlier statement that the client should know who the user is - is
> just plain WRONG. The client should only know the information the user is
>> A quick note, as my choice of language below seems to have been
>> confusing. First there is a typo, where the word “it” should have been “in”
>> to read:
>>
>> And second, there seems to be confusion around whether I’m trying to
>> argue about the scope “allowed” by the charter by saying “its definition
>> within this working group” here.
>>
>> To be clear, we as the working group are *defining* GNAP the protocol.
>> It has not yet been defined, and that’s why were all here. The charter
>> doesn’t define it. The input specs don’t define it. The working group
>> defines it, and my stance as a contributor to this WG is that we should
>> focus on a delegation protocol with some basic identifier query support and
>> leave the full fledged identity protocol to different work.
>>
>> should be limited to identifier claims. Other claims can come from other
>> protocols properly layered on top of GNAP. GNAP shouldn’t stop them from
>> being built, but in my opinion we shouldn’t be defining those here. See the
>> discussion below on the extensibility avenues of this approach.
>>
>>  — Justin
>>
>>> One thing I think we should learn from OIDC is that returning claims
>>> from an API, and not just an assertion or direct response, is a powerful
>>> and useful pattern. We have an opportunity to separate these cleanly, where
>>> weekend I’ve been playing with something that would look like this strawman
>>> in the request:
>>>
>>>
>>> {
>>>    subject: {
>>> Per the subject line, I'm looking at how the client acquires claims
>>> about the user. You don't think that is in scope, and that a different
>>> layer will solve that.
>>>
>>>>> client is going to want the rest of the identity information, but If the
>>>>> user’s logged into the client before, the client has likely cached that
>>>>> info and probably won’t need it, and sending it would be a violation of
>>>>> privacy principles.. The client would want the info pretty much just in
>>>>> these cases:
>>>>>
>>>> From a privacy perspective in non-enterprise use cases, I think the
>>>> user should give consent to any updated personal information to a client.
>>>> In general, the client should not be able to get the latest information
>>>> about a user whenever it wants.
>>>>
>>>>

---

From: Tom Jones <[email-masked]>
Date: Sat, 18 Jul 2020 19:34:30 -0700

absolutely, yes, tha az token can authorize any resource held by the
resource server.
The ONLY thing special about PII is the protection granted by the various
privacy laws.

As an aside, I don't find much in the current discussion that gives me a
warm feeling about privacy.
The stuff in the torsten tokens is about as anti-privacy an effort as
exists today.
Identity assurance does NOT need to be enabled by sending more and yet
again more PII.
Peace ..tom

On Sat, Jul 18, 2020 at 5:58 PM Dick Hardt <[email-masked]> wrote:

> Hey Tom
>
> While I think defining claims is out of scope of the WG, I think enabling
> a client to obtain claims about a user is in scope.
>> The title "Authorization" should rule the purposes of this group above
>> all else.
>>
>> There are some clients that act as fiduciaries for the user
>> (financial and healthcare come to mind), but as a general rule the "client"
>> is not to be trusted by the user.
>>>> I think we should learn from OIDC being on top of OAuth, and GNAP
>>>> should be able return ANY claim, not just identifier claims. There are use
>>>> cases that may be difficult to support if we do not have that functionality
>>>> in scope, such as some of the ones I list below, and it seems pretty
>>>>>> Now for case (1), how would the client know if it wants to request
>>>>>> the user’s profile info or not, since it doesn’t know who the user is?
>>>>>>
>>>>>
>>>>>> And for (2), the client won’t know if the user’s info has been
>>>>>> updated or not because it doesn’t know who the user is yet. If the AS can
>>>>>> provide some time of updated stamp to the client, the client can pull the
>>>>>> new info when it needs it.
>>>>>>
>>>>>
>>>>> See above.
>>>>>
>>>>>
>>>>> See above.
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>> We aren’t limiting the protocol, but instead limiting the scope of
>>>>> what we define internal to the GNAP protocol. There’s a lot of room for
>>>>> innovation on top of it.
>>>>>
>>>>>
>>>>>
>>>>> This is about the rights associated with the access token, then. And
>>>>> an access token doesn’t have to keep working if the AS has a policy that
>>>>> says it won’t. The AS/RS could easily decide that a particular access token
>>>>> will only return data that hasn’t been changed. Maybe it stops working
>>>>> after the data changes, or it just returns old data, or any number of
>>>>> things. This is for the AS/RS to decide and this is pretty standard
>>>>> interpretation of the token, nothing special here because we’re dealing
>>>>> with identity.
>>>>>
>>>>>  — Justin
>>>>>
>>>>>
>>>>> /Dick
>>>>> ᐧ
>>>>>
>>>>>
>>>>>
>>>>
>>> --
>>> Txauth mailing list
>>> [email-masked]

---

From: Dick Hardt <[email-masked]>
Date: Sun, 19 Jul 2020 13:45:14 -0700

Hi Tom

The proposal is that Client asks for a claim from the AS, the user consents
at the AS, and the AS directly releases the claim directly to the Client.
No access token. No resource server.

Simpler for Client and Grant Server (AS)

On Sat, Jul 18, 2020 at 7:34 PM Tom Jones <[email-masked]>
wrote:

>>> I agree with Justin's comment " what we should do, as we define GNAP as
>>> a protocol, is focus on this one, limited slice of the identity space and
>>> not spiral into others."
>>>>>> The User may have self identified to the client. The client may have
>>>>>> a cookie saying who the user was and the user said that was them. While the
>>>>>>> In the first stage, you push the bare minimum of what you need to
>>>>>>> get the user known to the client. In the second stage, the client uses its

---

From: Tom Jones <[email-masked]>
Date: Sun, 19 Jul 2020 21:13:32 -0700

Well, that might work for you. It won’t work for me. I put the as on the user’s phone. The source and sink of the data can switch roles on a millisecond basis. I will track your progress and adopt what I can.

..Tom's phone

> On Jul 19, 2020, at 1:45 PM, Dick Hardt <[email-masked]> wrote:
> 
> 
> Hi Tom
> 
> The proposal is that Client asks for a claim from the AS, the user consents at the AS, and the AS directly releases the claim directly to the Client. No access token. No resource server. 
> 
>> On Sat, Jul 18, 2020 at 7:34 PM Tom Jones <[email-masked]> wrote:
>> absolutely, yes, tha az token can authorize any resource held by the resource server.
>> The ONLY thing special about PII is the protection granted by the various privacy laws.
>> 
>> As an aside, I don't find much in the current discussion that gives me a warm feeling about privacy.
>> The stuff in the torsten tokens is about as anti-privacy an effort as exists today.
>> Identity assurance does NOT need to be enabled by sending more and yet again more PII.
>> Peace ..tom
>> 
>> 
>>> While I think defining claims is out of scope of the WG, I think enabling a client to obtain claims about a user is in scope.
>>> Would you consider authorization for the release of claims to be part of the purpose of this WG?
>>> 
>>> I'm concerned about the XYZ shift to subject identifiers from claims, and pushing claims to a higher layer, as it may indicate to developers that they can ONLY ask for a user identifier. 
>>> 
>>> When I think of a claim, I include any and all identifiers, but I also include user attributes such as under-13, over-21, student-at-an-accredited-school, resident of city/state/province/country.
>>> 
>>> GNAP can enable a client to ask for only the claims it needs, preserving user privacy, and compliance with many privacy regulations.
>>> 
>>> Would you agree?
>>> 
>>> /Dick
>>> 
>>> 
>>> 
>>> 
>>>> On Sat, Jul 18, 2020 at 9:56 AM Tom Jones <[email-masked]> wrote:
>>>> I agree with Justin's comment " what we should do, as we define GNAP as a protocol, is focus on this one, limited slice of the identity space and not spiral into others."
>>>> The title "Authorization" should rule the purposes of this group above all else.
>>>> 
>>>> The earlier statement that the client should know who the user is - is just plain WRONG. The client should only know the information the user is willing to share with the client.
>>>> It is now the law in California that the client cannot demand identity information that is not required for a legitimate business purpose.
>>>> There are some clients that act as fiduciaries for the user (financial and healthcare come to mind), but as a general rule the "client" is not to be trusted by the user.
>>>> I understand most of the people on this list are paid by the client's of the world, but you are still bound by the laws that apply to those clients.
>>>> 
>>>> Peace ..tom
>>>> 
>>>> 
>>>>>>>> Note: The “id” names are taken from https://tools.ietf.org/id/draft-ietf-secevent-subject-identifiers-05.html, the “assertion” names are made up as I didn’t see a source that collected them. If you wanted specific bundles of claims about the user from a UserInfoEndpoint, for example, you’d have something like:
>>>>>>>> 
>>>>>>>> {
>>>>>>>>    subject: {

---

From: Leif Johansson <[email-masked]>
Date: Mon, 20 Jul 2020 11:00:07 +0200

> Identity assurance does NOT need to be enabled by sending more and yet again more PII.

Taking off my chairs hat for a bit.

This thread has some very common missunderstanding about PII esp as it pertains
to legislation (eg in the EU).

Identifiers are just as much PII as claims containing things that are recognizably
personal (eg names etc).

The term PII stands for personal /identifiable/ information. Identifiers that
uniquely identify a data subject, regardless of what systems & resources may be
needed to de-reference those identifiers are PII - at least in the eyes of GDPR.

	Cheers Leif

---

From: Dick Hardt <[email-masked]>
Date: Mon, 20 Jul 2020 12:30:14 -0700

Curious: How are you envisioning the client communicates to the AS if it is
on the User's phone?
ᐧ

On Sun, Jul 19, 2020 at 9:13 PM Tom Jones <[email-masked]>
wrote:

> Well, that might work for you. It won’t work for me. I put the as on the
> user’s phone. The source and sink of the data can switch roles on a
> millisecond basis. I will track your progress and adopt what I can.
>
> ..Tom's phone
>
> The proposal is that Client asks for a claim from the AS, the user
> consents at the AS, and the AS directly releases the claim directly to the
> Client. No access token. No resource server.
>
>>> While I think defining claims is out of scope of the WG, I think
>>> enabling a client to obtain claims about a user is in scope.
>>> I'm concerned about the XYZ shift to subject identifiers from claims,
>>> and pushing claims to a higher layer, as it may indicate to developers that
>>>> I understand most of the people on this list are paid by the client's
>>>> of the world, but you are still bound by the laws that apply to those
>>>> clients.
>>>>
>>>> Peace ..tom
>>>>
>>>>
>>>>> To be clear, we as the working group are *defining* GNAP the
>>>>> protocol. It has not yet been defined, and that’s why were all here. The
>>>>> charter doesn’t define it. The input specs don’t define it. The working
>>>>> group defines it, and my stance as a contributor to this WG is that we
>>>>> should focus on a delegation protocol with some basic identifier query
>>>>> support and leave the full fledged identity protocol to different work.
>>>>>
>>>>>> language, you’d package it separately as a top-level request parameter
>>>>>> since it can include both the ID token response and the access token
>>>>>> response and we shouldn’t be encouraging mixing these things together.
>>>>>>
>>>>>>  — Justin
>>>>>>
>>>>>>> I know what it is. Per above, GNAP lets us support a wider set of
>>>>>>> use cases. Why limit ourselves to what OIDC supported?
>>>>>>>
>>>>>>>

---

From: Tom Jones <[email-masked]>
Date: Mon, 20 Jul 2020 15:14:19 -0700

if the user must authorize access to the resource, then what better place
for it than their phone. I don't much worry about inconveniencing some
gigantic corporation.
I should be clear tho, *user agents* do not need to be on user phones, i
was addressing my particular need.
If the user has delegated authority to some cloud based service, then
that *user
agent *could could also host an as.
It is interesting to speculate on whether an IdP (openId provider e.g.)
could ever be a trusted *user agen*t. Given what I understand of the market
today, I guess that is not possible. Markets do, however, change.
Some on the list speculate that the client (sink of user resources) could
be a *user agent*.  That is, at least, problematic, but conceivable.
I, personally, would not conflate a client with a *user agent.* After all,
the user agent has access to (at least some) user accessible resources.
maybe you should just rename the as to be a *user agent.* Or at least state
that the as is an endpoint of a user agent.

BTW, for me a user is an identifier claiming to represent a human at a
device. Whether they are the RO or a guardian is not of importance here. I
know others have other definitions, sorry about that.
Peace ..tom

On Mon, Jul 20, 2020 at 12:30 PM Dick Hardt <[email-masked]> wrote:

> Curious: How are you envisioning the client communicates to the AS if it
> is on the User's phone?
> ᐧ
>
>>>> GNAP can enable a client to ask for only the claims it needs,
>>>> preserving user privacy, and compliance with many privacy regulations.
>>>>
>>>> Would you agree?
>>>>
>>>> /Dick
>>>>
>>>>
>>>>
>>>>
>>>>> I agree with Justin's comment " what we should do, as we define GNAP
>>>>> as a protocol, is focus on this one, limited slice of the identity space
>>>>> and not spiral into others."
>>>>>> I am saying that GNAP, *in* its definition within this working
>>>>>> group, should be limited to identifier claims.
>>>>>>
>>>>>>
>>>>>> So my stance in what we should do, as we define GNAP as a protocol,
>>>>>> is focus on this one, limited slice of the identity space and not spiral
>>>>>> into others.
>>>>>>
>>>>>>  — Justin
>>>>>>
>>>>>>> think that GNAP should define the “userinfo” schema here, or the datatype
>>>>>>> values therein. That should be work outside of GNAP, probably for the OIDF.
>>>>>>>
>>>>>>>>> Yes, the core idea is to not have to parse an assertion to get
>>>>>>>>> back the core authentication information, which consists of an identifier
>>>>>>>> The User may have self identified to the client. The client may
>>>>>>>> have a cookie saying who the user was and the user said that was them.
>>>>>>>> While the latter cases are really a strong hint, they are likely right most
>>>>>>>> of the time and can lead to a user experience basde on that hint
>>>>>>>>
>>>>>>>>
>>>>>>>> In these cases, the AS might be able to guess if the client has
>>>>>>>> info about the user already, but probably not. And the assumptions fall
>>>>>>>> apart if it’s in fact a different user that ends up logging in, which is of
>>>>>>>> course possible (the hint you gave doesn’t match the identity of the
>>>>>>>> current user after the AS validates them). This possibility leads to
>>>>>>>> clients always asking for everything every time and the server providing
>>>>>>>> everything every time. That’s a pattern I think we should avoid in an
>>>>>>>> ultimate solution — but ultimately, I don’t think that this kind of
>>>>>>>> protocol decision is inside of GNAP.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> This is about the rights associated with the access token, then.
>>>>>>>> And an access token doesn’t have to keep working if the AS has a policy
>>>>>>>> that says it won’t. The AS/RS could easily decide that a particular access
>>>>>>>> token will only return data that hasn’t been changed. Maybe it stops
>>>>>>>> working after the data changes, or it just returns old data, or any number
>>>>>>>> of things. This is for the AS/RS to decide and this is pretty standard

---

From: Francis Pouatcha <[email-masked]>
Date: Tue, 21 Jul 2020 14:18:42 -0400

Before we dive into discussion on claims, we really do need some sort of
agreement on words like:

- User : I am ok if we find a replacement for this word in the current
draft.
- RO
- Agents (user Agent, RO Agent, ...)

Privacy concerns can be discussed more effectively once we have settled on
those terms.

Best Regards.
/Francis

On Mon, Jul 20, 2020 at 6:14 PM Tom Jones <[email-masked]>
wrote:

> If the user has delegated authority to some cloud based service, then that *user
> could ever be a trusted *user agen*t. Given what I understand of the
> market today, I guess that is not possible. Markets do, however, change.
> I, personally, would not conflate a client with a *user agent.* After
> all, the user agent has access to (at least some) user accessible resources.
> maybe you should just rename the as to be a *user agent.* Or at least
> state that the as is an endpoint of a user agent.
>
>>>>>> The earlier statement that the client should know who the user is -
>>>>>> is just plain WRONG. The client should only know the information the user
>>>>>> is willing to share with the client.
>>>>>> It is now the law in California that the client cannot
>>>>>> demand identity information that is not required for a legitimate business
>>>>>> purpose.
>>>>>>> I agree that an API to return claims is useful.. I think we have
>>>>>>> agreed on that.
>>>>>>>
>>>>>>>> claims from an API, and not just an assertion or direct response, is a
>>>>>>>> powerful and useful pattern. We have an opportunity to separate these
>>>>>>>> cleanly, where OIDC didn’t have the opportunity in defining the “claims”
>>>>>>>> request parameter.
>>>>>>>>
>>>>>>>> (as plain text in the response) and some subset of signed assertions in the
>>>>>>>>>> Now for case (1), how would the client know if it wants to
>>>>>>>>>> request the user’s profile info or not, since it doesn’t know who the user
>>>>>>>>>> is?
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> But the client could know who the user is. The client may have
>>>>>>>>> used a different AS to authenticate the user.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> And the AS won’t know if client is going to want the profile
>>>>>>>>>> info, since the AS won’t know if the client has the user’s info or not.
>>>>>>>>>> Sure, the AS might have seen that client and that user combo previously,
>>>>>>>>>> but it doesn’t know if the client needs an update.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> information inline with the main request/response, you end up in a
>>>>>>>>>> situation where the client always requests everything and the server always
>>>>>>>>>> provides everything, since you can’t be sure you’re not in situation (1) or
>>>>>>>>>> (2) ahead of time.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> information every time, then. But that’s an optimization for a very
>>>>>>>>> specific case.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> get the user known to the client.. In the second stage, the client uses its
>>>>>>>>> From a privacy perspective in non-enterprise use cases, I think
>>>>>>>>> the user should give consent to any updated personal information to a
>>>>>>>>> client. In general, the client should not be able to get the latest
>>>>>>>>> information about a user whenever it wants.
>>>>>>>>>
>>>>>>>>>

-- 
Francis Pouatcha
Co-Founder and Technical Lead
adorsys GmbH & Co. KG
https://adorsys-platform.de/solutions/

---

From: Justin Richer <[email-masked]>
Date: Tue, 21 Jul 2020 15:25:17 -0400

I completely agree that there’s been a lot of circular discussion due to mismatches in use of terminology here. I struggled with that on the pending update to the XYZ spec as well, specifically in separating the “user’ from the “resource owner”. The “user” is the person/entity currently operating the client software. The “Resource owner” is the person/entity who can grant access. In OAuth 2 they’re the same thing, and in GNAP it’s important that they easily CAN be the same. But it’s also important to several members of the community, myself included, that they can be separated. There’s a lot that we can learn from how UMA handles this split, as well as CIBA’s call-center authentication use case. I’ve also helped deploy an OAuth device flow system where the approval happens at a controlled kiosk where the RO is a certified human agent separate from the user. Or at least, that party exists, it’s arguable whether they’re performing the “RO” role since it’s about identifying the user who’s got the client application on their device. It gets complex fast if we don’t have good terms that we can all agree to! And it’s made worse by the fact that many of these terms mean other things in other spaces.

 — Justin

> On Jul 21, 2020, at 2:18 PM, Francis Pouatcha <[email-masked]> wrote:
> 
> Before we dive into discussion on claims, we really do need some sort of agreement on words like:
> 
> - User : I am ok if we find a replacement for this word in the current draft.
> - RO
> Privacy concerns can be discussed more effectively once we have settled on those terms.
> 
> Best Regards.
> /Francis
> 
> On Mon, Jul 20, 2020 at 6:14 PM Tom Jones <[email-masked] <mailto:[email-masked]>> wrote:
> if the user must authorize access to the resource, then what better place for it than their phone. I don't much worry about inconveniencing some gigantic corporation.
> I should be clear tho, user agents do not need to be on user phones, i was addressing my particular need.
> If the user has delegated authority to some cloud based service, then that user agent could could also host an as.
> It is interesting to speculate on whether an IdP (openId provider e.g.) could ever be a trusted user agent. Given what I understand of the market today, I guess that is not possible. Markets do, however, change.
> Some on the list speculate that the client (sink of user resources) could be a user agent.  That is, at least, problematic, but conceivable. I, personally, would not conflate a client with a user agent. After all, the user agent has access to (at least some) user accessible resources.
> maybe you should just rename the as to be a user agent. Or at least state that the as is an endpoint of a user agent.
> 
> BTW, for me a user is an identifier claiming to represent a human at a device. Whether they are the RO or a guardian is not of importance here. I know others have other definitions, sorry about that.
> Peace ..tom
> 
> 
> On Mon, Jul 20, 2020 at 12:30 PM Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
> Curious: How are you envisioning the client communicates to the AS if it is on the User's phone?
> ᐧ
> 
> On Sun, Jul 19, 2020 at 9:13 PM Tom Jones <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jul 19, 2020, at 1:45 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> 
>> Hi Tom
>> 
>> On Sat, Jul 18, 2020 at 7:34 PM Tom Jones <[email-masked] <mailto:[email-masked]>> wrote:
>> On Sat, Jul 18, 2020 at 5:58 PM Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> Hey Tom
>> 
>> On Sat, Jul 18, 2020 at 9:56 AM Tom Jones <[email-masked] <mailto:[email-masked]>> wrote:
>> On Mon, Jul 13, 2020 at 12:31 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>>> On Jul 13, 2020, at 2:51 PM, Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>>> 
>>>> I agree that an API to return claims is useful.. I think we have agreed on that. 
>>>> 
>>>>>> In the first stage, you push the bare minimum of what you need to get the user known to the client.. In the second stage, the client uses its access token to call an API to get whatever else it needs to know about the user.
>>>>>> 
> https://adorsys-platform.de/solutions/ <https://adorsys-platform.de/solutions/>