Re: [OAUTH-WG] Alignment of JWT Claims and Token Introspection "Claims"

Justin Richer <> Thu, 05 March 2015 13:15 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id 854E51B2A41 for <>; Thu, 5 Mar 2015 05:15:45 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -4.211
X-Spam-Status: No, score=-4.211 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=ham
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id oTVIz2065Jcj for <>; Thu, 5 Mar 2015 05:15:36 -0800 (PST)
Received: from ( []) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 81CA51A1A38 for <>; Thu, 5 Mar 2015 05:15:35 -0800 (PST)
X-AuditID: 12074424-f79356d000004839-52-54f856f58960
Received: from ( []) (using TLS with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by (Symantec Messaging Gateway) with SMTP id 89.1C.18489.6F658F45; Thu, 5 Mar 2015 08:15:34 -0500 (EST)
Received: from ( []) by (8.13.8/8.9.2) with ESMTP id t25DFXk0008568; Thu, 5 Mar 2015 08:15:33 -0500
Received: from [] ( []) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by (8.13.8/8.12.4) with ESMTP id t25DFVoE002289 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT); Thu, 5 Mar 2015 08:15:32 -0500
Message-ID: <>
Date: Thu, 05 Mar 2015 08:15:24 -0500
From: Justin Richer <>
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0
MIME-Version: 1.0
To: Hannes Tschofenig <>, Mike Jones <>
References: <> <2A7D9B45-2459-4558-8356-CAB1029D113D@MIT.EDU> <>, <> <> <> <> <>
In-Reply-To: <>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjleLIzCtJLcpLzFFi42IR4hTV1v0W9iPE4OJRVoulO++xWuyd9onF 4uTbV2wOzB6LN+1n81iy5CeTR+uOv+wBzFFcNimpOZllqUX6dglcGfdOL2ctmLqIsaLxw0nG BsZrDYxdjJwcEgImEvdfNLFC2GISF+6tZ+ti5OIQEljMJDHh/29mCGcDo8TXB+/YIZxbTBK9 EzazgbTwCqhJvPzyEGwUi4CqxO3598FGsQHZ09e0MIHYogJREj1/uqHqBSVOznzCAmKLCKRI HJ52AqyeWUBdovf3SjBbWCBAYsW2k6wQy14ySXxf9gesgROo6PXa78wQDWYSXVu7GCFseYnm rbOZJzAKzkKyYxaSsllIyhYwMq9ilE3JrdLNTczMKU5N1i1OTszLSy3SNdfLzSzRS00p3cQI Cm52F5UdjM2HlA4xCnAwKvHwztj4PUSINbGsuDL3EKMkB5OSKG+w8Y8QIb6k/JTKjMTijPii 0pzU4kOMEhzMSiK8e0OBcrwpiZVVqUX5MClpDhYlcd5NP/hChATSE0tSs1NTC1KLYLIyHBxK Ery+II2CRanpqRVpmTklCGkmDk6Q4TxAw5eBDS8uSMwtzkyHyJ9iVJQS500Gpg8hAZBERmke XC8s+bxiFAd6RZj3PUg7DzBxwXW/AhrMBDRYSwxscEkiQkqqgVGkuSDbTzZBMrvP+8XxRSlR J5WOsqp+ehsiY8VnpWR9uI1906EV23tbCg7cm8/+tC0/f9e5bdrbjx58EmbZxXFfzXHmpxXn Uw81lZV+WR++bhrL2/ymqUYGIa6SOp8Ulqy9v2DnuRvNpksDWuMvJyrz+wX8mr1sM+uFiVuF xe0qVsfpvE+zWKnEUpyRaKjFXFScCADaWZH8GQMAAA==
Archived-At: <>
Cc: "<>" <>
Subject: Re: [OAUTH-WG] Alignment of JWT Claims and Token Introspection "Claims"
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: OAUTH WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Thu, 05 Mar 2015 13:15:45 -0000


You're on the right track: the "active" claim *is* effectively a top 
level toggle, much like an error message would be. However, we're taking 
the same approach that token revocation uses and returning an HTTP OK 
response with the information inside instead of an HTTP error. This was 
decided (in both cases) because the HTTP request itself is not in error, 
nor is there any error state on the server, it's returning information 
about the object requested. It's actually up to the RS to determine what 
to do with that in its response back to the client.

Furthermore, in many cases, the RS *can't* know and *shouldn't* know how 
or why the AS makes that determination, just like the client *can't* and 
*shouldn't* know how the AS generates a token value itself. The client 
just knows that one was created, or not, in response to an authorization 
request. Likewise, the RS in this case just knows that the token was 
good, or not, in response to an introspection request. This type of 
black-box interoperability is exactly what standards are about and is 
not hand-wavy at all. In fact, it's telling you exactly what it says on 
the tin without needlessly disclosing details (leading to a potential 
oracle attack from an RS fishing for tokens). It's the simplest thing 
that could possibly work, and it's been shown to work and interoperate 
between vendors for years in production.

If you're building an RS and you're outsourcing AS functionality 
entirely, then you need to trust that the AS is going to give you the 
right answer when you ask the question "is this token any good?", which 
is what's going on here. You as the developer might or might not care 
how the AS came to that conclusion, but, importantly, it doesn't matter 
for the protocol how that decision was reached. We can provide guidance 
for AS developers as in the text that I suggested earlier in this 
thread, but prescribing behavior beyond that isn't helpful.

If you think the definition itself can be more clearly articulated, 
please propose updated text for us to include.

  -- Justin

On 3/5/2015 7:53 AM, Hannes Tschofenig wrote:
> Hi Justin,
> in a security specification we should be able to say exactly what the
> semantic of a certain attribute is.
> What I expect happening today is that many organizations provide both
> resource server and authorization server and agree in an out-of-band
> fashion what the meaning of that value is. This is why we don't hear
> back from implementers at this point in time.
> This is, however, not the purpose of standardization. We want to develop
> a spec that allows two different vendors to plug their stuff together
> and it works without having to agree (out of band) what the semantic if
> the different fields is.
> We have already seen in OAuth that vague text does not increase security.
> If the purpose of the active claim is only to say that the AS did some
> checks without further indicating what it actually did then we could as
> well use the fact that there has been a response to the request (rather
> than an error message) as well. That seems to be roughly the level of
> semantic we are at with this at the moment.
> I hope you understand that I have to push back on these hand-wavy ideas
> since otherwise we need profiles in other organizations that explain
> what the IETF OAuth documents really mean.
> Ciao
> Hannes
> On 03/05/2015 01:23 PM, Justin Richer wrote:
>> The "active" claim boils down to the AS saying "Do I think this token is
>> any good or not?" and it's really up to the AS how it determines that.
>> Our own implementation does a data store lookup on the token value. If
>> it finds the token, then the token is active. If the token had been
>> revoked, or expired, then it wouldn't have come out of the data store in
>> the first place, and it's not active. I've seen others do the same thing.
>> Other stateless implementations are going to probably parse the token
>> itself and do things like check claims and signatures to see if the
>> token's any good. Or they might decrypt the token at the AS (assuming in
>> this example that it was encrypted using the AS's key) and dig inside
>> the protected structure that's not available to the RS. Once it's inside
>> that structure the AS can figure out if the token's active or not, and
>> tell the RS.
>> Or there might be a combination of the two where the AS parses the token
>> and checks its signature and then uses some key field in the token to
>> look up more information in a data store. If all that checks out then
>> the token is active, probably.
>> And the AS might want to do other checks, like see if this particular RS
>> is even allowed to ask about this particular token.
>> It is not, however, just a sanity check across other claims already
>> embedded in the token -- you could very easily use an unstructured
>> token. In fact, that's the world that this was first deployed in back
>> 4-5 years ago.
>> The important thing is that as far as the RS is concerned, the AS did
>> *some* check on the token and came back with a thumbs up / thumbs down
>> response. The thumbs up response can contain other information as well,
>> such as scopes and client IDs and whatnot, which can help the RS make
>> its authorization decision. But at its core, the "active" claim
>> fundamentally says "is this token any good at all, according to the AS
>> that I asked?" and the RS can make its primary authorization decision
>> based on that. If the RS has made the decision to outsource the token
>> validity check to the AS, then the RS either understands or doesn't care
>> what checks the AS makes in its decision regardless of implementation or
>> vendor. Either way, it will abide by them since that's the whole point
>> of outsourcing that decision.
>> And I think you're too quick to dismiss the lack of confusion on the
>> part of developers, considering that they are in fact the target
>> audience of specifications like this. If we're not writing these
>> documents for developers, who are we writing them for?
>>   -- Justin
>> On 3/5/2015 3:39 AM, Hannes Tschofenig wrote:
>>> Hi Mike, Hi Justin,
>>> I guess you agree with me that fundamentally the JWT and the token
>>> introspection solve the same problem, namely to provide the
>>> authorization server with information that it can use to make an
>>> authorization decision. The difference is only in the way how the
>>> message flows.
>>> Now, to the argument that developers have not yet complained about the
>>> underspecified claims/attributes is not particularly good. We tend to
>>> hear about complains years later when things go wrong and then we cannot
>>> change them anymore.
>>> Tell me for the active claim what type of checks the authorization
>>> server is supposed to do.
>>> If the authorization server and the resource server are provided by
>>> different parties then it is important to be clear about what checks
>>> each of the two parties are supposed to be doing. If the active claim
>>> aims to outsource the authorization decision from the resource server to
>>> the authorization server then that's a completely different story than
>>> just doing some basic sanity check on some of the JWT claims.
>>> Ciao
>>> Hannes
>>> On 03/05/2015 08:36 AM, Mike Jones wrote:
>>>> It sounds to me like you're making a good argument for this spec to have
>>>> its own registry.  Registries are easy to establish and use.
>>>> ------------------------------------------------------------------------
>>>> From: Justin Richer <>
>>>> Sent: ‎3/‎4/‎2015 6:43 PM
>>>> To: Mike Jones <>; Hannes Tschofenig
>>>> <>
>>>> Cc: <> <>
>>>> Subject: Re: [OAUTH-WG] Alignment of JWT Claims and Token Introspection
>>>> "Claims"
>>>> I'm actually fine with keeping the introspection-specific elements out
>>>> of the registry (see my note on "active" and how it doesn't fit in JWT
>>>> below), but I do not want to give up the short names. The short names
>>>> are already in production, especially "active", which is well understood
>>>> and used in practice today, and has been for years[1]. Changing this
>>>> would fundamentally break all existing implementations for no good
>>>> reason. I'm slightly more OK with changing "user_id" to "username",
>>>> since that's not as widely deployed to my knowledge (other implementers,
>>>> please pipe up if I'm mistaken), and I'm well familiar with
>>>> "preffered_username" in OIDC because I'm the one that put it in there
>>>> [2]. :) While I prefer to leave it be at this stage, I think this is a
>>>> less destructive change than "active", "scope", or "client_id" would be.
>>>> For background to my stance regarding the registry: several revisions
>>>> (and years) ago, the introspection draft re-defined several fields that
>>>> overlapped with JWT and we were asked to correlate the two. Originally,
>>>> we simply had a pointer to re-use the JWT claims as defined, and stacked
>>>> our own claims on top. Later, we were asked to outright merge them,
>>>> which is what we have right now. If the WG wants to back off that last
>>>> change to the middle state -- where we re-use the JWT registry but don't
>>>> write to it -- I'm very happy with that result and can work that (back)
>>>> into the next draft.
>>>> Though it does point out something strange about the standards process
>>>> that we're running into here: JWT needed a place to register bits of
>>>> metadata about a token, so it created one. This became the "JWT
>>>> registry", and now it's got hangings of being "JWT-specific". When
>>>> introspection came along with a need to talk about much the same kind of
>>>> information, it makes sense to re-use the existing items but also that
>>>> there would be things that are introspection-specific.
>>>>    -- Justin
>>>> [1]
>>>> [2]
>>>> On 3/4/2015 6:28 PM, Mike Jones wrote:
>>>>> I have severe concerns with this approach.  It’s not appropriate to
>>>>> register arbitrary JSON object member names as JWT claim names –
>>>>> especially when the JSON object member names are not even being used
>>>>> as JWT claim names.  *Please do not do this*, as it would needlessly
>>>>> pollute the JWT claim name namespace with registered names that are
>>>>> application specific.
>>>>> Secondarily, I have concerns about these names and suggestions for how
>>>>> to address them.
>>>>> “active” – This claim is not presently adequately defined.  And its
>>>>> definition will of necessity be specific to the introspection
>>>>> application.  Therefore, it should not be registered as a general JWT
>>>>> claim name.  A name I would be comfortable with for this concept would
>>>>> be urn:ietf:params:oauth:introspection:active, since it makes it clear
>>>>> what application the name is used with.
>>>>> “user_id” – The concept you’re describing is almost universally called
>>>>> “username”.  User ID is typically the numeric account identifier
>>>>> (carried in the “sub” claim in a JWT), and so is not the right name
>>>>> for this.  Compare it to the preferred_username claim in OpenID
>>>>> Connect.  Please change this either to “username” or
>>>>> urn:ietf:params:oauth:introspection:username.
>>>>> “token_type” – While this is well-defined, the usage is fairly
>>>>> specific to this application.  Again, adding the
>>>>> urn:ietf:params:oauth:introspection: name prefix would address this
>>>>> issue.
>>>>> If you give up registering these names in the JWT Claims registry, I’m
>>>>> OK with you using short names.  But if you want them to live alongside
>>>>> other JWT claim names, please include the
>>>>> urn:ietf:params:oauth:introspection: in lieu of registration.
>>>>>                                                               Thank you,
>>>>>                                                               -- Mike
>>>>> *From:*OAuth [] *On Behalf Of *Justin
>>>>> Richer
>>>>> *Sent:* Wednesday, March 04, 2015 1:46 PM
>>>>> *To:* Hannes Tschofenig
>>>>> *Cc:* <>
>>>>> *Subject:* Re: [OAUTH-WG] Alignment of JWT Claims and Token
>>>>> Introspection "Claims"
>>>>> Hi Hannes, thanks for the feedback. Responses inline.
>>>>>       On Mar 3, 2015, at 5:56 AM, Hannes Tschofenig
>>>>>       < <>>
>>>>> wrote:
>>>>>       Hi Justin, Hi all,
>>>>>       in OAuth we provide two ways for a resource server to make an
>>>>>       authorization decision.
>>>>>       1) The resource server receives a self-contained token that
>>>>>       contains all
>>>>>       the necessary information to make a local authorization
>>>>> decision. With
>>>>>       the JWT we have created such a standardized information and data
>>>>>       model.
>>>>>       2) With an access request from a client the resource server
>>>>> asks the
>>>>>       authorization server for "help". The authorization server provides
>>>>>       information that help make the authorization decision. This is the
>>>>>       token
>>>>>       introspection approach.
>>>>>       I believe the two approaches need to be aligned with regard to the
>>>>>       information and the data model. Since both documents already use
>>>>>       JSON as
>>>>>       a way to encode information (=data model) and almost have an
>>>>> identical
>>>>>       information model (the data that is being passed around).
>>>>>       What needs to be done?
>>>>>       * Use the term 'claims' in both documents.
>>>>>       * Use the same registry (i.e., the registry established with
>>>>> the JWT).
>>>>>       * Register the newly defined claims from the token introspection
>>>>>       document in the claims registry.
>>>>> We’ve already done this in the latest draft. Or at least, that’s the
>>>>> intent of the current text — the registry is referenced and the new
>>>>> claims are registered. Can you specifically point to places where this
>>>>> needs to be improved upon?
>>>>> Then, I have a few comments on the new claims that are proposed:
>>>>> Here is the definition of the 'active' claim:
>>>>>     active
>>>>>        REQUIRED.  Boolean indicator of whether or not the presented
>>>>> token
>>>>>        is currently active.  The authorization server determines whether
>>>>>        and when a given token is in an active state.
>>>>> This claim is not well-defined. You need to explain what "active"
>>>>> means.
>>>>> It could, for example, mean that the token is not yet expired. Then,
>>>>> there is of course the question why you are not returning the 'exp'
>>>>> claim together with the 'nbf' claim.
>>>>> The definition of “active” is really up to the authorization server,
>>>>> and I’ve yet to hear from an actual implementor who’s confused by this
>>>>> definition. When you’re the one issuing the tokens, you know what an
>>>>> “active” token means to you. Still, perhaps we can be even more
>>>>> explicit, such as:
>>>>>       active
>>>>>         REQUIRED. Boolean indicator of whether or not the presented
>>>>>       token is currently active. The specifics of a token’s active state
>>>>>       will vary depending on the implementation of the authorization
>>>>>       server, but generally this will indicate that a given token has
>>>>>       been issued by this authorization server, has not been revoked by
>>>>>       the resource owner, and is within its given time window of
>>>>>       validity (e.g. not expired).
>>>>> Also, this is one of the places where the overlap between JWT and
>>>>> introspection claims don’t make sense. It doesn’t make any sense for a
>>>>> JWT to carry an “active” claim at all. Why would you have a JWT claim
>>>>> to be anything but active? We should register it with the JWT registry
>>>>> to avoid name collisions, but there’s nothing in the JWT registry that
>>>>> says “don’t use this inside of a JWT”. Do you have any advice on how
>>>>> to address this?
>>>>> client_id: What is the resource server going to do with the client_id?
>>>>> What authorization decision could it make?
>>>>> Whatever it wants to. If an RS can figure out something from the
>>>>> client_id, why not let it? The client_id is a piece of information
>>>>> about the context of the issuance of the token, and a common enough
>>>>> OAuth value for decision making.
>>>>> I have a couple of reactions when I read the 'user_id' claim:
>>>>>    - I believe the inclusion of a user id field in the response could
>>>>> lead to further confusion regarding OAuth access token usage for
>>>>> authentication.
>>>>> This isn’t any different from having a userinfo-endpoint equivalent
>>>>> (like social graph or twitter API) and it’s got the same trouble.
>>>>>    - Since you define it as a human readable identifier I am wondering
>>>>> whether you want to say something about the usage. Here it seems
>>>>> that it
>>>>> might be used for displaying something on a webpage rather than making
>>>>> an authorization decision but I might well be wrong.
>>>>> We added in “user_id” to our implementation due to developer demand —
>>>>> they wanted a username associated with the return value, but to leave
>>>>> the “sub” value the same as that defined by OpenID Connect. Note that
>>>>> this is in an environment where the username is a known quantity, and
>>>>> they’re not trying to do cross-domain authentication. They just want
>>>>> to know whose token this was so they can figure out whose data to
>>>>> return. It’s not used for display, but I tried to make the definition
>>>>> in contrast to the machine-facing “sub” value.
>>>>>    - I am missing a discussion about the privacy implications of it.
>>>>> While there is a privacy consideration section I am wondering what
>>>>> controls the release of this sensitive information from the
>>>>> authorization server to the resource server. While in some cases the
>>>>> two
>>>>> parties might belong to the same organization but in other cases that
>>>>> may not necessarily be true.
>>>>> You’re correct, this is currently missing and I’ll add that in.
>>>>>    - In terms of the information exchanged about the user I am curious
>>>>> about the usefulness of including other information as well, such as
>>>>> the
>>>>> info that is included in an id token (see
>>>>> If this
>>>>> has nothing to do with the ID token concept and the information carried
>>>>> within it then I would add that remark.
>>>>> You could introspect an ID token if you wanted to, but it’s usually
>>>>> easier to just parse it yourself because it’s self-contained. The ID
>>>>> Token also extends JWT, so there’s nothing stopping you from returning
>>>>> those claims as well. However, note that the audience of the ID token
>>>>> is the OAuth *client* whereas the targeted user of the introspection
>>>>> endpoint is the *protected resource*. The PR isn’t going to see the ID
>>>>> Token most of the time, and the client’s not going to need to (or be
>>>>> able to) introspect its tokens most of the time, so in practice
>>>>> there’s not really any overlap.
>>>>>    — Justin
>>>>> Ciao
>>>>> Hannes
>>>>> _______________________________________________
>>>>> OAuth mailing list
>>>>> <>