Re: [OAUTH-WG] Token Chaining Use Case

Justin Richer <> Wed, 08 July 2015 11:41 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id 4F9D71B34B4 for <>; Wed, 8 Jul 2015 04:41:02 -0700 (PDT)
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 Ajp9XrxZSbrb for <>; Wed, 8 Jul 2015 04:40:58 -0700 (PDT)
Received: from ( []) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 480A91B34D0 for <>; Wed, 8 Jul 2015 04:40:52 -0700 (PDT)
X-AuditID: 1209190c-f79296d000000622-52-559d0c436643
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 45.80.01570.34C0D955; Wed, 8 Jul 2015 07:40:51 -0400 (EDT)
Received: from ( []) by (8.13.8/8.9.2) with ESMTP id t68BeoLm024586; Wed, 8 Jul 2015 07:40:50 -0400
Received: from artemisia.richer.local ( []) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by (8.13.8/8.12.4) with ESMTP id t68Bem3l010339 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 8 Jul 2015 07:40:49 -0400
Content-Type: text/plain; charset=windows-1252
Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2098\))
From: Justin Richer <>
In-Reply-To: <>
Date: Wed, 8 Jul 2015 07:40:47 -0400
Content-Transfer-Encoding: quoted-printable
Message-Id: <>
References: <> <> <> <> <> <>
To: Sergey Beryozkin <>
X-Mailer: Apple Mail (2.2098)
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42IRYrdT0XXmmRtqsGyFoMXJt6/YLP4ttXdg 8tg56y67x5IlP5kCmKK4bFJSczLLUov07RK4MlZ+72IteFFScX5HL2sD45/ILkZODgkBE4nt XY8YIWwxiQv31rN1MXJxCAksZpJY/+sfE4SzgVFi5uwmRgjnAZPEzu/XWUFamAX0JHZc/wVm 8wLZj54+ZgexhQX0JZZv7wOLswmoSkxf08IEYnMKaEr8nd8Eto5FQEXi2dYvLF2MHEBz1CXa T7pAjNSWWLbwNTPESCuJo61P2SH2vmSSWPRlOth8EaCii69vsYP0SgjISnzdKjeBUXAWkotm IbloFpKxCxiZVzHKpuRW6eYmZuYUpybrFicn5uWlFuka6uVmluilppRuYgSFL6ckzw7GNweV DjEKcDAq8fB6xMwJFWJNLCuuzD3EKMnBpCTKG/cIKMSXlJ9SmZFYnBFfVJqTWnyIUYKDWUmE 9zzn3FAh3pTEyqrUonyYlDQHi5I476YffCFCAumJJanZqakFqUUwWRkODiUJXhUuoEbBotT0 1Iq0zJwShDQTByfIcB6g4WbcIMOLCxJzizPTIfKnGHU5WhbfWMskxJKXn5cqJc6rAVIkAFKU UZoHNweWdl4xigO9JcwbAFLFA0xZcJNeAS1hAlqyXHcWyJKSRISUVANjG5+ia5iJ0n6l1XIe TZ2MMt17rireLpiQXhW80yZnRxGHyaP0PM/1f9/9lJn0/+TRa6k/3ytHfz61f3XiaguX8iyL L67L2lsSj5YLzw4S++r94/tGS/We1f1i8d6Vf9KsTr27utzj8VlxFdG7CmcfM3BuWM9gyCZW x6Xd2ffnzuLTU9qsP0UosRRnJBpqMRcVJwIAtp0MSRYDAAA=
Archived-At: <>
Cc: "<>" <>
Subject: Re: [OAUTH-WG] Token Chaining Use Case
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: Wed, 08 Jul 2015 11:41:02 -0000

The HTTP *request* should be able to be covered by a JWT signature, and that should be applicable to any interaction with the token endpoint. I’m aware that Nat’s draft is talking about the authorization endpoint, but the same logic could be applied here at the token endpoint. It could actually even be easier there because we could simply specify that the Content-Type of the input POST is application/jwt and the payload of said JWT simply contains all the parameters to the token endpoint. Orthogonal functionality that meshes well together.

Brian’s draft puts everything as a parameter, including the input token (which can be arbitrary — the requester doesn’t need to know what’s in the tokens at all). This could easily be turned wholesale into an input JWT using the transform just described.

The current draft is a weird halfway state where some input parameters are in a JWT that’s passed as an input parameter alongside other things that are outside the JWT. I don’t think that works particularly well, and I think there’s a better, simpler solution that solves all of these use cases and then some.

 — Justin

> On Jul 8, 2015, at 5:26 AM, Sergey Beryozkin <> wrote:
> Hi,
> On 08/07/15 01:41, Mike Jones wrote:
>> I’ll start by saying that if you compare
>> and
>> unsurprisingly, you’ll find a lot in common.  Both have requests and
>> responses formatted using JSON objects, both have input and output
>> tokens, both have security token type parameters describing their
>> corresponding inputs and outputs.  Both can convey act_as and
>> on_behalf_of tokens.  And despite what was written below, both define a
>> new grant_type value that is used to make this new kind of request at
>> the Token Endpoint.
>> The primary thing that Brian’s draft is missing semantically is the
>> ability for the requester to sign the set of input parameters.  This is
>> critical to establishing proper trust to enable the exchange to occur in
>> many use cases.  That’s why the WG draft uses a JWT as the request – so
>> a signature can be applied to the request, when appropriate.  (And when
>> it’s not needed, “alg”: “none” can be used.)
> The requester is a client talking to the token endpoint and this client needs to authenticate, why it needs to sign the token-exchange related parts too ?

> Thanks, Sergey
>> Justin, you’re right that the current WG draft doesn’t have a separate
>> “input token” request parameter.  In the current draft, the (optionally)
>> signed request **is** the input token.  Thinking some more about the
>> token chaining use case you’re interested in, I see why you want to have
>> that token to be a separate element in the request.  I believe the best
>> way to accomplish that is to add an optional claim to the request that
>> would contain that token.  (I think the closest equivalent in Brian’s
>> draft is the possibility of using an access token or assertion as the
>> client authentication mechanism, possibly passing it as defined in RFC
>> 6750, although the draft doesn’t say that.)  Passing the input token as
>> a claim lets it be part of the signed request.
>> It’s completely up to us when using a different grant_type to define
>> what the input and output parameters when using that grant_type are.
>> (RFC 6749 already has different sets, depending upon the grant_type
>> used.)  I personally find it cleaner to return the output security token
>> that may not be an access token in a “security_token” parameter rather
>> than repurposing the “access_token” parameter to hold something that’s
>> not an access token, but now we’re more discussing syntax than
>> semantics.  Still, if something is different, it’s probably less error
>> prone to use a different syntax for it.
>> I’m sympathetic to your comment about Nat’s signed requests draft,
>> except that the requests that draft specifies are requests to the
>> interactive Authorization Endpoint, whereas the requests we’re dealing
>> with here are requests to the non-interactive Token Endpoint.  Still,
>> thinking of the Token Exchange requests as signed requests to the Token
>> Endpoint, just like Nat’s draft makes signed requests to the
>> Authorization Endpoint, is probably a good unifying mental framework for
>> all of us to consider applying to this problem space.
>>                                                                 Best
>> wishes,
>>                                                                 -- Mike
>> *From:*Justin Richer []
>> *Sent:* Tuesday, July 07, 2015 4:47 PM
>> *To:* Mike Jones
>> *Cc:* Brian Campbell; <>
>> *Subject:* Re: [OAUTH-WG] Token Chaining Use Case
>> This approach is not a good fit for my use cases, and it’s still not
>>  OAuth-y at all. It requires a specially-formed security assertion on
>> the way in, which the client must understand and generate. I still can’t
>> take an arbitrary token I’ve been handed by someone else and pass it off
>> to be pushed forward. The new “*_type” parameters seem to merely kick
>> the can down the road instead of addressing the problems with the
>> current specification.
>> I think that Brian’s approach works much better. It unrolls important
>> parameters, properly uses the token endpoint, and allows for arbitrarily
>> formatted input tokens.
>> When combined with Nat’s draft that specifies how to perform all generic
>> OAuth requests as JWTs (or even some of the upcoming PoP work if we ever
>> do that), you’ve pretty much got the draft below but with much more
>> flexibility and power.
>>  — Justin
>>    On Jul 7, 2015, at 6:51 PM, Mike Jones <
>>    <>> wrote:
>>    As just updated <>, I believe that
>>    the working group token exchange draft
>> can
>>    now also serve the “OAuthy” token exchange use cases, such as Justin
>>    and Phil’s token chaining use case, as well as support general token
>>    exchange, including exchange of JWT and SAML tokens.  The mechanism
>>    would be the same one that Brian suggested below – defining security
>>    token type values for OAuth 2.0 access tokens and refresh tokens –
>>    enabling them to be used as inputs and outputs in any of the token
>>    exchanges.
>>    For instance, by using “access token” as the input security token
>>    type, providing new scope values, and using “access token” as the
>>    output security token type, token chaining is achieved.
>>    Now, a question for the working group…  What should the security
>>    token type values for access token and refresh token be?  Two
>>    different choices seem to make sense.
>>    (1)  Use the values “access_token” and “refresh_token”, which are
>>    used in RFC 6749 token response values.
>>    (2)  Define new URNs for this usage, such as
>>    urn:ietf:params:oauth:token-type:access-tokenand
>>    urn:ietf:params:oauth:token-type:refresh-token.
>>    I’d personally be fine just using the short names in (1).
>>    If people agree with this approach, we can document this usage in
>>    the -03 draft and publish it as soon as the submission tool reopens
>>    Monday morning during IETF 93.
>>                                                                     -- Mike
>>    *From:*OAuth [] *On Behalf Of *Brian
>>    Campbell
>>    *Sent:* Thursday, March 26, 2015 3:15 PM
>>    *To:* Justin Richer
>>    *Cc:* < <>>
>>    *Subject:* Re: [OAUTH-WG] Token Chaining Use Case
>>    This kind of token exchange might involve exchanges other than
>>    swapping an AT for another AT (and downscoping it). It might be an
>>    AT for a structured JWT specifically targeted at one of the the
>>    particular services that the original RS needs to call. Or an AT
>>    might be exchanged for a SAML assertion to use with legacy SOAP
>>    serveries.  A good general token exchange mechanism enables lots of
>>    variations of cases like the one Justin mentioned. And more. In
>>    fact, I think downscoping might be a minority use case where what
>>    token exchange is often need for is translating tokens from what you
>>    have into what the resource you need to call can deal with.
>>    There need to be ways for the caller to tell the AS about the token
>>    it's asking for - by type or by the address/identifier of where
>>    it'll be used. There needs to be ways for the caller to authenticate
>>    to the AS. And there needs to be some way of expressing this
>>    delegation thing (though I'm still not totally convinced it couldn't
>>    be just the token is about the user/principal and the caller/client
>>    of the exchange is who is being delegated to).
>>    I realize few (approaching zero) people have or are going to read it
>>    but I have endeavored to cover all these things in the
>> draft. It's
>>    an early draft so not without it some rough edges but can provide
>>    some guidance on what is needed and offers some protocol syntax for
>>    expressing it. I believe Justin's use case would be covered by it
>>    (defining a specific token type URI for an OAuth access token issued
>>    by the AS in question might be needed) as are many others.
>>    On Thu, Mar 26, 2015 at 1:31 PM, Justin Richer <
>>    <>> wrote:
>>    As requested after last night’s informal meeting, here is the token
>>    chaining use case that I want to see represented in the token swap
>>    draft.
>>    [ Client ]  ->   [ A ] -> [ B ] -> [ C ]
>>    An OAuth client gets an access token AT1, just like it always would,
>>    with scopes [A, B, C] in order to call service A, which requires all
>>    three scopes. Service A (an RS) accepts this token since it has its
>>    scope, and then needs to call service B in turn, which requires
>>    scopes [B, C]. It could just re-send the token it got in, AT1, but
>>    that would give the downstream RS the ability to call services with
>>    scope [ A ] and it should not be allowed to do that. To limit
>>    exposure, service A calls a token swap at the AS to create AT2 with
>>    scopes [ B, C ], effectively acting as an OAuth client requesting a
>>    downscoped token based on AT1. Service A then acts as an OAuth
>>    client to call service B, now acting as an RS to service A’s client,
>>    and can fulfill the request. And it’s turtles all the way down:
>>    Service B can also call service C, and now B acts as a client,
>>    requesting AT3 with scope [ C ] based on AT2, and sending AT3 to
>>    service C. This prevents C from being able to call B or A, both of
>>    which would have been available if AT1 had been passed around. Note
>>    that service A or the Client can also request a downscoped token
>>    with [ C ] to call service C directly as well, and C doesn’t have to
>>    care how it got there.
>>    In other words, it lets the client software be very, very dumb. It
>>    doesn’t have to do any special processing, doesn’t have to know
>>    what’s in the token, it just follows the recipe of “I got a token, I
>>    get another token based on this to call someone else”. It’s also
>>    analogous to the refresh token flow, but with access tokens going in
>>    and out. I’ve deployed this setup several times in different service
>>    deployments. Even though there is a performance hit in the
>>    additional round trips (as Phil brought up in another thread), in
>>    these cases the desire to have the tokens hold least privilege
>>    access rights (smallest set of scopes per service) outweighed any
>>    performance hit (which was shown to be rather small in practice).
>>    What I want is for the token swap draft to define or use a mechanism
>>    that allows us to do this. I think we can do that pretty easily by
>>    adjusting the token swap syntax and language, and explicitly calling
>>    out the semantic processing portion (the current core of the
>>    document) for what it is: a way for a token issuer to communicate to
>>    a token service specific actions. At a high level, the spec would be
>>    something like:
>>    1. How to swap a token at an AS
>>       1. Send a request to the token endpoint with a new grant type,
>>    and a token (of any type/format/flavor) on the way in
>>       2. Get back a new token in a token response
>>    2. Communicating act as / on behalf of semantics via a JWT assertion
>>       1. How to create (as an AS/RS/client/other issuer) a JWT with
>>    act-as semantics
>>       2. What to do (as an AS/RS) with a JWT with act-as semantics
>>       3. How to create a JWT with on-behalf-of semeantics
>>       4. What to do with a JWT with on-behalf-of-semantics
>>       5. How to possibly represent these semantics with something other
>>    than a JWT
>>    Section 2 uses the syntax from section 1. Other applications, like
>>    the one I laid out above, can use the syntax from section 1 as well.
>>    This works for structured, unstructured, self-generated,
>>    cross-domain, within-domain, and other tokens.
>>      — Justin
>>    _______________________________________________
>>    OAuth mailing list
>> <>
>> _______________________________________________
>> OAuth mailing list
> -- 
> Sergey Beryozkin
> Talend Community Coders
> Blog:
> _______________________________________________
> OAuth mailing list