Subject: [Txauth] Multiple Access Tokens in XYZ

From: Justin Richer <[email-masked]>
Date: Fri, 13 Mar 2020 18:13:00 -0400

I took some time to implement an idea that was tossed out on the list here recently, and that’s how we might support requests and responses for multiple access tokens. I’ve got a method that I think works pretty well without getting in the way of the common, simple case of requesting a single access token. I’ve implemented this in our Java implementation of XYZ and I’ve updated the https://oauth.xyz/ website with more details. I’ll update my ID spec text when I get a chance to reflect this, but I wanted to start this discussion first. Everything in here is based on the XYZ protocol.

Normally, the “resources” element of a tx request is an array of items:

resources: [
	{
            actions: ["read", "write", "dolphin"],
            locations: ["https://server.example.net/", "https://resource.local/other"],
            datatypes: ["metadata", "images"]
        },
	{
            actions: ["foo", "bar", "dolphin"],
            locations: ["https://resource.other/"],
            datatypes: ["data", "pictures"]
        }
]

This tells the AS that the client is asking for a single access token with multiple, perhaps orthogonal sets of access. This is in parallel to RAR being developed in OAuth 2. However, if we allow the “resources” item to be an object instead of an array, we can let the client signal to the AS that it wants multiple access tokens. The client picks “labels” for these access tokens, in this case “token1” and “token2”, and sends a request like this.

resources: {
    token1: [{
            actions: ["read", "write", "dolphin"],
            locations: ["https://server.example.net/", "https://resource.local/other"],
            datatypes: ["metadata", "images"]
     }],
     token2: [{
            actions: ["foo", "bar", "dolphin"],
            locations: ["https://resource.other/"],
            datatypes: ["data", "pictures"]
     }]
}

The client could request multiple kinds of access within each sub-object’s array (the value of the “token1” and “token2” fields), but I wanted to keep it simple here. This example is the same total set of resources that the client is asking for in the first case, but here the client’s saying it wants them as two different access tokens instead of a single one. The AS can tell the difference in the request because the first type is an array at the top and the second type is an object at the top. So that means that the AS can send back a single access token in a tx response like this:

{
        access_token: {
            value: "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0",
            type: "bearer"
        }
}

Or multiple access tokens in a tx response like this:

{
    multiple_access_tokens: {
          token1: {
            value: "OS9M2PMHKUR64TB8N6BW7OZB8CDFONP219RP1LT0",
            type: "bearer"
          },
          token2: {
            value: "UFGLO2FDAFG7VGZZPJ3IZEMN21EVU71FHCARP4J1",
            type: "bearer"
          }
    }
}

These fields are mutually exclusive, so you either get a single unnamed token or a set of named tokens. Since the client pics the labels for the access tokens, it’s clear which part of the request maps to which part of the response. It’s more complexity for the client to track, but that complexity is only seen and borne by clients that need it. Simple clients get to stay simple while letting a complex problem get solved. 

A note about the polymorphic JSON that’s in user here, though it’s already a key part of XYZ’s protocol design. For those unfamiliar with the concept, this is when a given field can have a value that takes multiple different types: a string, a boolean, an object, an array, etc. This is pretty simple to deal with in dynamically typed languages, you just check the type of the resulting object and it will tell you what you’re dealing with. It’s trickier in statically typed languages, but I’ve found that pretty much every platform and library has hooks for custom serialization and deserialization that will let you dispatch to different types during the process, so you can still call your top-level parser and toString methods and things will work as expected. This is one of the reasons that I did an implementation in Java, to prove that we could do this kind of thing in a strongly typed language that’s not very flexible about what goes in objects, and I’ve done it without resorting to generic collections for the dynamic fields. Previously, I’ve used this feature in XYZ to allow a single string to stand in as a reference for an object — something XYZ calls “handles”. These let you have constructs akin to a client_id, a scope, a refresh token, and a few other items without having to create explicit elements for these, since they always stand in for the object they replace there’s no ambiguity. So for things like a resource request, each of these can be replaced by a string using resource handles and polymorphic JSON (see note below) to act like a scope in OAuth2.

resources: [ “metadata-readwrite”, “foobar-pictures” ]

Polymorphic JSON is great for things like this because it means you don’t have to have multiple fields and normative rules for mutual exclusivity, like we’d have to have otherwise. The type switching only works when the base type is significantly different, though — that’s why I have “access_token” and “multiple_access_tokens” above, since both are objects at the top level and you can’t cleanly switch at the parser level, and you don’t want to have to dig down into the object to see what to do with it.

People have been asking for a good way to do multiple access tokens with OAuth for years, but we’ve never had a good or clean way to pull it off because of OAuth’s model and the assumptions that it makes. I think TxAuth gives us the opportunity to solve this in a way that’s consistent with the rest of the protocol, and do so in a way that doesn’t make the simple cases we know and love too complicated for average developers.

 — Justin

---

From: Vladimir Dzhuvinov <[email-masked]>
Date: Sat, 14 Mar 2020 22:15:25 +0200

+1 for the multiple access tokens.

The user experience of apps which need to deal with multiple resources
can significantly benefit from this.

If the JSON syntax is intuitive and concise that would be really nice.

The polymorphic JSON and how can be handled in languages like Java
doesn't worry me at all.

Vladimir

---

From: Dick Hardt <[email-masked]>
Date: Fri, 20 Mar 2020 11:45:22 -0700

Justin: How are each of the access tokens refreshed in the multiple access
token scenario?

On Fri, Mar 13, 2020 at 3:13 PM Justin Richer <[email-masked]> wrote:

> I took some time to implement an idea that was tossed out on the list here
> recently, and that’s how we might support requests and responses for *multiple
> access tokens*. I’ve got a method that I think works pretty well without
> getting in the way of the common, simple case of requesting a single access
> token. I’ve implemented this in our Java implementation of XYZ and I’ve
> updated the *https://oauth.xyz/ <https://oauth.xyz/>* website with more
> details. I’ll update my ID spec text when I get a chance to reflect this,
> but I wanted to start this discussion first. Everything in here is based on
> the XYZ protocol.
>
> This tells the AS that the client is asking for a single access token with
> multiple, perhaps orthogonal sets of access. This is in parallel to RAR
> being developed in OAuth 2. However, if we allow the “resources” item to be
> an object instead of an array, we can let the client signal to the AS that
> it wants multiple access tokens. The client picks “labels” for these access
> tokens, in this case “token1” and “token2”, and sends a request like this.
>
> resources: {
>     token1: [{
> The client could request multiple kinds of access within each sub-object’s
> array (the value of the “token1” and “token2” fields), but I wanted to keep
> it simple here. This example is the same total set of resources that the
> client is asking for in the first case, but here the client’s saying it
> wants them as two different access tokens instead of a single one. The AS
> can tell the difference in the request because the first type is an array
> at the top and the second type is an object at the top. So that means that
> the AS can send back a single access token in a tx response like this:
>
> {
>         access_token: {
> These fields are mutually exclusive, so you either get a single unnamed
> token or a set of named tokens. Since the client pics the labels for the
> access tokens, it’s clear which part of the request maps to which part of
> the response. It’s more complexity for the client to track, but that
> complexity is only seen and borne by clients that need it. Simple clients
> get to stay simple while letting a complex problem get solved.
>
> *A note about the polymorphic JSON *that’s in user here, though it’s
> already a key part of XYZ’s protocol design. For those unfamiliar with the
> concept, this is when a given field can have a value that takes multiple
> different types: a string, a boolean, an object, an array, etc. This is
> pretty simple to deal with in dynamically typed languages, you just check
> the type of the resulting object and it will tell you what you’re dealing
> with. It’s trickier in statically typed languages, but I’ve found that
> pretty much every platform and library has hooks for custom serialization
> and deserialization that will let you dispatch to different types during
> the process, so you can still call your top-level parser and toString
> methods and things will work as expected. This is one of the reasons that I
> did an implementation in Java, to prove that we could do this kind of thing
> in a strongly typed language that’s not very flexible about what goes in
> objects, and I’ve done it without resorting to generic collections for the
> dynamic fields. Previously, I’ve used this feature in XYZ to allow a single
> string to stand in as a reference for an object — something XYZ calls
> “handles”. These let you have constructs akin to a client_id, a scope, a
> refresh token, and a few other items without having to create explicit
> elements for these, since they always stand in for the object they replace
> there’s no ambiguity. So for things like a resource request, each of these
> can be replaced by a string using resource handles and polymorphic JSON
> (see note below) to act like a scope in OAuth2.
>
> Polymorphic JSON is great for things like this because it means you don’t
> have to have multiple fields and normative rules for mutual exclusivity,
> like we’d have to have otherwise. The type switching only works when the
> base type is significantly different, though — that’s why I have
> “access_token” and “multiple_access_tokens” above, since both are objects
> at the top level and you can’t cleanly switch at the parser level, and you
> don’t want to have to dig down into the object to see what to do with it.
>
>
>
> People have been asking for a good way to do multiple access tokens with
> OAuth for years, but we’ve never had a good or clean way to pull it off
> because of OAuth’s model and the assumptions that it makes. I think TxAuth
> gives us the opportunity to solve this in a way that’s consistent with the
> rest of the protocol, and do so in a way that doesn’t make the simple cases
> we know and love too complicated for average developers.
>
>  — Justin
>
> --
> Txauth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/txauth
>

---

From: Justin Richer <[email-masked]>
Date: Fri, 20 Mar 2020 20:55:58 -0400

Our implementation currently refreshes all of them together when a refresh is requested. Will we need finer grained access than that? Maybe. 

As I’ve said on the list before, I think there’s merit in exploring the per-access-token management URL idea in XAuth, but I still am not a fan of separating the concept of the “refresh token” back out.

 — Justin

> On Mar 20, 2020, at 2:45 PM, Dick Hardt <[email-masked]> wrote:
> 
> Justin: How are each of the access tokens refreshed in the multiple access token scenario? 
> 
> On Fri, Mar 13, 2020 at 3:13 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> I took some time to implement an idea that was tossed out on the list here recently, and that’s how we might support requests and responses for multiple access tokens. I’ve got a method that I think works pretty well without getting in the way of the common, simple case of requesting a single access token. I’ve implemented this in our Java implementation of XYZ and I’ve updated the https://oauth.xyz/ <https://oauth.xyz/> website with more details. I’ll update my ID spec text when I get a chance to reflect this, but I wanted to start this discussion first. Everything in here is based on the XYZ protocol.
> 
>             locations: ["https://server.example.net/ <https://server.example.net/>", "https://resource.local/other <https://resource.local/other>"],
>             locations: ["https://resource.other/ <https://resource.other/>"],
>             locations: ["https://server.example.net/ <https://server.example.net/>", "https://resource.local/other <https://resource.local/other>"],
>             locations: ["https://resource.other/ <https://resource.other/>"],
> [email-masked] <mailto:[email-masked]>
> https://www.ietf.org/mailman/listinfo/txauth <https://www.ietf.org/mailman/listinfo/txauth>