Re: [OAUTH-WG] Namespacing "type" in RAR

Dick Hardt <> Tue, 21 July 2020 17:56 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id C92D93A0D35 for <>; Tue, 21 Jul 2020 10:56:34 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -0.097
X-Spam-Status: No, score=-0.097 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, PDS_OTHER_BAD_TLD=1.999, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=no autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id AnnNKrmRmvxZ for <>; Tue, 21 Jul 2020 10:56:31 -0700 (PDT)
Received: from ( [IPv6:2a00:1450:4864:20::22d]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id A27F13A0D31 for <>; Tue, 21 Jul 2020 10:56:30 -0700 (PDT)
Received: by with SMTP id j11so25018602ljo.7 for <>; Tue, 21 Jul 2020 10:56:30 -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=En0SZSMd/2C5hpzXoxl26Jk+IJSgXFeaBAKCjm55ZVs=; b=CRhs5Rfv/c9dsETuwlJiY4GZDrqrCc1+b8JWDIUog0bqCmbhsxBn/3Wh+2q60mnymq cFjBI6XfjeK+8jCDf2BgAGpYlIn4LLoq240mWSGsL95/QRYjuP7oWXxBEXqGdSGp3NKK OKS6lgvux57MuSfLikM5X/0yVboJRoHs23c/LjMIX1p//X4QLavup1QJqX9l0kOTv5eM lX804hmu1wXpnatUBHn8Aqw9XL3vTTxpk6ivTh2G+gptxg02kzNOdqWIjUaPXlwEmCzy haOSYfEi4OR3RnOKbFiUQhqbqRg8mpCjOmVDIuOd1Z19cdmJX83nwvZAqExuparkB/eW OT7w==
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=En0SZSMd/2C5hpzXoxl26Jk+IJSgXFeaBAKCjm55ZVs=; b=T4hgiC0ayr+yN8vj2+i3LfZb6IUPqHlIBJvdmWdGyOTI8NjLPeHG46rV4wfCp8HOBf iJ9gHvkak8YWJM8eukwDgCEgoElBiTanaYXJ1+sgzaHJJ95PTxnWTqisN6A1dVHAthaL Ies5g/wJ0CM7Zy+7rJe4cV0j6zSjuWTa44SFB2i/xbmC8qS0SJwnw/vXqhMU0BPD+PVj ZW+vpjRaLjkERl9qTZa09NMZTr/ZZA+jIXlBvf+nsxF3E8M0UbwOGF5JQl4+ZPqoBSS5 tlipQrWvgPfL8F0YVqb/vPZ8YNgtLP260p4NPhzGppyltZd16qJzkyS5cmSPI+vaN1s7 0Eew==
X-Gm-Message-State: AOAM533J8TaAJSi9CdtLyaimxtHdnQ/2Efd6OXbLzyuWA/e7ECkg3efn PgRgBuc+SmXXhV2nGuAOh6qeUuAsF+yORHSoUujDPtRo
X-Google-Smtp-Source: ABdhPJwXq5hpHpnpSdtGKmmVrm1VHRB0oO1hhI6T/ShV0ZtojSYYmSgaZhapjXxUbQWX/eJcXmf07nQ9WLx/wmsFbdE=
X-Received: by 2002:a2e:80c9:: with SMTP id r9mr13740867ljg.69.1595354188674; Tue, 21 Jul 2020 10:56:28 -0700 (PDT)
MIME-Version: 1.0
References: <> <> <> <> <> <> <> <> <> <> <>
In-Reply-To: <>
From: Dick Hardt <>
Date: Tue, 21 Jul 2020 10:55:52 -0700
Message-ID: <>
To: Justin Richer <>
Cc: oauth <>
Content-Type: multipart/alternative; boundary="000000000000b4fb7e05aaf757e7"
Archived-At: <>
Subject: Re: [OAUTH-WG] Namespacing "type" in RAR
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Tue, 21 Jul 2020 17:56:35 -0000

In unicode, a glyph can be represented by more than one code point. When
reading the docs and entering a value, the developer will not know which
code point the AS intended.

Are you suggesting that AS documentation would have the bytes rather than
glyphs? Or not use glyphs that have multiple code points? Or that they only
use english?

On Tue, Jul 21, 2020 at 10:34 AM Justin Richer <> wrote:

> Right, and I’m saying that all three of those would be DIFFERENT “type”
> values, because they’re different strings. The fact that when treated as
> URIs they would be equivalent is irrelevant. Just like “foo”, “Foo”, and
> “FOO” would be different “type” values, per the spec. Nothing is stopping
> an AS from treating them as equivalent internally, but that seems a bit
> dangerous to me. I’d love to see a formal breakdown of that, though.
> As for the unicode example, if we define things as using byte comparisons,
> then that becomes an issue for proper documentation and configuration — and
> again, probably a good place to have recommendations for picking type value
> strings so as to avoid such problems.
> In short, I don’t think we should have any requirements on
> canonicalization for these values.
>  — Justin
> On Jul 21, 2020, at 1:03 PM, Dick Hardt <> wrote:
> The following are the same URI, but are different strings:
> “”
> “HTTPS:// <>”
> “https://SCHEMA.EXAMPLE.ORG/v1 <>”
> Before comparing them to each other, they must be canonicalized so that
> they become the same string.
> From earlier in this thread, I am NOT suggesting that it must be a URI,
> nor that it is required:
> Since the type represents a much more complex object then a JWT claim, a
> client developer's tooling could pull down the JSON Schema (or some such)
> for a type used in their source code, and provide autocompletion and
> validation which would improve productivity and reduce errors. An AS that
> is using a defined type could use the schema for input validation. Neither
> of these would be at run time. JSON Schema allows comments and examples.
> What is the harm in non-normative language around a retrievable URI?
> On Tue, Jul 21, 2020 at 9:58 AM Justin Richer <> wrote:
>> String comparison works just fine when the strings happen to be URIs, and
>> you aren’t treating them as URIs:
>> “”
>> Is different from
>> “”
>> And both are different from
>> “ <>/“
>> All of these are strings, and the strings happen to be URIs but that’s
>> irrelevant to the comparison process. Can you please help me understand why
>> doing a string comparison on these values does not work in exactly the same
>> way it would for “foo”, “bar”, and “baz” values? Why would these need to be
>> canonicalized to be compared? The definition of a JSON string is an ordered
>> set of unicode code points, and this can be compared byte-wise. (Or
>> code-point-wise, whatever’s most correct here.) Can you give me
>> counter-examples as to where string comparison doesn’t work? And can you
>> help me understand how this same worry doesn’t apply to all of the rest of
>> the values in the RAR specification, which are also strings and will need
>> to be compared?
>> I’m still very confused as to the URI retrieval issue here, if there even
>> is one. It sounds like we’re both saying that it could be useful if type
>> values are retrievable when they’re URIs, but that would be something to
>> augment a process and not required for the RAR spec. I’m against requiring
>> the value to be a URI and against requiring the AS to process that URI *as
>> a URI* at runtime. Anything that an AS wants to do with the “type”
>> value, including providing additional tooling and validation, is up to the
>> AS and outside of the spec.
>>  — Justin
>> On Jul 21, 2020, at 12:35 PM, Dick Hardt <> wrote:
>> This statement:
>> “compare two strings so that they’re exact”
>> does not work for either Unicode or URIs. A string, and a canonicalized
>> Unicode string are not the same thing. Similar for a URI. I have assumed
>> you understand the canonicalization requirement, but it does not sound like
>> you do. Would you like examples?
>> wrt. the AS and URI, *you* keep saying that *I* said the AS would
>> retrieve the URI. I HAVE NOT SAID THAT!
>> I am suggesting that the URI MAY be retrievable, and I gave examples on
>> how that would be useful for tooling for client developers, and for an AS
>> in doing input validation. The URI would NOT be retrieved at run time.
>> On Tue, Jul 21, 2020 at 7:35 AM Justin Richer <> wrote:
>>> If we treat all the strings as just strings, without any special
>>> internal format to be specified or detected, then comparing the strings is
>>> a well-understood and well-documented process. I also think that we
>>> shouldn’t invent anything here, so if there’s a better way to say “compare
>>> two strings so that they’re exact” then that’s what I mean. Sorry if that
>>> was unclear.
>>> I’m saying the AS should *not* retrieve the URI passed in the “type”
>>> value. You brought that up and then described the process that the AS would
>>> take to do so. I have said from the start that the use of a URI is for name
>>> spacing and not for addressing content to be fetched, so I’m confused why
>>> you think I intend otherwise.
>>>  — Justin
>>> On Jul 20, 2020, at 2:59 PM, Dick Hardt <> wrote:
>>> Canonicalization of URIs and unicode is fairly well specified. I was not
>>> suggesting we invent anything there.
>>> A byte comparison, as you suggested earlier, will be problematic, as I
>>> have pointed out.
>>> I'm confused why you are still talking about the AS retrieving a URI.
>>> ᐧ
>>> On Mon, Jul 20, 2020 at 4:42 AM Justin Richer <> wrote:
>>>> Since this is a recommendation for namespace, we could also just say
>>>> collision-resistant like JWT, and any of those examples are fine. But that
>>>> said, I think there’s something particularly compelling about URIs since
>>>> they have somewhat-human-readable portions. But again, I’m saying it should
>>>> be a recommendation to API developers and not a requirement in the spec. In
>>>> the spec, I argue that “type” should be a string, full stop.
>>>> If documentation is so confusing that developers are typing in the
>>>> wrong strings, then that’s bad documentation. And likely a bad choice for
>>>> the “type” string on the part of the AS. You’d have the same problem with
>>>> any other value the developer’s supposed to copy over.  :)
>>>> I agree that we should call out explicitly how they should be compared,
>>>> and I propose we use one of the handful of existing string-comparison RFC’s
>>>> here instead of defining our own rules.
>>>> While the type could be a dereferenceable URI, requiring action on the
>>>> AS is really getting into distributed authorization policies. We tried
>>>> doing that with UMA1’s scope structures and it didn’t work very well in
>>>> practice (in my memory and experience). Someone could profile “type" on top
>>>> of this if they wanted to do so, with support at the AS for that, but I
>>>> don’t see a compelling reason for that to be a requirement as that’s a lot
>>>> of complexity and a lot more error states (the fetch fails, or it doesn’t
>>>> have a policy, or the policy’s in a format the AS doesn’t understand, or
>>>> the AS doesn’t like the policy, etc).
>>>> And AS is always free to implement its types in such a fashion, and
>>>> that could make plenty of sense in a smaller ecosystem. And this is yet
>>>> another reason that we define “type” as being a string to be interpreted
>>>> and understood by the AS — so that an AS that wants to work this way can do
>>>> so.
>>>>  — Justin
>>>> PS: thanks for pointing out the error in the example in XYZ, I’ll fix
>>>> that prior to publication.
>>>> On Jul 18, 2020, at 8:58 PM, Dick Hardt <> wrote:
>>>> Justin: thanks for kindly pointing out which mail list this is.
>>>> To clarify, public JWT claims are not just URIs, but any
>>>> collision-resistant namespace:
>>>> "Examples of collision-resistant namespaces include: Domain Names,
>>>> Object Identifiers (OIDs) as defined in the ITU-T X.660 and      X.670
>>>> Recommendation series, and Universally Unique IDentifiers (UUIDs)
>>>> [RFC4122]."
>>>> I think letting the "type" be any JSON string and doing a byte-wise
>>>> comparison will be problematic. A client developer will be reading
>>>> documentation to learn what the types are, and typing it in. Given the wide
>>>> set of whitespace characters, and unicode equivalence, different byte
>>>> streams will all look the same, and a byte-wise comparison will fail.
>>>> Similarly for URIs. If it is a valid URI, then a byte-wise comparison
>>>> is not sufficient. Canonicalization is required.
>>>> These are not showstopper issues, but the specification should call out
>>>> how type strings are compared, and provide caveats to an AS developer.
>>>> I have no idea why you would think the AS would retrieve a URL.
>>>> Since the type represents a much more complex object then a JWT claim,
>>>> a client developer's tooling could pull down the JSON Schema (or some such)
>>>> for a type used in their source code, and provide autocompletion and
>>>> validation which would improve productivity and reduce errors. An AS that
>>>> is using a defined type could use the schema for input validation. Neither
>>>> of these would be at run time. JSON Schema allows comments and examples.
>>>> What is the harm in non-normative language around a retrievable URI?
>>>> BTW: the example in
>>>> has
>>>> not been updated with the "type" field.
>>>> On Sat, Jul 18, 2020 at 8:10 AM Justin Richer <> wrote:
>>>>> Hi Dick,
>>>>> This is a discussion about the RAR specification on the OAuth list,
>>>>> and therefore doesn’t have anything to do with alignment with XAuth. In
>>>>> fact, I believe the alignment is the other way around, as doesn’t Xauth
>>>>> normatively reference RAR at this point? Even though, last I saw, it uses a
>>>>> different top-level structure for conveying things, I believe it does say
>>>>> to use the internal object structures. I am also a co-author on RAR and we
>>>>> had already defined a “type” field in RAR quite some time ago. You did
>>>>> notice that XYZ’s latest draft added this field to keep the two in
>>>>> alignment with each other, which has always been the goal since the initial
>>>>> proposal of the RAR work, but that’s a time lag and not a display of new
>>>>> intent.
>>>>> In any event, even though I think the decision has bearing in both
>>>>> places, this isn’t about GNAP. Working on RAR’s requirements has brought up
>>>>> this interesting issue of what should be in the type field for RAR in OAuth
>>>>> 2.
>>>>> I think that it should be defined as a string, and therefore compared
>>>>> as a byte value in all cases, regardless of what the content of the string
>>>>> is. I don’t think the AS should be expected to fetch a URI for anything. I
>>>>> don’t think the AS should normalize any of the inputs. I think that any
>>>>> JSON-friendly character set should be allowed (including spaces and
>>>>> unicodes), and since RAR already requires the JSON objects to be
>>>>> form-encoded, this shouldn’t cause additional trouble when adding them in
>>>>> to OAuth 2’s request structures.
>>>>> The idea of using a URI would be to get people out of each other’s
>>>>> namespaces. It’s similar to the concept of “public” vs “private” claims in
>>>>> JWT:
>>>>> What I’m proposing is that if you think it’s going to be a
>>>>> general-purpose type name, then we recommend you use a URI as your string.
>>>>> And beyond that, that’s it. It’s up to the AS to figure out what to do with
>>>>> it, and RAR stays out of it.
>>>>>  — Justin
>>>>> On Jul 17, 2020, at 1:25 PM, Dick Hardt <> wrote:
>>>>> Hey Justin, glad to see that you have aligned with the latest XAuth
>>>>> draft on a type property being required.
>>>>> I like the idea that the value of the type property is fully defined
>>>>> by the AS, which could delegate it to a common URI for reuse. This gets
>>>>> GNAP out of specifying access requests, and enables other parties to define
>>>>> access without any required coordination with IETF or IANA.
>>>>> A complication in mixing plain strings and URIs is the
>>>>> canonicalization. A plain string can be a fixed byte representation, but a
>>>>> URI requires canonicalization for comparison. Mixing the two requires URI
>>>>> detection at the AS before canonicalization, and an AS MUST do
>>>>> canonicalization of URIs.
>>>>> The URI is retrievable, it can provide machine and/or human readable
>>>>> documentation in JSON schema or some such, or any other content type. Once
>>>>> again, the details are out of scope of GNAP, but we can provide examples to
>>>>> guide implementers.
>>>>> Are you still thinking that bare strings are allowed in GNAP, and are
>>>>> defined by the AS?
>>>>> On Fri, Jul 17, 2020 at 8:39 AM Justin Richer <> wrote:
>>>>>> The “type” field in the RAR spec serves an important purpose: it
>>>>>> defines what goes in the rest of the object, including what other fields
>>>>>> are available and what values are allowed for those fields. It provides an
>>>>>> API-level definition for requesting access based on multiple dimensions,
>>>>>> and that’s really powerful and flexible. Each type can use any of the
>>>>>> general-purpose fields like “actions” and/or add its own fields as
>>>>>> necessary, and the “type” parameter keeps everything well-defined.
>>>>>> The question, then, is what defines what’s allowed to go into the
>>>>>> “type” field itself? And what defines how that value maps to the
>>>>>> requirements for the rest of the object? The draft doesn’t say anything
>>>>>> about it at the moment, but we should choose the direction we want to go.
>>>>>> On the surface, there are three main options:
>>>>>> 1) Require all values to be registered.
>>>>>> 2) Require all values to be collision-resistant (eg, URIs).
>>>>>> 3) Require all values to be defined by the AS (and/or the RS’s that
>>>>>> it protects).
>>>>>> Are there any other options?
>>>>>> Here are my thoughts on each approach:
>>>>>> 1) While it usually makes sense to register things for
>>>>>> interoperability, this is a case where I think that a registry would
>>>>>> actually hurt interoperability and adoption. Like a “scope” value, the RAR
>>>>>> “type” is ultimately up to the AS and RS to interpret in their own context.
>>>>>> We :want: people to define rich objects for their APIs and enable
>>>>>> fine-grained access for their systems, and if they have to register
>>>>>> something every time they come up with a new API to protect, it’s going to
>>>>>> be an unmaintainable mess. I genuinely don’t think this would scale, and
>>>>>> that most developers would just ignore the registry and do what they want
>>>>>> anyway. And since many of these systems are inside domains, it’s completely
>>>>>> unenforceable in practice.
>>>>>> 2) This seems reasonable, but it’s a bit of a nuisance to require
>>>>>> everything to be a URI here. It’s long and ugly, and a lot of APIs are
>>>>>> going to be internal to a given group, deployment, or ecosystem anyway.
>>>>>> This makes sense when you’ve got something reusable across many
>>>>>> deployments, like OIDC, but it’s overhead when what you’re doing is tied to
>>>>>> your environment.
>>>>>> 3) This allows the AS and RS to define the request parameters for
>>>>>> their APIs just like they do today with scopes. Since it’s always the
>>>>>> combination of “this type :AT: this AS/RS”, name spacing is less of an
>>>>>> issue across systems. We haven’t seen huge problems in scope value overlap
>>>>>> in the wild, though it does occur from time to time it’s more than
>>>>>> manageable. A client isn’t going to just “speak RAR”, it’s going to be
>>>>>> speaking RAR so that it can access something in particular.
>>>>>> And all that brings me to my proposal:
>>>>>> 4) Require all values to be defined by the AS, and encourage
>>>>>> specification developers to use URIs for collision resistance.
>>>>>> So officially in RAR, the AS would decide what “type” means, and
>>>>>> nobody else. But we can also guide people who are developing
>>>>>> general-purpose interoperable APIs to use URIs for their RAR “type”
>>>>>> definitions. This would keep those interoperable APIs from stepping on each
>>>>>> other, and from stepping on any locally-defined special “type” structure.
>>>>>> But at the end of the day, the URI carries no more weight than just any
>>>>>> other string, and the AS decides what it means and how it applies.
>>>>>> My argument is that this seems to have worked very, very well for
>>>>>> scopes, and the RAR “type” is cut from similar descriptive cloth.
>>>>>> What does the rest of the group think? How should we manage the RAR
>>>>>> “type” values and what they mean?
>>>>>>  — Justin
>>>>>> _______________________________________________
>>>>>> OAuth mailing list