Re: [Txauth] Polymorphism (Was: JSON Schema?)

Justin Richer <> Tue, 07 July 2020 10:40 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id E36533A0A97 for <>; Tue, 7 Jul 2020 03:40:51 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.898
X-Spam-Status: No, score=-1.898 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id E5rMRdocuRQA for <>; Tue, 7 Jul 2020 03:40:50 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 7C32B3A0A94 for <>; Tue, 7 Jul 2020 03:40:50 -0700 (PDT)
Received: from [] ( []) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by (8.14.7/8.12.4) with ESMTP id 067Aelrt022165 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 7 Jul 2020 06:40:48 -0400
Content-Type: text/plain; charset=utf-8
Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.\))
From: Justin Richer <>
In-Reply-To: <>
Date: Tue, 7 Jul 2020 06:40:47 -0400
Content-Transfer-Encoding: quoted-printable
Message-Id: <>
References: <> <> <>
To: Dick Hardt <>
X-Mailer: Apple Mail (2.3608.
Archived-At: <>
Subject: Re: [Txauth] Polymorphism (Was: JSON Schema?)
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Tue, 07 Jul 2020 10:40:52 -0000

I wanted to respond to this comment more fully:

> 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