Re: [OAUTH-WG] JWT profile and IdentityServer

Vittorio Bertocci <> Mon, 04 May 2020 08:20 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id D74773A0147 for <>; Mon, 4 May 2020 01:20:18 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Status: No, score=-2.098 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, HTML_MESSAGE=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id l4Dmf04MADnk for <>; Mon, 4 May 2020 01:20:16 -0700 (PDT)
Received: from ( [IPv6:2607:f8b0:4864:20::430]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id AF9463A0112 for <>; Mon, 4 May 2020 01:20:16 -0700 (PDT)
Received: by with SMTP id 145so5163513pfw.13 for <>; Mon, 04 May 2020 01:20:16 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=google; h=from:to:subject:thread-topic:thread-index:date:message-id :references:in-reply-to:accept-language:content-language :mime-version; bh=cK9V0UG38Eb2u+jUJLw/p7tzimJVbNebAo0mVNToEXg=; b=TGbh5ZSfdhPcE1sjs/yywvvJhGpkDW355FTM3mj8vXAiamTwaOTFJ0Eu0X9m/NB7i+ V5kirxt+0xO6tr/cZmPu6NeD96sNNJS6/pjJY62RZyCu2ZOdQSBqRKdN7Cj+H4LrFhgh VQUJvcMvMwKH1awLRqo6+J/+XtMrE3FM4M83heJTH93HsNcscqu03tm0BNLRCnwHQrzM deL4TBLYmlkIcqBZw2NvLWN+qFXIXDhpTLGzxxEsdSUiu4+AURAt+AO+RNqZMWP8EDQs QLagtIw3x1edwb6Y7JlBPKVoUvG4xC+jne9fVjPDFe2eQ7RjuxPI+C9SjB9fYiQNqx9c 2brg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:from:to:subject:thread-topic:thread-index:date :message-id:references:in-reply-to:accept-language:content-language :mime-version; bh=cK9V0UG38Eb2u+jUJLw/p7tzimJVbNebAo0mVNToEXg=; b=bi5cwCir6KZZmjRtiS0BVW6UvTl3o/xbBAEwWmNx6jcDOaWtPXbx7lloofoRpAEWMl KYp5Bceb0zgKyD0ix9isYDc6oyKyBVht5F6oIOcCXWo6QG5txB0d4zPi2EjmPq+EhMIp 4dcqy9aXXk0pmTsA38voNbLYevKMnD23VMijX+zJwD0nD1/JkyWjlU+6V8vmmpBIpmhR V1ASWvrs8zN8lCSdpWuMhOcEhHqUtMlF42pOfIl4ydnsAvaLvvzs3L9v9+GNrCXPqTuB pAUWHexC3fglAEnTPtpk03OQAqRMRTsm3g7RAlFLWwdKK56CwK6V8dHOY8UKYjDrCS5x 34oQ==
X-Gm-Message-State: AGi0Puaoo0rpSVvm4g+9gDYfepX7ZM3DXQAXtnAa0WRRFGDVOzFoIIyl IzXvvOF9KAOQ0wo4zaZfYraRtw==
X-Google-Smtp-Source: APiQypKqzp0gXFY3HZ3/hmPvk25S+8C5ih4q02dMUWZzfhFlDOTDJVzUqai6QpdBxUhrJeeNeRa8Sw==
X-Received: by 2002:aa7:9546:: with SMTP id w6mr16445217pfq.114.1588580415549; Mon, 04 May 2020 01:20:15 -0700 (PDT)
Received: from ([2603:1036:120:1d::5]) by with ESMTPSA id l64sm6553201pjb.44.2020. (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 May 2020 01:20:15 -0700 (PDT)
From: Vittorio Bertocci <>
To: Dominick Baier <>, "" <>
Thread-Topic: JWT profile and IdentityServer
Thread-Index: AVE9N2dzbaeCGd3GrvweciKl9BMni4nJatxf
X-MS-Exchange-MessageSentRepresentingType: 1
Date: Mon, 4 May 2020 08:20:14 +0000
Message-ID: <>
References: <>
In-Reply-To: <>
Accept-Language: en-US
Content-Language: en-US
X-MS-Exchange-Organization-SCL: -1
X-MS-Exchange-Organization-RecordReviewCfmType: 0
Content-Type: multipart/alternative; boundary="_000_MWHPR19MB1501DD31A0B6743C680D3382AEA60MWHPR19MB1501namp_"
MIME-Version: 1.0
Archived-At: <>
Subject: Re: [OAUTH-WG] JWT profile and IdentityServer
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: Mon, 04 May 2020 08:20:19 -0000

Thank you Dominick, very useful!
I’d like to understand more about the security risks you mention. My goal is not to change your mind on the implementatio, just to make sure I better understand the general implication.
>* the user info endpoint needs to do extra checking
This is an interesting use case. Often the token issued for the userinfo is formatless, given that it is colocated within the AS, but I can see how using JWT for your own userinfo might be useful if you don’t particularly care about token size or you don’t want to handle an internal token format/reference.
Could you expand on the security risk? Either the sub doesn’t correspond to a user, or if it does, the AS itself was the issuer hence it had full control of whether a sub for a user would end up in a token obtained via client creds grant… the main way I can see this going south would be if the developer is allowed to place an arbitrary sub value, but in that case the issue seem larger (eg in a grant including a user, placing the sub of another user).

>* extension grants that did not use to present users
Technically we are still not presenting users- the sub is the authenticated subject, which can be a user or an app. Here I am channeling the consensus that was reached after quite a few back and forths, see
But besides the nitpicking. Could you expand on the extension grants you are thinking of, and how they’d be affected?
>* token exchange scenarios
This is another really interesting point. I admit I haven’t studied the RFC and I might be remembering an older version, but I believe the specs referred to principals, which aren’t necessarily human; and I remember one dev from the community describing a scenario where he would have liked to be able to do OBO with machine identities, and his scenario was reasonable.
Is there anything specific that breaks in your implementation of token exchange if you have a sub not corresponding to a user?

>* enforce a collision domain for sub and client_id
If your product allows developers to arbitrarily set values for one or both of those, I totally see how enforcement would be extra work! I would argue that in that case perhaps you don’t have to, if the user can set arbitrary values they can already do things that would break standards (like assigning the same sub to two different users) hence in that case you can’t be responsible for it at product design, it’s kind of up to them.

Note, I know that answering the above might require extra work in investigating and writing about it, I don’t mean to burden you with it. My aim here is understanding whether the challenges you identified mostly stem from the underlying assumption “presence of a sub=>it’s a user”, which is understandable but was established in the discussions referenced above not to be enough to violate 7519, or if there are other factors at play that introduce challenges when sub is used that way.
Thanks again for putting time in checking this and considering implementing it!

From: Dominick Baier <>
Date: Monday, May 4, 2020 at 00:36
To: "" <>rg>, "" <>
Subject: JWT profile and IdentityServer


Just some notes on applying the JWT profile to IdentityServer

* we emit the at+jwt typ - that’s very useful
* we emit iat in addition to nbf (if we would remove nbf, we would break the .NET JWT library from Microsoft - I guess that’s the reason AAD emits it as well)
* we have an option to emit scope as a space delimited string (we used a string array for historic reasons - also because that’s how the claims plumbing in .NET prefers it)

* aud

Audience is optional in IdentityServer if you request scopes that do not have an association to a resource. I personally think this is the right way to go. You can “force” an audience even for this situation if you absolutely want to

* sub vs client_id

In IdentityServer access tokens that do not have a user present, do not have a sub claim - only client_id. If there is a user present, sub ALWAYS represents the user.

I was prototyping a setting to emit the sub claim for situation where there is no user, which would not be hard to do - but we found out that there are many situations where this would need VERY THOROUGH testing of all the various flows to not introduce subtle security bugs

* the user info endpoint needs to do extra checking
* extension grants that did not use to present users
* token exchange scenarios
* enforce a collision domain for sub and client_id

This could all be sorted probably if I would have enough time right now - but the bottom line is, that this ambiguity and special casing requires careful re-writing and I guess this applies to any reasonably complex system that is already out there. So I am still not sold that the “dual purpose” claims are the best choice. YMMV.

IOW - we will not adopt the sub/client_id semantics as proposed by the document.

My 2c / cheers
Dominick Baier