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

Dick Hardt <dick.hardt@gmail.com> Fri, 10 July 2020 17:39 UTC

Return-Path: <dick.hardt@gmail.com>
X-Original-To: txauth@ietfa.amsl.com
Delivered-To: txauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id A373E3A0789 for <txauth@ietfa.amsl.com>; Fri, 10 Jul 2020 10:39:56 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.096
X-Spam-Level:
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: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 66eJtMjgzRKk for <txauth@ietfa.amsl.com>; Fri, 10 Jul 2020 10:39:54 -0700 (PDT)
Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [IPv6:2a00:1450:4864:20::234]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 529DE3A0544 for <txauth@ietf.org>; Fri, 10 Jul 2020 10:39:53 -0700 (PDT)
Received: by mail-lj1-x234.google.com with SMTP id h19so7342973ljg.13 for <txauth@ietf.org>; Fri, 10 Jul 2020 10:39:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=bATqocGimeWDCUYxRROx+ovciRXoAPDNNDHqy7F8a+o=; b=G/AD4uuPH3UpQrBWJZnGNRrPNnPZymkE3kYJMDGXXYeV6aAyXXZ4X4EtV2dvYjtT2+ 4PxnPtZEBNgl8N10S6rGTGjWQJze2BahZh7YF2i2QDaKq3FglCdZ+jzNMiVq+D2wryed bvasqF3I7fyXQmAtTZLgUIzql3qGnnk5KjNfMCg9bJEiH+6dy2QG4MGfMYyqYqf8da65 K14boKZpjjF2A9g0GcXY8p7KiXNnnGRaIxUYJmWIVPLwKbaw3dLAz9iewMgOadorLFNf pxMMoN7OO8mVpFvmxqdhRNIJ2o7nwpAzH5I9zxzoTslt4IibfrHIkjKgeCK7QfLL+WYP QRYg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=bATqocGimeWDCUYxRROx+ovciRXoAPDNNDHqy7F8a+o=; b=Ubi2N3Rn5tQUpW2VhpmbfT/FsV6F21ir5GVwGeXsr17xfSxDGQ83VSidCD1mhY12hz 6c3URQILapgC1ZZE6c8hVjtYXt8qrZCoeEMphwjQ/3BgVrQy4DWhFLJKFWfD/HhnvA/B gBw1rpBcg0KlprJCkhzIvw9wL8OhrFSVH3JOyot9OhOduLU1022vgwYyF4aXDaTztAxT +AftS0fjDJ/kHbTVut7NUWn2KQs6F8sPCVsSjbEOkI11z8OAJSNVWwwzV3PZxK9p6zjd ptFA+eLluR5co8ecqMfPNQu+aMQldd6FNCgilRA45EsnulynI4hMzmw0lzodzfEEKXoG XeRQ==
X-Gm-Message-State: AOAM533HcEpNbBDGVbwFtS8wi7PrYVk19gLIc5fVHMJsTtxFsHTocUrp 9Kd87HnErmdgT7WrDRt40+3dVFAswO9CZ0UftfI=
X-Google-Smtp-Source: ABdhPJxAylnN30f7YPIWi0YWir4lX9WxoGMXIFlrV2vnrobj0aWFeKVsmUp1D8kqqde3jocPBIogMG3Vbl3jC47WpIk=
X-Received: by 2002:a2e:80c9:: with SMTP id r9mr3471822ljg.69.1594402790511; Fri, 10 Jul 2020 10:39:50 -0700 (PDT)
MIME-Version: 1.0
References: <CAD9ie-vnA98pobbboS00SAHneEG52_8eMxh_sE3r3jg6gyooGg@mail.gmail.com> <E9EC90C9-7A9A-4909-8627-A161B33E941F@mit.edu> <CAD9ie-vyB8+5jS=K_qUHfvxsF2wPV5APRo+7WUDfJxNzJONJpg@mail.gmail.com> <8CC8B466-FD6F-4C23-8DAA-99B8A9BDF548@mit.edu> <CAD9ie-u9z7Mc-wNjztoOTy4N_Z9jFDc2Sb6quLspasMGAMKdSw@mail.gmail.com> <097FB93E-96DA-4DF6-8511-0B32FD321211@mit.edu> <CAD9ie-tpuisauOFGiUj65-RcYPtcvW_gZP1CAadqq5cE6P36HQ@mail.gmail.com> <EE4A7D91-1106-44CB-92BF-C3AA3649BDFE@mit.edu> <CAD9ie-saoc2FUm46r4h1B27iYK04j_skf5-zJR7EXLmWBzj=hA@mail.gmail.com> <F41A8F88-C1B4-4CE2-8573-7A03C086D25B@mit.edu> <CAD9ie-tHCg9Ti1xWuzUP5EGLAcU2cpFALErqq98+fPnD3enZCQ@mail.gmail.com> <820525FD-4556-4617-8D89-C600D8C90C33@mit.edu> <CAD9ie-uwz_Li7n9iuX_--YtWeE+HX5sWEe95nZ8Y0akYh8WTHg@mail.gmail.com> <CAD9ie-vFwjQWQZjeL1Qza9MQ5=35qbWW15umyqGhhawFWephLA@mail.gmail.com> <D3EB60DC-6040-480D-A477-C1346130DF96@mit.edu> <CAD9ie-v9MdskdG74Ou__nn9mMmN2gJT6F45mg3dPs7CzJeD7WQ@mail.gmail.com> <69082870-1A99-4912-95EA-D1B7A1C967E5@mit.edu> <CAD9ie-uJHm4UHzNqreVta6Rrm5iQ=8chAbZqfaUFX6OOyXTbow@mail.gmail.com> <D1CD3AF7-051B-4BBD-9E16-5640FB2A718F@mit.edu>
In-Reply-To: <D1CD3AF7-051B-4BBD-9E16-5640FB2A718F@mit.edu>
From: Dick Hardt <dick.hardt@gmail.com>
Date: Fri, 10 Jul 2020 10:39:13 -0700
Message-ID: <CAD9ie-v+vv0VWeCC8gxytgjaVaHUjF9XJqwLa=sdB=FPwxpGTA@mail.gmail.com>
To: Justin Richer <jricher@mit.edu>
Cc: txauth@ietf.org
Content-Type: multipart/alternative; boundary="000000000000f5186605aa19d35e"
Archived-At: <https://mailarchive.ietf.org/arch/msg/txauth/jNAmiRbjO2GI27t3rRdi2WRT5W0>
Subject: Re: [Txauth] Polymorphism (Was: JSON Schema?)
X-BeenThere: txauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: <txauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/txauth>, <mailto:txauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/txauth/>
List-Post: <mailto:txauth@ietf.org>
List-Help: <mailto:txauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/txauth>, <mailto:txauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 10 Jul 2020 17:39:57 -0000

On Thu, Jul 9, 2020 at 5:46 PM Justin Richer <jricher@mit.edu> wrote:

>
>
> On Jul 9, 2020, at 6:50 PM, Dick Hardt <dick.hardt@gmail.com> wrote:
>
>
>
> On Thu, Jul 9, 2020 at 12:17 PM Justin Richer <jricher@mit.edu> wrote:
>
>> On Jul 9, 2020, at 2:32 PM, Dick Hardt <dick.hardt@gmail.com> 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.
>>
>
> 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.
>

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.


>
>
> 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.
>

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}
}



>
>
>
>>
>>
>> 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.
>>
>>
>> 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.
>
>
> 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.



>
>
>
>>
>> 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.
>>
>>
>> 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".
>
>
> 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"


>
>
>
>>
>> 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 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

>
> ᐧ