Re: RAR Structures for VC HTTP API

I appreciate Justin's explanation. I have some experience with
sophisticated and extensible APIs in the form of the HL7 FHIR standards for
health records https://www.hl7.org/fhir/ . This represents a huge
investment by a particular industry and it is then adopted as part of
regulation
https://www.healthit.gov/isa/united-states-core-data-interoperability-uscdi

Please try to imagine the difficulty in achieving interoperability as well
as security through data minimization and least-privilege using OAuth
scopes.

My point with respect to VC-HTTP API and SSI standards in general, is that
our work is not industry-specific to healthcare or education. It is not
specific to VCs that have no expiration date like a medical license and
will be presented hundreds of times or that become irrelevant in a day like
a boarding pass and will be presented twice.

These are the reasons why Justin and I, from rather different real-world
experience, are working on GNAP and hoping this work will be adopted by the
SSI community.

- Adrian



On Wed, Jul 21, 2021 at 11:18 AM Mahmoud Alkhraishi <mahmoud@mavennet.com>
wrote:

> Thanks Justin.
> I feel like I thought I got your points during your initial presentation
> but this email really made it click, I appreciate that you keep driving
> this.
>
>
>
> On Jul 21, 2021, at 10:59 AM, Orie Steele <orie@transmute.industries>
> wrote:
>
> 
> Thanks Justin, these examples are very helpful. It seems like the primary
> value of RAR is extensibility. Objects are easier to extend than strings.
>
> I want to understand the security tradeoffs by leveraging these
> extensibility features. Your identifier security parameter example is very
> helpful.
>
> In that case, are you not exposing that identifier to the AS? Why does the
> AS need to know which DIDs a resource server can issue/present on behalf of?
>
> It would seem safe to make use of the extensibility as long as you don't
> leak subject identifiers to the AS, can you comment on these design
> considerations?
>
> I'm on my phone sorry for any spelling.
>
> OS
>
> On Wed, Jul 21, 2021, 9:42 AM Justin Richer <jricher@mit.edu> wrote:
>
>> On yesterday’s call, we briefly discussed the applicability of RAR for
>> the VC HTTP API, and I wanted to continue that conversation with some
>> additional concrete points. Apologies in advance for the long email, but
>> there’s a lot to untangle here as it seems a number of people have the
>> wrong idea.
>>
>> First, what are we proposing? I am suggesting, strongly, that when
>> defining this API, the group also define the different ways to control
>> access to it. Which is to say, what actions can you do, what kinds of data
>> do you want to switch on — in short, we’ve got an API, how do we want to
>> slice it? I am explicitly saying that we do not define anything about the
>> process of getting a token (so, specifying client credentials is a terrible
>> idea) or how to process the token (so specifying token formats is also a
>> terrible idea) because these don’t affect the API. What does affect the API
>> is the availability of different kinds of actions for a specific call. What
>> are the things that I can DO here?
>>
>> This is what OAuth 2 invented scopes for, instead of the OAuth 1 or HTTP
>> Basic method of “you just get everything”. So, why not just use
>> parameterized scopes? It seemed like a good idea when I first invented it a
>> decade ago: https://blue-button.github.io/blue-button-plus-pull/#scopes or
>> when it got pulled into other efforts like
>> https://openid.net/specs/openid-heart-fhir-oauth2-1_0-2017-05-31.html …
>> and Orie even suggested the following set of parameterized scopes for this
>> API:
>>
>>             'create:credentials': Grants permission to create credentials
>>             'derive:credentials': Grants permission to derive credentials
>>             'create:presentations': Grants permission to create presentations
>>             'verify:presentations': Grants permission to verify presentations
>>             'exchange:presentations': Grants permission to exchange presentations
>>
>> So what’s the problem? I can say with full confidence after years of
>> experience building and deploying systems to support parameterized scopes
>> like this that they are fragile, awkward, and lead to insecure corner
>> cases. For example, am I supposed to parse these strings to find the bits
>> on either side of that colon? Am I allowed to make up my own combinations
>> of elements, so for example do I get “derive:presentations” from that set
>> above, for free? What if I am protecting more than one API and they use a
>> different separator? Or what if there’s just a plain old namespace
>> collision and someone else has “exchange:presentations” on their unrelated
>> API that that the AS is protecting at the same time? And what if someone
>> has an additional dimension they need to convey, like the identifier for a
>> specific account— does that mean we add a parameter to the string above, or
>> do we need a separate scope to carry this, and how do we combine all of
>> that? While all of these questions can be answered, the answers make
>> something that seems simple on the surface spiral out of hand very quickly.
>> I know this because I’ve seen it time and again, and this experience is
>> exactly what led me to create what has become RAR.
>>
>> So let’s talk about how we’d address the above actions in RAR. First,
>> please note that I’m going to be fast and loose with JSON syntax here
>> because I’m typing it out by hand, so don’t try to compile this. :) Second,
>> for simplicity of following this argument, let’s say that all five actions
>> above are inside a single RAR type value, and we’ll just use “vha" as the
>> stand-in for that value (in reality it would be a URI, and there might be
>> multiple for a given API family like VC HTTP API).
>>
>> Picking apart the pieces above, we’ve got two elements that fit fairly
>> well into the “actions” and “datatypes” fields in a RAR request type:
>>
>> actions: [ create, derive, verify, exchange ]
>> datatypes: [ credentials, presentations ]
>>
>> Since RAR is about combining different dimensions into a single request,
>> we can easily get to the kind of expressions above. Let’s say I want to
>> create credentials and permissions, but nothing else — I can ask for the
>> following value:
>>
>>
>> {
>> type: “vha”,
>> actions: [ create ],
>> datatypes: [ credentials, presentations ]
>> }
>>
>> Or if I want to create and derive credentials but do nothing with
>> presentations, I can do:
>>
>> {
>> type: “vha”,
>> actions: [ create, derive ],
>> datatypes: [ credentials ]
>> }
>>
>> And how about a more complex cross-product? Let’s say I want to create
>> and derive credentials but only exchange presentations. All RAR requests
>> are in an array, just like OAuth 2 scopes are fundamentally an array, so
>> that request would look like this:
>>
>> [
>>
>> {
>> type: “vha”,
>> actions: [ create, derive ],
>> datatypes: [ credentials ]
>> },
>> {
>> type: “vha”,
>> actions: [ exchange ],
>> datatypes: [ presentations ]
>> }
>>
>> ]
>>
>> Unlike with scopes, the extent of each aspect is clear to developers of
>> both the API and the clients of the API. It’s very clear what I’m asking to
>> do and what I’m doing it to, without having to define or parse or
>> understand any kind of VC-HTTP-API-specific syntax to cram into an existing
>> field. This gets even better with GNAP because you can ask for multiple
>> different-scoped tokens at the same time.
>>
>> And what if someone requests a confusing or bad combination?
>>
>> {
>> type: “vha”,
>> actions: [ create, derive ],
>> datatypes: [ credentials, presentations ]
>> }
>>
>> RAR clearly defines each object as the union of all items within it, so
>> anything processing this would be able to tell that “derive” and
>> “presentations” doesn’t fit together and this is an invalid request.
>> There’s no need to guess and no need to put in special casing. Your
>> implementation would be configured with viable combinations, and anything
>> that falls outside of that is easily detected.
>>
>> It gets even clearer if we want to talk about other dimensions not
>> captured in the example scopes above. If I want to do this for a specific
>> account? We can define a security identifier in this request to contain
>> that information:
>>
>> {
>> type: “vha”,
>> actions: [ create, derive ],
>> datatypes: [ credentials ],
>> identifier: did:example:12345
>> }
>>
>> Already we’re doing something that would be difficult with scope strings.
>>
>> And what if we are protecting multiple APIs that use similar syntax? They
>> sit in separate namespaces so there is no chance for confusion.
>>
>> [
>>
>> {
>> type: “vha”,
>> actions: [ create, derive ],
>> datatypes: [ credentials ]
>> },
>> {
>> type: “TOTALLY-NOT-VHA”,
>> actions: [ create, derive ],
>> datatypes: [ credentials ],
>> not-a-vha-attribute: do-some-weird-thing
>> }
>>
>> ]
>>
>> What does this mean for the VC HTTP API itself? It means that each call
>> defined as part of the API would have a section like:
>>
>> Security:
>> Type: “vha”
>> Action: “create”
>> Datatype: “credentials"
>>
>> … and that’s all the detail that would be needed. The core part of the
>> spec would say something like “use the fields defined in the ’security’
>> section to make a RAR or GNAP request”, and that only applies if you’re
>> doing OAuth 2 (with any flow) or GNAP (with any mode). You’re still free to
>> protect the API with whatever fancy pants thing you want, but even then the
>> Security section will lay out the core dimensions that each call is
>> differentiated on.
>>
>> So yes, it’s possible to pull this off with scope strings. I’ve done
>> things more complex than this and have seen some really crazy stuff like
>> using a fully-qualified query language as the scope string value. However,
>> what I’m trying to convince this group is that there is a much simpler way
>> and that’s by embracing the object structures that RAR lets you define, to
>> talk about the dimensions of access that you want to allow or disallow.
>> That discussion is going to happen anyway, and is probably ALREADY
>> happening. I am saying this group should embrace that challenge as part of
>> the protocol definition, and do so sooner rather than later. If we wait,
>> it’ll end up a mess of proprietary solutions that don’t want to change, and
>> people will dig in their heels even more for either a loose spec or
>> patchwork of things so implementations don’t have to change.
>>
>> What I’m calling for is structure for interoperability and compatibility,
>> in a way that’s a very, very light lift on the spec itself and would in
>> fact help define the elements of the spec. Believe me — I’ve been down this
>> road before and I am hoping that this group could learn from my mistakes
>> instead of repeating them.
>>
>>  — Justin
>>
>

Received on Wednesday, 21 July 2021 15:34:06 UTC