I’m averse to making the client or RS too smart about cleanup and these half-working conditions. A simpler protocol is more likely to be functional in the long run. If things can fail, they should fail with pretty well defined semantics. In OAuth, you can get a token, and that token can work or not work. This is good enough for the vast majority of situations, and so I’m not in favor of marking things as partially met. It’s adding complexity without benefit that I can clearly see.



I’d also like to remind the group of the original argument that I made to add the “Default Deny” language in there, as it’s got very little to do with the current discussion. Basically, imagine this naive implementation:

  - Each resource set has policies that are fulfilled by claims
  - The client/RqP present claims to fulfill these required policies
  - If you fulfill any policies on the resource, you get a token with the associated scopes

This is all well and good. However, if you have:

  - A resource set that has *no* policies set

Then you could end up with the following aberrant logic:

  - Client requests a token for a resource, gather up the set of required claims to access said resource
  - Required claims is the empty set as no policies are set
  - Client/RqP present no claims
  - Empty set satisfies the empty set, client gets issued a token

*this* precise bug is what I was trying to guard against with my original proposal. I fear we’ve gone off into the woods now.

 — Justin


On Jan 26, 2017, at 11:10 AM, George Fletcher <george.fletcher@teamaol.com> wrote:

Good point:) I would rather have the AS return to the client that it issued the RPT but didn't fully meet all requested permissions. The problem, is that the client has no clue as to what a resource_set maps to from a URI perspective. I suppose if the AS returned to the client that it was not able to fully meet the permission_ticket scopes in some "partially_met" flag, then the client can try a resource but knows it's possible it won't work.

I think if the client sends a RqP through a claims negotiation flow for access to resourceA, if it has to do the same thing again, it could tell the RqP that access will be denied unless the RqP supplies all the requested claims. Maybe the AS could show this to the user during the interactive claims negotiation?

Bob would probably understand Alice's resource name/description of "Alice's calendar". So, if in interactive mode, the AS could tell Bob, "unfortunately you did not meet the policy necessary to access Alice's calendar". That way the user knows that the next client request for "Alice's calendar" will fail.

Don't know if that's better?

On Thu, Jan 26, 2017 at 10:40 AM James Phillpotts <james.phillpotts@forgerock.com> wrote:
That's interesting. I'm still not sure it 100% satisfies what I'm thinking about, as a new RPT that failed to get resourceB would look the same as an existing RPT for resourceA and resourceC, so the RS would send back to try and get resourceB if it needed it.

On 26 January 2017 at 14:13, George Fletcher <george.fletcher@teamaol.com> wrote:
Ahh... good point James. If the permission ticket encompasses multiple resource set ids, then the AS should be able to authorize the different resource set ids separately.

I do worry about requiring the AS to return the "denied" resource_set(scope) tuples, because at introspection time that could be very complicated to reconstruct.

What about the following?

1. The RS is "authoritative" for requesting the required scopes for any resource_set_id. This means that in order for the RPT to include a resource_set:scope tuple, the client/RqP MUST meet all policy for the scopes in the permission_ticket for that resource_set.
2. If the permission_ticket contains multiple resource_set:scope tuples, the AS MAY authorize a partial set of the tuples so long as all the scopes for that tuple are fully met.

This has the effect of encouraging the RS to not request a huge amount of scopes for a given resource_set while not prohibiting the RS from asking for more than is absolutely necessary.

This also, should I believe, address the use case James described. For instance, is the RS asks the AS for a permission_ticket for resourceA(scopeA), resourceB(scopeB), resourceC(scopeC). And when the client/RqP supplies claims or goes through claims negotiation, they only can satisfy the RO policy for resourceA(scopeA) and resourceC(scopeC). The AS can then return the RPT with resourceA(scopeA) and resourceC(scopeC).

WDYT?

On Thu, Jan 26, 2017 at 6:42 AM James Phillpotts <james.phillpotts@forgerock.com> wrote:
Yep, that does make sense. The problem would be:

10 RS requests resourceA(scope1, scope2)
20 AS issues RPT resourceA(scope1)
30 RS introspects RPT, finds insufficient scope for request, GOTO 10

Maybe what the RS needs to know is what was denied as well as what was granted? The situation I want to allow is for the RS to be able to say Either(resourceA(scope1), resourceB(scope1) - but that relies on the AS being able to return partially matched scopes, which with the current introspection can allow the problem you describe. If the introspection of the RPT above instead returned: Granted:resourceA(scope1); Denied:resourceA(scope2) then the RS would not GOTO 10 because it knows there is no point is submitting that permission request again.

WDYT?
James

On 25 January 2017 at 17:56, George Fletcher <george.fletcher@teamaol.com> wrote:
Given that the RPT is somewhat equivalent to an OAuth2 access token, the OAuth2 best practice is to return the set of scopes that were met as part of the request, and also inform the client of which scopes where granted.

This becomes a little more problematic for the scopes defined by the permissions_ticket because the client doesn't know what they are. If we allow the "partial scopes" response, it will be possible for the client to successfully get an RPT that does not provide it the access it needs to a particular resource.

Take the following example:

Alice has a photo album that Bob is trying to access. Bob's client makes the request to Alice's album and the RS requests the AS to generate a permission_ticket with view,edit scopes for the resource. Bob's client presents the permission_ticket to the AS and goes through some claims negotiation. The result of the set math is that Bob's client gets 'edit' scope but not 'view'. If the AS issues the RPT with just the 'edit' scope, the it's unlikely that Bob's client will work as it really wanted 'view' access.

I'm becoming more convinced that the responsibility for the scopes necessary to issue the RPT must lie with the RS and NOT the AS. If the RS is asking for too many scopes up front, then Bob's experience will have a lot of overhead just to be able to view the photos. On the other hand, if the RS asks for just the scopes needed and the AS overrides that decision by returning less, the overall experience will break.

Hopefully that makes sense:)

Thanks,
George

On Wed, Jan 25, 2017 at 12:37 PM James Phillpotts <james.phillpotts@forgerock.com> wrote:
Right, I see. Maybe an example would help?

On 25 January 2017 at 17:35, Eve Maler <eve@xmlgrrl.com> wrote:
Hey, I'm always up for a good disquisition ("a long or elaborate essay or discussion on a particular subject"). :-) In fact, I did try new wording in rev 13 already based on the fact that with our set math I couldn't make heads or tails of the MUST wording (note that this comes after the new agreed wording about the AS having a choice to respond with an RPT or a failure if the scopes satisfied are less than the scopes requested):

"Note: While a reasonable approach for most scenarios is to implement the classic security stance of default-deny ("everything that is not expressly allowed is forbidden"), corner cases can inadvertently result in default-permit behavior. For example, it is insufficient simply to assume that all resources have some non-zero set of claims required for access, and then accept an empty set of supplied claims as sufficient for access."

This was in order to advise anyone starting to build an AS from scratch about some of the best practices and subtleties of policy engine and access control work. Thoughts?




Eve Maler
Cell +1 425.345.6756 | Skype: xmlgrrl | Twitter: @xmlgrrl


On Wed, Jan 25, 2017 at 8:32 AM, James Phillpotts <james.phillpotts@forgerock.com> wrote:
Hi all,

Thanks for the reminder to send this email Eve! ;)

The paragraph in question is:
The authorization server MUST use a default-deny authorization assessment model in adding permissions to RPTs, that is, "everything that is not expressly allowed is forbidden" for resources for which resource servers have requested access permission on behalf of clients. Exercise caution in implementing default-deny because corner cases can inadvertently result in default-permit behavior. For example, it is insufficient simply to assume that all resources have some non-zero set of claims required for access, and then accept an empty set of supplied claims as sufficient for access.
I'm not convinced that this paragraph is really very useful, but that may be because it isn't clear at what level the 'deny' is relating to in this context - is it on a per-resource, per-scope, or an RPT level?

If per-resource, I think this is a reasonable thing to express, but I'm not sure the paragraph does a particularly good job of it.

If per-scope, does this only apply to additional scopes requested by the client?

If RPT, then I don't think the idea is correct, as the RPT shouldn't be denied based on the outcome of a particular policy for a particular resource.

On one of the calls I thought someone had mentioned that the RPT should only be granted if all of the scopes requested in the permission ticket were able to be granted, but I think it should be perfectly reasonable to grant a subset - e.g. if ticket requests view, edit for resource A and view for resource B but all that can be granted is view for A, then that is a perfectly reasonable response?

This was partly triggered by Mike's suggestion of patterned URIs, where I was thinking about the RS wants either view on A, view on B or view on C, because it knows that the actual requested URL is covered by all 3 of those registered resource sets (although as per other email, I wouldn't like that to be a pattern).

Sorry if this is slightly rambling.

Cheers,
James



_______________________________________________
WG-UMA mailing list
WG-UMA@kantarainitiative.org
http://kantarainitiative.org/mailman/listinfo/wg-uma



_______________________________________________
WG-UMA mailing list
WG-UMA@kantarainitiative.org
http://kantarainitiative.org/mailman/listinfo/wg-uma
-- 
Distinguished Engineer
Identity Services Engineering, AOL Inc.

-- 
Distinguished Engineer
Identity Services Engineering, AOL Inc.

-- 
Distinguished Engineer
Identity Services Engineering, AOL Inc.
Mobile:+1-703-462-3494  Office:+1-703-265-2544
_______________________________________________
WG-UMA mailing list
WG-UMA@kantarainitiative.org
http://kantarainitiative.org/mailman/listinfo/wg-uma