Thanks for sending this, and sorry again for not having seen it in time. The danger of a) filtering email directly into a folder and b) getting a lot of email… Yikes.
I actually have a V1.0 swimlane along with the swimlane I sent out, so if you respond with answers to my questions below, I can correct the new one and send out both for comparison. I found the exercise of doing endpoint-specific swimlanes valuable.
This looks pretty close. Some comments below.
Since I wasn't able to make the call, let me try to lay it out end
to end for people to see what I'm talking about:
0) Alice sets up a relationship between RS and AS, just like UMA
says to do today. Done, no big deal.
1) Bob tells his client to access a resource, the resource says
"no", and points bob's client at the AS along with a ticket (which
should be passed in the response header, but that's another issue)
2) Bob's client registers with the AS (dynamically on its own, or by
pestering bob to email an admin and do it the hard way, whatever).
3) Bob's client then sends a request to the token endpoint using a
*new* OAuth grant type, let's call it grant_type=uma_authorization
(in reality it's a URI but work with me here). The ticket is passed
as another parameter, since it's just a simple string.
4) The combination of the client's own credentials and the ticket
are sufficient to start the token request process for Bob's client.
5) As this is a call to the token endpoint, the client can even ask
for a specific set of scopes, just like it could with a refresh
token or other backchannel grant types.
6) The AS decides that it needs to know more about Bob before it can
issue a token, so it responds with "need_info" to the client.
Bob's client then figures out a way to get those claims to the AS,
either by casting a spell and getting a magical assertion that can
ignore audience restrictions and other security and sanity measures
(which people have pointed out that they're already doing in
practice) or by having
(Hmm, no need for the ad hominem... The use cases I’m involved in do no such thing. And as I’ve pointed out, other assertion languages besides OIDC’s somehow manage to be flexible enough to be used in new protocols.)
Bob interactively present himself to the
claims gathering endpoint.
There is no ad hominem attack present in my comment, except against those who would willingly ignore audience restrictions on assertions that are designed to have them (both SAML and OIDC come to mind here). There are some very limited use cases where this can be optimized (like the AS being the issuer of the assertion, or the AS being audience of an assertion granted to the client by a third party specifically to carry to the AS).
Great. Those are all the use cases I’m aware of. I don’t think anyone wants to throw away audience checking. If we need trusted claims from someone and can’t trust the client, they get pumped through interaction.
What I’m trying to say is that, in my opinion, these should be very carefully cordoned off by the spec as special optimization cases. Otherwise, you run a very real risk of developers slinging around bearer assertions that they’re not meant to be publishing, and around parsing assertions not meant for them and taking them as good. Both of these kinds of mistakes have been well documented in the wild, often to horrible effect.
Okay. So this:
Sec 3.4.1.2.1 Client Pushes Claim Tokens to Authorization Server
“token
REQUIRED. A string containing the claim information in the indicated format, base64url encoded. If claim token format features are included that require special interpretation, the client and authorization server are assumed to have a prior relationship that establishes how to interpret these features. For example, if the referenced format equates to SAML 2.0 assertions and the claim token contains audience restrictions, it is the joint responsibility of the client and authorization server to determine the proper audience values that enable successful token consumption.”
and this:
Sec 6 Specifying Additional Profiles
“In all cases, it is RECOMMENDED that profiles document the following information:
…
• Supply any additional security and privacy considerations."
Should be paired with an additional security consideration in Sec 8?
(I’m realizing now that a phrase I thought was somewhere in 3.4.1.2 didn’t make it in there, and Sec 8 might be a better/additional place for it. Something like: There are two conditions for successfully pushing claims: a claims-aware client [mechanism] and a client that the authorization server trusts [security]. An acceptable fallback in either case is for the authorization server to ask the client to redirect the requesting party over for interactive claims-gathering.)
7) If the client passes an assertion, it can do so to the token
endpoint in a new parameter, like say uma_assertion=ejy...foo.
Basically "oh let me try that again but with more stuff this time”.
Are you saying the client is identifying itself through claims, or Bob? On the last call, it was discussed that Bob needs an opportunity to consent to the AS/C authorization process, as we have now. You’ve got consent below, but if the client has already started pushing Bob’s claims, it’s too late. Or am I missing something? Needs discussion.
I’m simply saying that the current direct assertion presentation mechanism, with all of its flaws as discussed above, is still fully supported by an OAuth extension grant as opposed to a custom endpoint. With that, you can use it to pass whatever claims you like through it. For example: Does the client have an assertion to identify its deployment organization in a way that’s not communicated through the client_id? Sure, send it here! Did you get Bob’s identity assertion directly from this AS? Sure, send it!
Okay.
I was wondering last night: In the case of pushed claims making a round trip AS->client->AS, does gathering Bob’s consent make any sense? In that case, we’re in a "closed system". Further, the “prior relationship” (effectively, an access federation trust framework of some kind) mentioned above may apply to users (Bob) as well as the AS and client, possibly affecting the technical mechanisms at a lower level than OAuth/UMA, by the time the user shows up for this interaction (e.g. having accepted a mobile app’s terms or something).
Thoughts from everyone? This may also be a question for the legal subgroup to ponder. Talk about hitting them with “tomatoes” early on. :-)
8) If the client sends Bob to the interactive claims gathering
endpoint, Bob can log in to a local account, or use a federated
login (like the OIDC model we used in PoF), or provide some shared
secret that Alice emailed to him, or squint really, really hard at
his screen -- whatever the claims require. The AS is still free to
have this be whatever it wants, importantly including capturing
Bob's consent to use the client (since it's identified itself here).
[ Also note that in the alice-to-alice case, the AS can basically
re-purpose its authorization endpoint after Alice logs in and this
all collapses to vanilla OAuth. ]
Not sure I understand. Alice logs in to the claims-gathering endpoint and then gets sent to the authz endpoint? or the one endpoint equals the other? or something else?
I haven’t tried to actually build this out yet, but this would be another optimization step that the AS could undertake if it recognizes Alice logging in to share with herself. Basically, instead of collecting claims about Alice herself, because the AS is already pretty sure that Alice is Alice, it can instead get Alice’s consent a-la a more traditional OAuth style authorization screen. Whether this happens through the authorization endpoint or the claims gathering endpoint kinda comes out in the wash, but I am assuming it’s the latter owing to the different kind of response required. Either way, the interactivity is a good place to gather Bob’s consent.
More stuff I was thinking about last night (clearly I gotta get more sleep): One nice feature of the current model is that A-to-A sharing is just a degenerate case of A-to-B sharing, so it would be great if any changes we made could achieve the same effect. Of course, if claims are pushed, the AS may smoothly recognize Alice at that stage. But figuring out an interaction path that initially doesn’t differ from Bob’s would be ideal.
9) With the claims probably in place, the client can try again at
the token endpoint with the same ticket.
10) If the claims aren't good enough, repeat 6-9 ad nauseum until
someone guesses the right set of claims (but that's another issue).
If they're good enough, issue an OAuth token using the standard
OAuth token endpoint response structure. This includes expiration,
scopes, and other hints to the client. It can even include a refresh
token, ID token, or other extension stuff. This also allows the RPT
to be a PoP token without UMA
Since the current MTI-defined RPT structure includes permissions for multiple resource sets, each has its own expiration, and the AS has the opportunity to cache claims that it learns about the RqP independently of the policy needs of any one RS, individual permission time-to-live can potentially be managed completely independently. We’ve discussed in the past whether it made sense to have a refresh token, and decided it didn’t. It’s worth examining just how many normal OAuth token constructs can be made to fit UMA, but if not all do, what’s the right answer?
If the RPT can turn into a regular access token, which it by all colors already is and our implementation mints and stores it as one, then you can start to attach other normal access token kinds of things to it. A refresh token is pretty helpful if you want the RPT to expire in a shorter timeframe than the grant that was used to mint it. As a (big) added bonus: your clients don’t have to do anything special to handle it: it’s just another access token.
Does a PoP token automatically mean the “right thing” for UMA? (It’s something I’ve been wondering for a long time, actually.)
Also, as was already discussed, we have to get the privacy implications right around token issuance. It’s different in a use case that involves a “Bob” than one that only involves an “Alice”.
having to say anything about whether
or not it is, since token_type is a required response parameter and
UMA can now inherit new token definitions.
PoP will make a lot of sense as an option in UMA, just as it will in OAuth. The real question here is whether or not the OAuth WG will ever get around to defining what a PoP token actually *is*. We’re kinda slow in that regard. :) But the important thing here is that UMA should be able to inherit PoP style tokens without doing extra work (or extra profiles). Basically, the “RPT as a Bearer” profile goes away entirely because it’s just another access token, and “RPT as a Bearer” is effectively defined by RFC6750 in entirety. [ Caveat: yes there are some small details that would need to be included in UMA still, but it’s tiny. ]
I’m curious about the small details, and I just want to be sure I understand about the
UMA extensions we’ve made to JWTs as well. Do those just get absorbed into OAuth token mechanisms as you see it?
Bob never sees or uses the authorization endpoint. Bob never needs
an account (federated or othewise) at the AS that is capable of
doing regular-user stuff like issuing OAuth tokens. The AS doesn't
have to carve out special "external" accounts that only allow for
the "uma_authorization" scope but not act as regular OAuth resource
owners. (Remember, this is Alice's AS, not Bob's, and Bob has no
business getting a regular OAuth token here.)
The AAT isn't needed for anything since Bob's client is identified
directly and Bob is identified through claims (which already exist).
The client could further be identified through claims if it wants
to.
The RPT endpoint isn't needed since this is now just a
slightly-specialized OAuth grant type. Many systems (including our
own) already have hooks for extending with handlers for new grant
types as this is once place where OAuth is *already* extensible. In
our own implementation, we'd get handed the request from the token
endpoint handler (which already validates the client and syntax of
the input among other things)
The JSON response from the protected API isn't needed either since
the ticket is a single string and can easily (and safely) be passed
back in a header. ( again this is another issue but if we're
breaking all wire compatibility let's get it right... and a note on
the returning-the-ticket-as-a-header thing. It also opens the door
for public API responses and discovery of multiple user stuff, like
this (totally off the cuff):
Public data can be solved like: Bob's client talks to a URL with no
token and gets back some data, but a header that says "if you want
more go to this AS and present this ticket.
Multi-user data (like the userinfo endpoint) can be solved like:
Bob's client talks to a URL and gets sent back a header that says
"if you want more then give me an indicator of who you're after (an
opaque token, a webfinger URI) or go to this interactive page to
have Bob figure it out, then come back and we'll talk again".
Basically, you can bootstrap the process with some user interaction
that could lead into George's multi-stage protected discovery
system. )
Someone is going to have to explain to me what is possible in the
current system that is not possible in the above setup, because I'm
not seeing anything.
Can we build it like it is today? Yes of course; I've done so
myself. It works, but it's clunky and ugly and requires lots of
special "if-uma-do-this" kind of code. I don't like that. It also
requires Bob being able to do a regular OAuth flow to get the AAT
even if he's not a local user, and I don't like that either.
So let's say we did things this way and called it UMA 2.0.0 (since
this is a very backwards-incompatible change set and the group has
adopted semantic versioning). What does that mean for me as a
developer? Quite frankly, it means a whole lot less special code for
implementing UMA at the AS, the client, and the RS, assuming I'm
starting from an OAuth system. And it makes it much, much easier for
me to have dual-purpose codebases that do both UMA and OAuth. Both
of these are highly appealing to me as a systems architect and
developer, and I don't think that I would be standing alone in this
opinion.
You’re definitely not alone.
You’ll see from my previous message that my recommendation was for taking this up as a major version exercise. Now, having seen this more complete proposal, I’m more confident that we can actually get to the end of a design process like this without angst — I just think we shouldn’t attempt it for the patch workstream. :-)
I wholeheartedly agree that this is not a candidate for a patch release, and have said as much all along. :) I still believe that there shouldn’t be any breaking changes without backwards-compatibility shims in a patch release, and that “1.0.0 -> 1.0.1” should not be treated in any way as “special” in that regard. And I also believe that work on “UMA 2.0.0” can start right now along side “UMA 1.0.1”, (and even “UMA 1.1.0” if people really want it).
— Justin
Actually, when we nominated issues for the patch release, we could have left these issues out — that would have made more sense in retrospect! We can discuss what we think about major and minor versions in the fullness of time. I suspect that, on Thursday, we should discuss what we think about the entire V1.0.1 exercise in light of this thread.
For my (and hopefully others’) edification, I’ll still work up a fresh swimlane or two. Those were essential in the early going for V1.0, as the charter UMAnitarians can attest.