Re: [GNAP] Feedback on polymorphism
Andrii Deinega <andrii.deinega@gmail.com> Thu, 29 October 2020 19:23 UTC
Return-Path: <andrii.deinega@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 BE84F3A09E1 for <txauth@ietfa.amsl.com>; Thu, 29 Oct 2020 12:23:28 -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 swD4xb3dUrWr for <txauth@ietfa.amsl.com>; Thu, 29 Oct 2020 12:23:22 -0700 (PDT)
Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) (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 2A1C53A07D7 for <txauth@ietf.org>; Thu, 29 Oct 2020 12:23:22 -0700 (PDT)
Received: by mail-ej1-x62d.google.com with SMTP id w27so5404469ejb.3 for <txauth@ietf.org>; Thu, 29 Oct 2020 12:23:21 -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=wvbAGjpM7NhmvWURM8PA9vkp1tsI4ZfLQySo7mAAZkE=; b=YJpaz+j1MAVnKSqxfJJXiyoX61qlaNpz9Mwv29ey8Z+JBk//BwIURrFczFtebbZsAs 7vlY+CIjLEJzYnHnDXWISpSG6iLuCt5N0WDnIaf1LY/StT5yXgob9DKXQy6kojIIhnRI +sx8q4ZQEKPh5Dly/921WuY1y7DfFJ1G1JJ811fR5WAg9nqQz26wcu5adt2hWNI/JRJx d6mDl8q7AFd8SAVizKRhLHsY/5dBg6hHwoL/6DGSImV+w03k//b3IBdVbNd2xeSNJQ/M nUiwCia9hujx+rcMzzXvf9nZNZvG5lhElb3v40+uyBQiPX2wQdL/wh3h6W0SFbWuyNzN pW5w==
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=wvbAGjpM7NhmvWURM8PA9vkp1tsI4ZfLQySo7mAAZkE=; b=JtllvEjrgz9OguzeosFUBd+FwhxIUpsqOfOy42pbQiBCzHaqXb4lIG0wdbCj2dCTP+ KNVqGsiEJhjjCpijdSHQbUB0tBNGHM6dO/WuzFsW4gtZy0FijzLmYD6VTzJ8L50sT66l SlENaClb+7ljUVQ1q9+so2ePWqPosASwF2lsL8yTvijAzyw8Qq41KSSHrrmIyx8U89Zg VsEeWU/jqh1RAwUGIoxAI62LomjQjTO0w0nFLDqr6RcMY/51VZBIvtuRO8/O4y7MG/CU a5n8zNIW8UtPbJ99hhevh/+UUzmIz6i0PkCVWDduETiibMByPwQ78JCnPa8lBhqk+r21 L7nA==
X-Gm-Message-State: AOAM533BziiG0w7tOHtmjIKfll9MzFIdAG5bc0jxxpxLopkyiofKXfe5 EA9hEqqs6gYYKr72UXMK002vYPdxNovso8rkt/g=
X-Google-Smtp-Source: ABdhPJzoBE4ey4Rj+PLIhdm3h/P/D/ItgIV93UDPlSyUxvDWlP6TTE4hvQQnOf9hEQ+/2bv/fPs0iVWQI/p1TjJkG44=
X-Received: by 2002:a17:906:8891:: with SMTP id ak17mr5542374ejc.176.1603999400152; Thu, 29 Oct 2020 12:23:20 -0700 (PDT)
MIME-Version: 1.0
References: <CADxMOMf016Rq2GhRF5utT6KsiQiS3ir4QXjrnW_1+buiqtG7uA@mail.gmail.com> <AAF5364C-F337-483F-B011-A2B11779290E@mit.edu> <CAD9ie-v-RygTSh4VBnAzMDFy6O21sH-Jhh+_7QMVTT0mn_ur2g@mail.gmail.com> <30AE73A0-6A18-454A-AA20-0ECE5AEBD49A@mit.edu> <CAD9ie-s1ENJv610qGYLB=OJaX7q2g3G1zWA+YeNWoRPdktVi2A@mail.gmail.com> <14F2A48D-F6CC-4DF4-9F5F-D3A01776907A@mit.edu> <CAM8feuRWn8Hyd-kcODBTtfmNquhkKHgtONfsD-W3VrmPXGDf+A@mail.gmail.com> <CAD9ie-sckXpX_2JYPRMnk34naZ4Yi4LSsU6o4ep-OtzaWqadyw@mail.gmail.com> <CAM8feuSXN3jfUvVbV0pB-WyKFJtQ_LCPrTR+mko9N25hC7sQLA@mail.gmail.com> <CAM8feuSj2f+z4XOo7SmfU_JZm_t5-i_2scOs2WOnUDwEYOKx+g@mail.gmail.com> <CAD9ie-ujooRXmUAzL6=crcVAfZ3U4ey-fJu1meZgnDi+2JcL2A@mail.gmail.com> <CAM8feuRWN7y7Cyqrr=eTQB3HXOchVezi57rmpoiquowvo=HhEg@mail.gmail.com> <CADxMOMcKiKYUfNQR7T17yBLxnK1TNh74fi+xPkOCZwi9dP+ByQ@mail.gmail.com> <CAM8feuQbzd8e_xUEEAUd42YrPgj_6k0c+djz_KSkiOJ2VK_+Sw@mail.gmail.com> <E13AEC54-C3A6-4968-B326-418528723615@gmail.com> <CAM8feuTHUcVwqSoca5jO0txbGQpMfvczWH2FhAyrXO5L21szNw@mail.gmail.com>
In-Reply-To: <CAM8feuTHUcVwqSoca5jO0txbGQpMfvczWH2FhAyrXO5L21szNw@mail.gmail.com>
From: Andrii Deinega <andrii.deinega@gmail.com>
Date: Thu, 29 Oct 2020 12:23:08 -0700
Message-ID: <CALkShcvU=mn-Vwm28cuvpKoYau4gZLjK6sY9ys=16tbDgLmSfg@mail.gmail.com>
To: Mika Boström <mika.bostrom@smarkets.com>, Justin Richer <jricher@mit.edu>
Cc: Yaron Sheffer <yaronf.ietf@gmail.com>, GNAP Mailing List <txauth@ietf.org>, Dick Hardt <dick.hardt@gmail.com>, Fabien Imbault <fabien.imbault@gmail.com>
Content-Type: multipart/alternative; boundary="00000000000077529905b2d436af"
Archived-At: <https://mailarchive.ietf.org/arch/msg/txauth/bz7f9DjqlCbx0Qf4c_c4S2fFW9w>
Subject: Re: [GNAP] Feedback on polymorphism
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: Thu, 29 Oct 2020 19:23:30 -0000
Hi Mika, Justin, and WG, The act (actor) claim introduced in RFC 8693 (OAuth 2.0 Token Exchange) has a JSON object as its value. This claim could be a part of AT JWT or a token introspection response and has the same semantics in both cases. The JSON object as its value may look like this "act": { "sub":"admin@example.com" } or even be nested like in "act": { "sub":"https://service16.example.com", "act": { "sub":"https://service77.example.com" } } Personally, I find it to be a very expressive approach. Also, as far I as know, several (oAuth2) client libraries have good support of things like "aud":"https://service1.example.com" and "aud":[" https://service1.example.com","https://service2.example.com"] in AT JWTs for a quite long time. Regards, Andrii On Wed, Oct 28, 2020 at 12:58 PM Fabien Imbault <fabien.imbault@gmail.com> wrote: > Hi Yaron, > > We'll indeed have to check how make it as idiomatic as possible with > experts of each language (help welcome). > > Regarding the client, the variations are more limited but they do exist. > Here I believe it's much more problematic than on the server side and there > are at least a few actions we should take: > > A) check in sec 7 if we really have a compelling reason for key and proof > variants. This is derived from larger discussions on key binding as per the > related note. There are quite a few open questions related to this theme. > > B) there is also the choice between value/reference that may generate > complexity. > > C) More generally, as many feedbacks already have noticed, we need to have > a systematic review and reduce the set of available options in the > protocol. > > Unless we have a clear idea why runtime behavior requires mutability, it > might be useful to have a way to define the chosen variant before hand, so > that the expected behavior becomes deterministic on the client side. There > are various ways it could be done in practice. > > For sure several independant implementations would help, especially if we > make sure they can work together. > > Anyway all this open to improvement. > > Cheers > Fabien > > > Le mer. 28 oct. 2020 à 19:47, Yaron Sheffer <yaronf.ietf@gmail.com> a > écrit : > >> Hi Fabien, >> >> >> >> At least in the case of Go, I think the “solution” is far worse than the >> problem. The code in the article you cite is very specific to the use case >> and IMHO quite ugly. So my preferred Go implementation would be a >> combination of untyped structures (Go interface{}) and run-time enforcement >> of JSON Schema. >> >> >> >> Also, going back to our earlier discussion on this topic, I just read >> Sec. 7 of gnap-00 and realized that the RC also needs to deal with >> polymorphism (the “key” value), not only the AS. >> >> >> >> Thanks, >> >> Yaron >> >> >> >> *From: *TXAuth <txauth-bounces@ietf.org> on behalf of Fabien Imbault < >> fabien.imbault@gmail.com> >> *Date: *Wednesday, October 28, 2020 at 18:56 >> *To: *Mika Boström <mika.bostrom@smarkets.com> >> *Cc: *GNAP Mailing List <txauth@ietf.org>, Justin Richer <jricher@mit.edu>, >> Dick Hardt <dick.hardt@gmail.com> >> *Subject: *Re: [GNAP] Feedback on polymorphism >> >> >> >> Thanks for the great feedback. Your concern is very valid. >> >> >> >> My implementation is in rust, which makes life easier in that specific >> case. >> >> >> >> So I'm not a golang specialist but I guess the transcription of json >> strings/arrays into go structs would work around the lines described by >> https://medium.com/@alexkappa/json-polymorphism-in-go-4cade1e58ed1 >> >> When we have a more formalized json schema, I suggest we make a library >> of json examples and some related code samples in mainstream languages, to >> check it is feasible for everyone. >> >> >> >> Cheers, >> >> Fabien >> >> >> >> >> >> On Wed, Oct 28, 2020 at 5:28 PM Mika Boström <mika.bostrom@smarkets.com> >> wrote: >> >> Hi everyone, >> >> >> >> Looks like I stuck my finger in a hornets' nest. First off, apologies for >> not chipping in earlier, but there was a lot of material to digest. Also, >> warning: lots to read ahead. >> >> >> >> I'm one of those people who end up making use of AuthN/AuthZ >> functionality through a library. On top of that I can see myself being >> roped in as a server (AS) implementation help. So I'm approaching this from >> an outsider's perspective. Someone who expects to be exposed to the >> eventual RFC and all the nitty-gritty details. My relatively terse comment >> ended up at the top of the aforementioned HN thread, which didn't >> necessarily help. Sorry about that. >> >> >> >> Now, having read Justin's initial reply - and the rest of the thread - I >> believe I can see where the desire for polymorphism comes from. To be >> clear: I am all for strict types inside an implementation, as it will add >> helpful guard-rails to the state management code paths. However, I see this >> as a case of leaky abstraction. If we take the existing oauth.xyj-java code >> to be the reference implementation, the choice makes logical sense: JSON is >> not expressive enough to serialise arbitrary objects, so in order to avoid >> writing complex payload parser(s) the internal implementation details now >> leak to the protocol itself. From a purely technical perspective, it's a >> cool trick. From a distance it even looks a bit like the result of protobuf >> decoding, but without the generated code parts. >> >> >> >> But then the downside. I don't personally expect to be able to use the >> reference implementation, being mostly a Python user myself. A fair number >> of AS implementations will be written with languages such as Go, Python, >> C#, Ruby, and JavaScript (thanks to node.js), and all of them will have to >> deal with the polymorphism. From what I've read over the past couple of >> days, I understand that at least Go supports custom unmarshalers from JSON >> to typed structs, at the cost of an indirection. Normally when a Go code >> processes JSON to a typed struct, the process is helped by field >> annotations in the type definition itself. For example, if the payload for >> a person in JSON was >> >> >> >> { >> >> "name": "<string>", >> >> "age": <int>, >> >> "country": "<string>", >> >> "city": "<string>" >> >> } >> >> >> >> .. then the type definition would look like: >> >> >> >> type Person struct { >> >> Name string `json:"name" >> >> Age int `json:"age"` >> >> Country string `json:"country"` >> >> City string `json:"city"` >> >> } >> >> >> >> When the (possibly complex) type of a given field is fixed, unmarshaling >> should still be straightforward. I haven't verified, but since the >> annotation only gives which field to look at for a given typed value, there >> should be nothing special about that. But when the field can instead be a >> union of more than one distinct types, things start to get messy. There is >> no union type in the language at all, so the following construct is not >> even possible: >> >> >> >> type Entity struct { >> >> Resources []string `json:"resources"` >> >> Client union(Client, string) `json:"client"` >> >> } >> >> >> >> As I understand, the implicit expectation is that in the above case, the >> unmarshaler detects that "client" is a string, and so expands it from an >> opaque handle to the expected, populated type. Even after thinking about >> the ramifications over the past few days I remain confused, because I don't >> see how the commonly used annotations could work. If the expectation is >> that protocol implementations should use strong types, then the use of >> polymorphic JSON is very likely to make things _more_ complicated for >> non-reference implementations. >> >> >> >> Hence my concern. I'm afraid that the leaky abstraction, while making the >> reference implementation more robust and straightforward, contributes to >> making other implementations less robust. And this being a security >> protocol, the potential for brittle and/or confused implementations is >> terrifying. >> >> >> >> I am a fan of reducing complexity, and from what I can see, for the >> reference implementation the polymorphic approach actually does that. But >> I'm afraid it does so at others' expense. Languages have their individual >> constraints, idioms and best practices. If parsing a protocol payload >> introduces low-level complexities and encourages to go against common >> practices, that is an invitation for problems. I am aware that my choice of >> words in the HN thread was likely to put people on defense, and for that I >> apologise. But I do believe that the choice of polymorphic JSON is going to >> make the life and use of other implementations notably less boring than >> people in general would prefer. >> >> >> >> Cheers, >> >> Mika >> >> >> >> On Mon, 26 Oct 2020 at 02:04, Fabien Imbault <fabien.imbault@gmail.com> >> wrote: >> >> Hi Dick, >> >> >> >> Well technically yes. Obviously the client can present any interface it >> seems fit. >> >> >> >> Still there's the question of the common model we want to present to the >> outside world and supported by the protocol itself (which client libraries >> all build upon). >> >> >> >> But beneath the polyphormism question, the HN debate seems on the surface >> a lot like the original xyz (polyphormism goes along with the reduced >> endpoint model) vs xauth (a bit closer to OAuth2 in spirit, and where the >> client design has more latitude). Just explained differently, by outside >> people with different agendas. >> >> >> >> Which is a bit weird because many of the critics on HN (who criticize >> polyphormism) also seem to really dislike OAuth in the first place (the >> inconsistencies are partially due to a bunch of different people >> commenting). >> >> >> >> Really to me there's no fundamental truth behind that question. It's a >> matter of preference and priorities in the design. Whatever choices we >> make, we'll have to be prepared to explain and justify them in the open, >> even to some people that will dislike pretty much whatever we do (because >> it's fun to look smart and critize without proposing alternatives). And we >> owe these answers to people like Mika, who genuinely try to make the best >> of it. >> >> >> >> Fabien >> >> >> >> Le lun. 26 oct. 2020 à 00:58, Dick Hardt <dick.hardt@gmail.com> a écrit : >> >> Hi Fabien >> >> >> >> A library developer can provide whatever abstraction layer makes sense >> for the library's target audience and language. >> >> >> >> If the client library developer wants to use polymorphism in the >> interface presented to the user's of the library, the library developer can >> do that independent of polymorphism in the protocol, and vice versa >> >> >> >> => polymorphism in the protocol has no impact on client library developers >> >> >> >> >> >> [image: Image removed by sender.]ᐧ >> >> >> >> On Sat, Oct 24, 2020 at 3:40 PM Fabien Imbault <fabien.imbault@gmail.com> >> wrote: >> >> I'm just realizing your "least to most important" might actually say the >> same as what I was trying to say. So I'm not even sure what we're arguing >> against :-) >> >> >> >> In brief my point if it wasn't clear is that we should be crystal clear >> on where we put the cursor of simplicity, because this can mean different >> things for different people and different roles. >> >> And as we see on HN we need to better explain our design choices. >> >> >> >> >> >> Le dim. 25 oct. 2020 à 00:25, Fabien Imbault <fabien.imbault@gmail.com> >> a écrit : >> >> Hi Dick, >> >> >> >> Independantly from the debate on polyphormism, I beg to differ on your >> order preference. >> >> >> >> Your assumption is that AS devs matter the most, because they're doing >> the important security implementation. But eating our own dogfood might >> help a lot to change that view. Most security issues occur because users of >> the spec are unable to deal with the complexity that is passed onto them. >> >> >> >> 99% of the people that will actually use the output of the work are >> application developers (client or RS) and their own users. >> >> >> >> Our intent as well as the protocol drive the usage. Client libraries may >> help, but they're not a silver bullet, especially because GNAP ultimately >> has no control about what people do there (for better or worse). And >> everything we do here will help get to the better part. >> >> >> >> I'm not saying we don't intend to also care about AS developers >> (beginning with ourselves) but it's a second order optimisation. And since >> it's a tendancy we're leaning towards by default, I'm pretty sure we won't >> forget that anyway. >> >> >> >> Fabien >> >> >> >> >> >> Le sam. 24 oct. 2020 à 23:50, Dick Hardt <dick.hardt@gmail.com> a écrit : >> >> I'm confused by your logic Fabien. >> >> >> >> If a client library developer wants to expose polymorphism, they can do >> that independent of what is in the protocol. >> >> >> >> I differ on who our stakeholders are. >> >> >> >> I think our stakeholders are in least to most important: >> >> >> >> - AS developer >> - RS developer >> - client developer >> - user >> >> >> >> A client library developer can expose whatever interface they want to >> simplify implementation. >> >> >> >> I list the user so that we don't lose site of a critical role. >> >> >> >> /Dick >> >> >> >> >> >> [image: Image removed by sender.]ᐧ >> >> >> >> On Fri, Oct 23, 2020 at 6:27 PM Fabien Imbault <fabien.imbault@gmail.com> >> wrote: >> >> Hi there, >> >> >> >> Let me try to approach the issue under a different light. More like a >> product manager would deal with feature selection to make it intuitive for >> its users. >> >> >> >> For most people, riding a bike is far easier than using a unicycle. Feels >> more stable. And yet it's way easier to design for a single wheel than to >> build with 2. Because then you'll need a lot more accessories (chain, chain >> ring, etc.). Even so producing a bike doesn't have to be a brittle process, >> it can be industrialized. >> >> >> >> Back to the GNAP topic. >> >> Ultimately we should strive to make the spec as simple as can be. But we >> need to ask: simple for whom? For the bike owner or for the bike vendor? >> >> (short answer: the priority should be simplicity for spec users, not spec >> implementers and even less spec designers). >> >> >> >> The initial question that is asked is very interesting: isn't the design >> flawed if GNAP is using json polyphormism? Or if the AS needs to handle the >> state of the request? Or if we must handle token revocation? Or if we are >> looking for a global unique identifier? The argument stems of the fact that >> is still arguably harder and more error prone to implement. Fair enough. >> >> >> >> From a spec implementer's perspective, it may well be more complex. It >> mostly impacts the json library you'll end up using, plus a bit of >> input/output decoration around it. Even golang provides utilities for this, >> despite not exactly being made for this kind of purpose. >> >> My practical experience implementing it is that it's not that big a deal. >> I mean, I wished it could be simpler, but it's manageable and there are >> other ways to reach levels of insurance that it does work as intended (json >> schema, test cases to validate the implementation, etc.). Arguably it is >> still easier from an implementation perspective than say, json-ld, which is >> massively used in the SSI community. >> >> >> >> But ultimately who are we designing for? Are we striving to go easy on >> the spec implementer? Or are we trying to make sure end-developers using >> the client libraries won't shoot themselves in the foot? >> >> >> >> The job to be done (JTBD), from the end-developer's perspective, is to >> efficiently ship an application. And provide authN/authZ capabilities for >> end-users by relying on some well known implementation. >> >> In turn, this spec implementer will rely on cryptographic utility >> libraries that deals internally with the complexity of their own domain, so >> that we don't have to. And here we could launch another HN flame war that >> starts with the title "JWT sucks because". Which does have its set of very >> real issues but that's beyond the point. >> >> Note that any decent flamewar will be efficiently fueled by people hating >> medium. Is it outrageous for blog posts to be behind a paywall? Maybe but >> it's even more outrageous to lack consistency, either by not knowing how to >> get around a paywall if you're into a hacker punk movement, or on the >> contrary by to not paying a subscription if you believe that surveillance >> capitalism, to reuse Zuboff's terms, should be eradicated. >> >> What likely seems an unnecessary sidenote tries to illustrate the point: >> for Justin it was easier to publish on medium, because as a blog publisher, >> you might not want to deal with hosting your own blog. But maybe as a >> reader you'll find that annoying. Different audiences, different JTBD, >> different tradeoffs. >> >> >> >> Polyphormism is a tool that enables the end-developer to have minimal >> knowledge of what it means to deal with a GNAP client library. You prepare >> the request, send to the endpoint and you're good to go. Massively simpler >> than OAuth2 or any similar protocol by the way (as anyone with teaching >> experience on the subject might acknowledge). And there's a lot more to be >> done to make sure we indeed reduce the complexity for the end-developer and >> the end-user. >> >> >> >> If we find a better way to deal with that simplicity balance, I'm all in. >> But the arguments need to be way more convincing than just saying that it >> may be difficult to implement or validate. >> >> >> >> Cheers. >> >> Fabien >> >> >> >> >> >> >> >> >> >> >> >> Le ven. 23 oct. 2020 à 22:35, Justin Richer <jricher@mit.edu> a écrit : >> >> >> >> >> >> On Oct 23, 2020, at 3:52 PM, Dick Hardt <dick.hardt@gmail.com> wrote: >> >> >> >> Justin >> >> >> >> I did note that I was the one that argued for instance_id being in the >> object. Since it is in the object in the current draft, not including a >> pass by reference option would be preferable. >> >> >> >> As for concrete examples: >> >> - version of client >> >> - version of OS >> >> - security attestation of OS / device >> >> - location of client device >> >> - network client is operating on >> >> >> >> These are all attributes of the client that an AS may require on the >> initial grant request, and in future grant requests (which is when an >> instance_id) would be used. >> >> >> >> >> >> This is where our interpretations differ: I don’t see these as >> “attributes of the client” in the same way that the key, display >> information, class identifiers, and other items currently represented by an >> instance_id are attributes of the client instance. The attestation >> components don’t modify the instance so much as present additional >> information on top of the client instance itself. This is why I argue that >> they ought to be handled in a separate object, so you’d have something like >> this strawman: >> >> >> >> { >> >> >> >> posture: { >> >> software_version: 1.2.3, >> >> os_version: 14.3.2 >> >> device_attestation: { … some structure or signed blob? … } >> >> location: { lat: …, lon: …, alt: … } >> >> }, >> >> >> >> client: “client-541-ab" >> >> >> >> } >> >> >> >> This is a more fundamental question about GNAP than whether the syntax >> uses polymorphism: this is about GNAP being very explicit about the data >> model of its elements. OAuth 2’s incredibly loose and broad model of what >> the term “client” is referring to, exactly, is deeply problematic in >> practice. We’re even seeing that in the OAuth 2.1 work with having to >> define a “credentialed client”, and even then that doesn’t fully capture >> the different aspects that are out there. I think we’re getting closer here >> in GNAP with explicit definition of “client instance”, but we still need to >> be more precise about what exactly a client instance includes, and what it >> does not. >> >> >> >> — Justin >> >> >> >> >> >> /Dick >> >> >> >> [image: Image removed by sender.]ᐧ >> >> >> >> On Fri, Oct 23, 2020 at 12:42 PM Justin Richer <jricher@mit.edu> wrote: >> >> Dick, >> >> >> >> As you’ll recall, I argued against including the client instance >> identifier inside of the object as a mutually-exclusive field precisely >> because of the principle violation that you are pointing out here, and so >> it’s important to point out that the current text is a compromise that >> needs to be examined in the wider experience of the working group. I am on >> the side of removing the mutually-exclusive “instance_id” option within an >> object, but this needs to be explored. >> >> >> >> The crux of my argument is that is exactly a case of pass-by-reference vs >> pass-by-value, and that runtime attestations are not part of the “client >> instance” value itself but rather belong outside of that object in a >> another part of the request. As stated in the editorial notes in this >> section, we need to look carefully at how these concepts fit within the >> model and where we would want to put them. Without concrete examples of >> what these extensions look like and how they’re generated, that is nearly >> impossible to do at this stage. I look forward to seeing examples of this >> kind of data and how it can fit into the protocol. >> >> >> >> — Justin >> >> >> >> On Oct 23, 2020, at 3:07 PM, Dick Hardt <dick.hardt@gmail.com> wrote: >> >> >> >> Hey Justin, >> >> >> >> As the draft has evolved, I question the continued use of polymorphism. >> Note that I appreciate the elegance of using a string for >> pass-by-reference, and an object for pass-by-value. >> >> >> >> In the current draft, the >> >> >> >> Every time you create or process a field it will mean only one thing, and >> there’s only one field to look at to answer a question. >> >> >> >> is violated in 2.3.1. Identifying the RC Instance >> <https://tools.ietf.org/html/draft-ietf-gnap-core-protocol-00#section-2.3.1> >> >> >> >> >> >> instance_id An identifier string that the AS can use to identify the >> >> particular instance of this RC. The content and structure of this >> >> identifier is opaque to the RC. >> >> >> >> "client": { >> >> "instance_id": "client-541-ab" >> >> } >> >> >> >> If there are no additional fields to send, the RC MAY send the >> >> instance identifier as a direct reference value in lieu of the >> >> object. >> >> >> >> "client": "client-541-ab" >> >> >> >> The instance identifier can be sent two ways. Polymorphism is a >> convenience for the client, but requires the server to have two code paths >> for "instance_id". We discussed this in the design team, and I argued for >> having "instance_id" in the "client" object so that any updates, such as >> new devices assertions, could be in the "client" object. As noted above, >> while I appreciate the elegance of using a string (handle) to reference a >> previously provided object, it complicates how to update an existing object >> while providing the reference. >> >> >> >> In your example of the "key" object below, setting "proof" to bearer >> would avoid the issue you describe: >> >> >> >> { >> "key": { >> "proof": "bearer" >> } >> } >> >> >> >> In your example, when processing the "key" object, code is having to >> check both the JSON type of the property, as well as check the value of the >> "proof" property. In the example I provided, only the value of "proof" >> needs to be checked. The "proof" property is acting as a type for the "key" >> object. >> >> >> >> Not being a Java programmer, I don't know how this would work in a Java >> implementation, but node.js, the processing would need to be done as above. >> >> >> >> On a related note, there was significant negative feedback on handles and >> polymorphism in the Hacker News article >> https://news.ycombinator.com/item?id=24855750 >> >> >> >> /Dick >> >> >> >> >> >> On Fri, Oct 23, 2020 at 10:20 AM Justin Richer <jricher@mit.edu> wrote: >> >> Hi Mika, >> >> >> >> Thanks for bringing this topic here — I was able to see the forum >> discussion that brought you here, and hopefully I can help clear up what I >> mean with how polymorphism is used in the proposal. The short version is >> that the goal is to *avoid* the kinds of ambiguity that make insecure >> protocols, and so in that goal we’re fully aligned. I think that using >> polymorphism in very specific ways can help that goal — just as I agree >> that misusing it or applying it sloppily can lead to ambiguous and insecure >> systems. >> >> >> >> Some background: I built out the XYZ protocol (one of the predecessors to >> the initial GNAP Draft) in Java using strongly typed parsers and Java >> objects specifically to prove to myself that it could be done in a way that >> made any sense in the code. (My own open source implementation is at >> https://github.com/bspk/oauth.xyz-java, but note that it’s not yet up to >> date with the GNAP spec). It was important to me that I be able to use the >> system-wide configured parsers to implement this and not have to resort to >> stepping through elements completely by hand. Java doesn’t make it simple >> to get the hooks into the right places (especially with the Jackson parser >> that I used), but it is definitely possible to create a deterministic and >> strongly-typed parser and serializer for this kind of data structure. Some >> of the rationale for using polymorphism is covered in the trailing appendix >> of the draft document ( >> https://www.ietf.org/archive/id/draft-ietf-gnap-core-protocol-00.html#name-json-structures-and-polymor), >> but it’s still good to discuss this here as the working group decides which >> approaches to take. >> >> >> >> The driving reason for using polymorphism at the protocol level was to >> simplify the protocol and make it :more: deterministic to create and >> process, not less. Every time you create or process a field it will mean >> only one thing, and there’s only one field to look at to answer a question. >> Without polymorphic field values, you usually need to rely on mutual >> exclusivity of fields, which is prone to failure and requires additional >> error checking. Take for example the key binding of access tokens. An >> access token could be bound to the RC’s key used during the request, to a >> different key chosen by the AS, or it could be a bearer token with no key >> at all. By making the “key” field polymorphic, we can define it in terms of >> boolean values and objects and express this set of mutually-exclusive >> options in a non-ambiguous way. Without that, you’d need to have different >> fields for the options and include additional checks in your parser to make >> sure they weren’t sent simultaneously, otherwise you could get hit with >> this potential security vulnerability in an object: >> >> >> >> { >> >> key: { >> >> proof: httpsig, >> >> jwk: { … key value … } >> >> }, >> >> bearer_token: true, >> >> bind_to_rc_key: true >> >> } >> >> >> >> This would be an illegal object as per this alternate proposal, but then >> you’d have to check each field and make sure it wasn’t put next to others >> in the same object. I’ve done this exercise with many other protocols and >> it’s both error prone and easy to ignore since all the “good” examples >> would pass code that doesn’t check this. With the polymorphic approach to >> this same field, each of these three mutually-exclusive states is written >> in a way that they cannot be sent together. It’s not just illegal, it’s >> impossible and enforced by the syntax of JSON itself. >> >> >> >> { >> >> key: { >> >> proof: httpsig, >> >> jwk: { … key value … } >> >> } >> >> } >> >> >> >> // bearer token >> >> >> >> { >> >> key: false >> >> } >> >> >> >> // bound to the RC’s presented key >> >> >> >> { >> >> key: true >> >> } >> >> >> >> If someone sends a different type for this field, like an array or number >> or a null, this doesn’t have a defined interpretation in the protocol and >> would be a protocol level error. >> >> >> >> While it might sound like polymorphism means that any field could have >> any type or value, the opposite is true: each possible value is explicitly >> typed, it’s just that there are potentially different types that express >> meaning for the field. This applies to all members of all objects >> (dictionaries) as well as all members of an array (list). Every time you >> process a field value or other element, you look at the type and then the >> value to determine what to do with that typed value. >> >> >> >> In your example below, each field within the dictionary would also need >> to be typed, and each type would need to have a clear indication of its >> meaning. To take your strawman key format below, the “modulus” field could >> be defined polymorphically as either a “bigint” (a JSON number) or an >> “encoded string” (a JSON string). The definition would further say what >> exactly the encoding of the string would be. That means that when you read >> the “modulus” field there wouldn’t be any confusion on what the value was >> or how it was represented, regardless of the input format. Seeing a number >> there means exactly one interpretation and seeing a string means exactly >> one (different) interpretation — but importantly, both of them are a >> “modulus”, since that’s the field that determines the type. An >> implementation would likely use an internal BigInteger type of object to >> represent the field value after parsing, so the question is how to go from >> the JSON value (which is typed) into the BigInteger value.You don’t just >> apply the type rules on the “public_key” field, you apply it to all >> sub-fields of that object. >> >> >> >> So let’s dig into the specific bug you bring up in the strawman, because >> it’s interesting: A JSON encoder that encodes numbers as strings, and not >> numbers, is not compliant with the JSON definitions of the field in >> question. For another example, the quoted string value of “true” is not >> equivalent to the boolean value true in JSON, and they shouldn’t be treated >> the same by a parser implementation when mapping to a concrete object. It’s >> in this kind of automated guessing that this class of bugs occur, and >> that’s going to be the case whether or not you take advantage of JSON’s >> polymorphic nature. I’ve run into cases where a parser library was trying >> to be overly “helpful” in doing this kind of mapping, but ended up >> introducing errors in more strict components downstream. This is something >> that protocol designers need to be aware of and guard against in the design >> of the protocol to reduce possible ambiguities. Within GNAP today, we >> generally have things that branch whether they’re an object (for a rich >> description of something) or some non-structured special value (for a >> reference or other item). >> >> >> >> The design team created some simple JSON Schemas for parts of the >> protocol during our discussion, but we didn’t include them in the design >> document due to both lack of time to keep it updated with the rapid changes >> to the protocol during the design team discussion, and not knowing if there >> would be interest in such material. I personally think it would be helpful >> to include as an informative reference in the final document, but that’s >> something for the working group to take up eventually. >> >> >> >> — Justin >> >> >> >> On Oct 23, 2020, at 10:18 AM, Mika Boström < >> mika.bostrom=40smarkets.com@dmarc.ietf.org> wrote: >> >> >> >> Hello, everyone. >> >> >> >> For background: GNAP/TxAuth/XYZ/Oauth3 came up on a discussion forum and >> when I made note about certain concerns, I was requested to send my >> comments to this working group. >> >> >> >> In short, I believe that the use of polymorphic JSON in the protocol >> invites subtle and confusing implementation problems. I also searched >> through the WG archives, and noticed that similar concerns were noted, >> briefly, in a thread in July. >> >> >> >> The problem with polymorphic values, as I see it, is that implementations >> will need to branch on the (inferred) type of a given field. This isn't >> quite as bad if the types are strictly different, but allows for subtle >> bugs when the value in question is a dictionary. What makes this >> unappealing is that "subtle bugs" in security protocols have a habit of >> turning into vulnerabilities. >> >> >> >> Let's say we have these imaginary payloads, both possible and valid in >> the same protocol step: >> >> >> >> # payload 1 >> >> { >> >> ..., >> >> "public_key": { >> >> "alg": "rsa", >> >> "modulus": <BIGINT> >> >> } >> >> } >> >> >> >> # payload 2 >> >> { >> >> ..., >> >> "public_key": { >> >> "alg": "rsa", >> >> "modulus": "<encoded string>" >> >> } >> >> } >> >> >> >> In both cases, the type of "public_key" field is a dictionary. In both >> cases, they even have the same keys. However, the values in the >> dictionaries are entirely different, and an implementation will have to >> branch to at least two possible decoding mechanisms. To make things worse, >> some JSON implementations may choose to encode non-dictionary values as >> strings, so it is possible for an originator to transmit what they expect >> and believe to be payload 1 format, but which the receiver will interpret >> to be in payload 2 format. And if the encoded string contains only digits, >> it will even parse correctly as a bignum. >> >> >> >> While the above is clearly a manufactured scenario, it nonetheless >> demonstrates the potential for logic bugs with polymorphic JSON. With >> richer types and more complex dictionaries, there will surely be more room >> for errors. >> >> >> >> Ambiguity in protocols is always a source of implementation complexity >> and interoperability snags, but in an AuthN/AuthZ protocol it is worse: >> it's terrifying. If GNAP/Oauth3 is intended to supersede Oauth1/2, wouldn't >> it be in everyone's interest to keep implementation complexity and mistake >> potential to a minimum? >> >> >> >> Best regards, >> >> Mika >> >> >> >> -- >> >> Mika Boström >> >> Smarkets >> >> -- >> TXAuth mailing list >> TXAuth@ietf.org >> https://www.ietf.org/mailman/listinfo/txauth >> >> >> >> -- >> TXAuth mailing list >> TXAuth@ietf.org >> https://www.ietf.org/mailman/listinfo/txauth >> >> [image: Image removed by sender.]ᐧ >> >> >> >> >> >> -- >> TXAuth mailing list >> TXAuth@ietf.org >> https://www.ietf.org/mailman/listinfo/txauth >> >> >> >> -- >> >> Mika Boström >> >> Smarkets >> >> -- TXAuth mailing list TXAuth@ietf.org >> https://www.ietf.org/mailman/listinfo/txauth >> > -- > TXAuth mailing list > TXAuth@ietf.org > https://www.ietf.org/mailman/listinfo/txauth >
- [GNAP] Feedback on polymorphism Mika Boström
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Dick Hardt
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Dick Hardt
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Dick Hardt
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Yaron Sheffer
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Yaron Sheffer
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Huang, Peter (HPE HQ)
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Yaron Sheffer
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Dick Hardt
- Re: [GNAP] Feedback on polymorphism Dick Hardt
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Mika Boström
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Yaron Sheffer
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Andrii Deinega
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Yaron Sheffer
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Dick Hardt
- Re: [GNAP] Feedback on polymorphism Fabien Imbault
- Re: [GNAP] Feedback on polymorphism Justin Richer
- Re: [GNAP] Feedback on polymorphism Fabien Imbault