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

Dick Hardt <> Wed, 08 July 2020 22:11 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 3B44E3A083F for <>; Wed, 8 Jul 2020 15:11:15 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.096
X-Spam-Status: No, score=-2.096 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_FONT_LOW_CONTRAST=0.001, HTML_MESSAGE=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id NUJ-kbaQ2JHG for <>; Wed, 8 Jul 2020 15:11:12 -0700 (PDT)
Received: from ( [IPv6:2a00:1450:4864:20::233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 4183A3A082C for <>; Wed, 8 Jul 2020 15:11:12 -0700 (PDT)
Received: by with SMTP id h22so45647lji.9 for <>; Wed, 08 Jul 2020 15:11:12 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=aH2E+hyVVVpUVQZymdLyorx46KlXViBucepiJZwsQfg=; b=mDDbAf9ham2r+RmGZJjaPn7pXBd6bP7hN/LRlXdu4QVF6UrfvANpwY2zOBExJvyQFN wWyGYy2H803AfoP9wMSTGleSHHRwmIDzuF4j5WXB9y8nN3kvEi1tOkFA5oAabouNDKNC ChEdxYUkbrE/R1CXX9j9LAGYRnyO5acuyAyTplOGD8AKFwObzExOuz/q0YAD0YYGz6Hw ncbv2WJQ2sRJrQccyUvsaMkCgjFPbssUR618mU/hC5XUmwEmFW3Ka5lnVTsNZxUM9Lsl 6kRXZNDLgMrIxjPQXSuIwiYUeDvQLAc1QyQFR6lyrPq8IxgEjk5yuete73n0y86bel2s wPoQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=aH2E+hyVVVpUVQZymdLyorx46KlXViBucepiJZwsQfg=; b=XBYBfYKi4TN7gMG7ymNcQ9AWyzqJgbZSaH0zZTBHe9k8Au15gToTXt9AByeOD6J+Wp TPF+bprRJ1uFCZeo/gJ+IuNBcdwM3S/Z6TwICdMFLHfkp0+FjYy/6i1Kjxk4TEXGCoa5 NUPr986ujbtzBkBa164XDpEcUbkqJ6p722oHGPknn+i+iMSfMm+go2ReCuGqU7recepi m9bQyqqFZNOrklfVjRt7ccvYClciLThOhc/ovx/9SpqLUw4kOktRzF91pflsAWFpX+zg IcIUP6kzYHctf+Jnv8NsxH2a69vfJYzyVYRTzCZt7PKnSZzj5QNcfsaPT1RQb4uqXeh/ L0nA==
X-Gm-Message-State: AOAM531mMmujtMvZUIbNU7MyCaPikc/gWE4vPktTpM1nFOSx+LILyv9q YqzbNnJAFyis5WRc7c7w+d/+aYucvUAyeffF3mA=
X-Google-Smtp-Source: ABdhPJzYspsW83OUCoTIfyHL/lZgJZ01leKOQMnfturlua1EUcUA3OpE9Uu4SzxgqLL/LfBDVtG+c6Y5iHrcXGkD+Bw=
X-Received: by 2002:a2e:8316:: with SMTP id a22mr11667401ljh.246.1594246270206; Wed, 08 Jul 2020 15:11:10 -0700 (PDT)
MIME-Version: 1.0
References: <> <> <> <> <> <> <> <> <> <>
In-Reply-To: <>
From: Dick Hardt <>
Date: Wed, 8 Jul 2020 15:10:33 -0700
Message-ID: <>
To: Justin Richer <>
Content-Type: multipart/alternative; boundary="0000000000009ec8cb05a9f5625f"
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: Wed, 08 Jul 2020 22:11:15 -0000

On Wed, Jul 8, 2020 at 1:02 PM Justin Richer <> wrote:

> On Jul 8, 2020, at 3:16 PM, Dick Hardt <> 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
> it’s fully parsed everything?

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

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

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.
> To me, this remains much more understandable, extensible, and clean.

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