I’ll start by saying that if you compare
https://tools.ietf.org/html/draft-campbell-oauth-sts-02 and
https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-02, 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.)
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 [mailto:[email protected]]
Sent: Tuesday, July 07, 2015 4:47 PM
To: Mike Jones
Cc: Brian Campbell; <[email protected]>
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
<[email protected]<mailto:[email protected]>> wrote:
As just updated<http://self-issued.info/?p=1412>, I believe that the working
group token exchange draft
https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-02 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-token and
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 [mailto:[email protected]] On Behalf Of Brian Campbell
Sent: Thursday, March 26, 2015 3:15 PM
To: Justin Richer
Cc: <[email protected]<mailto:[email protected]>>
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
http://tools.ietf.org/html/draft-campbell-oauth-sts-02 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
<[email protected]<mailto:[email protected]>> 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
[email protected]<mailto:[email protected]>
https://www.ietf.org/mailman/listinfo/oauth
_______________________________________________
OAuth mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/oauth