16:01:23 <lbragstad> #startmeeting policy 16:01:24 <openstack> Meeting started Wed Nov 23 16:01:23 2016 UTC and is due to finish in 60 minutes. The chair is lbragstad. Information about MeetBot at http://wiki.debian.org/MeetBot. 16:01:25 <openstack> Useful Commands: #action #agreed #help #info #idea #link #topic #startvote. 16:01:28 <openstack> The meeting name has been set to 'policy' 16:01:53 <lbragstad> alright - i imagine this going to be a pretty light meeting, given it's US holiday tomorrow 16:02:47 <lbragstad> we'll give it until 4 after for others to show up 16:04:25 <lbragstad> #topic action items from last week 16:04:35 * lbragstad ITEM: ayoung to repropose https://review.openstack.org/#/c/391624/ 16:04:50 <lbragstad> looks like he did - did anyone have a chance to look that spec over? 16:05:09 <ayoung> Covered a bit of this in the meeting yesterday. The biggest difference is the focus on not-breaking caching 16:05:25 <lbragstad> ayoung yeah - that would be significant 16:05:57 <lbragstad> ayoung you broke the proposed implementation into pieces 16:06:02 <ayoung> the RBAC check is going to be performed in the keystonemiddleware auth_token layer, after token validation, and before returning passing to the calling WSGI applicaion 16:06:39 <ayoung> we'll keep an option on the table to do the check as part of the token validation, but that will be prioritized after the out-of-band check 16:06:50 <ayoung> er...whatever the middleware check is called 16:07:04 <ayoung> would like this to get in to Ocata, or at least the management API 16:07:27 <ayoung> I am about ready to propose a WIP patch, just trying to sort the JSON home tests and get a clean Tox run first 16:07:28 <lbragstad> ayoung can you take a step back and define management API for those who missed the keystone meeting yesterday? 16:07:45 <ayoung> so, before you can enforce RBAC, you need to define the rules 16:08:07 <lbragstad> which are currently defined in various policy.json files across the services 16:08:15 <ayoung> the API is going to be built on a new Database entity that I am right now calling url_pattern 16:08:25 <ayoung> the URL pattern object looks like this 16:08:54 <ayoung> sql.Column('id', sql.String(length=64), primary_key=True), 16:08:54 <ayoung> sql.Column('service', sql.String(length=64), nullable=False), 16:08:54 <ayoung> sql.Column('verb', sql.String(length=64)), 16:08:54 <ayoung> sql.Column('pattern', sql.Text, nullable=False), 16:08:54 <ayoung> sql.Column('role_id', sql.String(length=64), primary_key=True), 16:09:34 <ayoung> we had a discussion about the subtleties around the role_id yesterday that is worth recapping 16:09:45 <ayoung> the URL pattern here could also be called "operation" 16:10:08 <ayoung> the unique key is the URL + the Verb 16:10:17 <ayoung> so GET /v3/users 16:10:31 <ayoung> or PUT /v3/user/{user_id} 16:10:52 <ayoung> the service is the string name (not the ID) to be friendly to end deployers 16:10:59 <ayoung> they know about "compute" not about UUIDs 16:11:19 <ayoung> and this is purposely kept separate from the Service Catalog...a point we can debate later if so desired 16:11:34 <ayoung> do we have a quorum here? 16:11:56 <ayoung> want to make sure this is actually useful to people (beside lbragstad ) before carrying on? 16:12:08 <lbragstad> ayoung we have 7 folks here, including you 16:12:08 <rderose> I'm following 16:12:13 <ayoung> ++ 16:12:20 <ayoung> OK, so the interesting part is the role_id 16:12:25 <thinrichs> Hi all. Sorry I'm late. 16:12:29 <lbragstad> thinrichs o/ 16:12:36 <ayoung> that is limited to one role, but via implied roles, it can actually be many 16:13:33 <ayoung> so if a user has member, and member implied reader, you could have the reader role_id mapped to the URL pattern GET /v3/users 16:13:51 <ayoung> and so anyone with the Member role would be able to perform it. 16:13:52 <lbragstad> thinrichs you should be able to get scrollback here in a few minutes - http://eavesdrop.openstack.org/irclogs/%23openstack-meeting-cp/%23openstack-meeting-cp.2016-11-23.log.html 16:14:10 <thinrichs> lbragstad: thanks! 16:14:14 <lbragstad> thinrichs but right now we are addressing action items from last week 16:14:38 <lbragstad> and i completely forgot to publish the agenda #link https://etherpad.openstack.org/p/keystone-policy-meeting 16:14:41 <thinrichs> lbragstad: great--looking at the agenda right now 16:15:21 <ayoung> the reason to focus on implied roles is to allow a path to delegating a subset of the roles required to just perform the operation 16:15:22 <lbragstad> thinrichs ayoung is describing his spec right now... so if anyone has questions on it, now is the time 16:15:37 <ayoung> lets take a simplified view of computes create server 16:16:00 <ayoung> this is an API a user calls on Nova, but then nova has to call a few other services: 16:16:13 <ayoung> glance, neutron, cinder 16:16:45 <ayoung> so, we would want to have a consistent set of roles across the APIs to those other services that a user could do. Lets call this role create_compute: 16:17:00 <ayoung> member->create_compute 16:17:09 <ayoung> read -> as "implies" BTW 16:17:54 <ayoung> so if a user wants to delegat to a service user (say heat via the trust API) they can delegate create_compute even though they are only explicitly assigned member 16:18:39 <ayoung> the alternative was to say that each url_pattern had multiple roles assigned to it. 16:19:16 <ayoung> so if we had a system where POST /v2/compute creates a VM 16:19:37 <ayoung> we could assign multiple roles to that operation. Member would be there for everyone 16:20:13 <ayoung> but to delegate something that could "only" do POST /v2/compute and not all of the other things that a member can do, we would have to explicitly assign that new role to all the users 16:20:33 <ayoung> implied roles make it possible to keep this manageable, and to do least privilege 16:20:38 <rderose> hmm... so in this design, there isn't an admin role for ready and write; you'd have to have multiple roles to perform all operations, correct? 16:20:51 <rderose> *read and write 16:20:51 <ayoung> rderose, ok, lets talk that through 16:21:01 <ayoung> rderose, lets start where we are today 16:21:14 <ayoung> most of the admin operations would require the admin role 16:21:30 <ayoung> if you wanted to split them into read and write, you would create two new roles: admin_read, admin_write 16:21:47 <ayoung> and set admin->admin_read and admin->admin_write 16:22:09 <ayoung> then you would modify the url_pattern for an operation and explicitly make it admin_read or admin_write 16:22:18 <lbragstad> (i.e. would POST /v3/domains/{domain_id} fall under a admin_write operation) 16:22:22 <ayoung> the end administrators would still be able to perform all the actions 16:22:26 <ayoung> sure 16:22:33 <ayoung> that is a good example of one 16:22:46 <ayoung> so that would now get admin_write 16:22:56 <ayoung> and GET /v3/domains/{domain_id} would get admin_read 16:23:10 <ayoung> now, lets say that we decide GET /v3/domains/{domain_id} should be world readable 16:23:19 <ayoung> we create a new role, reader 16:23:24 <ayoung> admin_read -> reader 16:24:02 <ayoung> we change GET /v3/domains/{domain_id} so it is associated with reader, and anything to which we delegated the admin_read role would still work 16:24:25 <ayoung> It allows you to roll-forward policy 16:24:55 <ruan_06> don't you think we will toooo many roles to manage? 16:25:02 <ayoung> ruan_06, eventually, yes 16:25:06 <thinrichs> Implied roles makes sense. I'm assuming if role r1 implies roles r2 and r3 that r1 gets the union of r1, r2, r3 rights. Correct? 16:25:10 <ayoung> ruan_06, to start with, no 16:25:24 <ayoung> ruan_06, as a follow on, however, we can make the following adjustments: 16:25:33 <ayoung> today, we expand implied roles in the token validation response 16:25:33 <thinrichs> agree with ruan_06 that people will almost immediately want tooling to understand what rights any given user actually has. 16:26:12 <ayoung> thinrichs, tooling is possible, and can be done manually to start, built in a supported tool as a second step 16:26:23 <ayoung> ok, back to too many rules: 16:26:31 <ruan_06> I agree that this can be a short term solution, better than the current solution 16:26:39 <ayoung> lets talk about validation for a moment 16:26:51 <ayoung> assuming this is all done in middleware, ithe flow will be like this: 16:27:04 <thinrichs> ayoung: keystone has implied roles today? I thought this was part of the spec. 16:27:29 <rderose> ruan_06: but we want a long term solution; not something that is just better than what we have 16:27:34 <ayoung> after the middleware has validate the token (or fetched the token data from cache) the middleware will fetch the url_patterns from the Keystone server 16:27:35 <lbragstad> thinrichs implied roles exists today - but i'm not sure what it's current usage distribution is 16:27:45 <lbragstad> rderose ++ 16:27:54 <ayoung> that will be done based on the "service" string that middleware will read out of the config file 16:28:07 <ayoung> lbragstad, I'd assume none, as the CLI is still up for review 16:28:25 <ayoung> #link https://review.openstack.org/#/c/290253/ 16:28:38 <ayoung> ok, so it fetches the url_patterns, and matches the one the user requested 16:28:51 <ruan_06> redrobot: if you want a real one, we should switch from RBAC to ABAC 16:29:08 <ayoung> from there it looks at the "role" attribute and does a match with the set of roles in the auth_data 16:29:24 <ayoung> ruan_06, different conversation 16:29:40 <ayoung> let's table that for now, as it is important, but will take much longer 16:29:41 <lbragstad> ayoung so from a performance perspective - i have concerns 16:29:48 <ayoung> lbragstad, hold on for a moment 16:30:00 <ayoung> let me finish talking through the validation and too many roles concern 16:30:39 <ayoung> what we can do when we have more roles is switch to *not* expanding the roles in the token validation response, and instead add those to a "roles" attribute of the url_opattern 16:31:23 <ayoung> this would be a calculated value, with the implied-roles data used to generate a set. The generation would be backwards from the implied roles; for each implied-role, get the list of prior roles 16:31:37 <ayoung> should be a small subset per URL pattern 16:32:00 <ayoung> and it will have to be calculated once per- url pattern list 16:32:28 <ayoung> the URL pattern list is itself a JSON document, and would be stored in the same Memcache that is used for the tokens 16:32:52 <ayoung> it would be refetched based on cache timeout, just like the tokens are 16:33:04 <ayoung> and would not be fetched from Keystone on each token 16:33:18 <ayoung> OK... lbragstad you had a question about performance? 16:33:53 <lbragstad> ayoung we currently have each service validate two tokens (the subject token and the auth token) for an operation 16:34:09 <lbragstad> now we are going to be adding another round trip to the equation to get the list of url_patterns 16:34:24 <lbragstad> how long would the cache be valid for? 16:34:53 <lbragstad> if we set invalidation too long we're going to start running into revocation cases 16:36:22 <lbragstad> if we choose to get a fresh list of url_patterns on every token validation, we're going to be drastically increasing traffic to keystone 16:37:21 <ayoung> No revocations 16:37:32 <ayoung> We cache as long as the user is comfortable with holding the data 16:37:35 <lbragstad> (this is essentially fore-shadowing my concern about the third step in the process that pulls the RBAC decision and url_pattern matching into keystone token validation check) 16:37:36 <ayoung> 1 minute? 16:37:47 <ayoung> the url Data will be longer, probably 16:38:01 <ayoung> 10 minutes, whatever they are comfortable with for a change to RBAC policy 16:38:14 <ayoung> token validation does not change 16:38:21 <lbragstad> so what happens if a user does something and the policy or url_patterns change in that time/ 16:38:58 <ayoung> lbragstad, its an eventual consistency approach. Either the operation has the old behavior or the new 16:39:06 <ruan_06> this is the drawback of the token-based approach 16:39:17 <ayoung> yeah, but this is all trade off for perf 16:39:42 <ayoung> if we sent each request to the Keystone server, as in the original proposal, we get immediate enforcement, at the cost of perf 16:39:56 <ayoung> CAP theorem stuff still applies too. 16:40:37 <ayoung> if you want to create some way to automatically flush the caches, go for it, but it really is outside the scope and control of Keystone 16:40:48 <ayoung> we've discussed that before, and it just is too invasive 16:41:29 <ayoung> We could do something in the future where we put a checksum in both the RBAC file and in the tokem, and if they don't match, refetch, but I am not goimng to try and implement that in the context of this review 16:41:32 <ayoung> too muich 16:41:37 <ayoung> too little benefit 16:42:01 <dstanek> ayoung: that could be bolted on later. i don't see that changing your design 16:42:27 <dstanek> ayoung: tbh, i meant to reread the spec again last night, but ran out of time. 16:42:48 <thinrichs> Time check: 20min left. Seems we understand the design and tradeoffs for this proposal. Are there other agenda items we want to fit into this meeting? 16:43:26 <lbragstad> yeah - we had a few more action items from last week 16:43:51 <lbragstad> I wanted to give ktychkova some time to explain what she has been able to accomplish with Apache Fortress 16:44:04 <lbragstad> (if she want to) 16:44:08 <lbragstad> wants* 16:44:19 <ktychkova> Yes 16:44:38 <ktychkova> Apache Fortress is a java implementation of RBAC 16:44:42 <ayoung> It is essentially an external PDP 16:44:48 <ayoung> more than just RBAC, right? 16:44:51 <lbragstad> ok - so now that ayoung has filled us in on his spec - i'll leave the action item for folks to go back and continue looking at it. 16:45:02 <lbragstad> let's carry the discussion about RBAC and url_patterns there 16:45:07 <ayoung> We'd consider the APache fortress approach full ABAC 16:45:16 <ayoung> lbragstad, ++ 16:45:17 <ktychkova> It is possible to integrate it with OpenStack 16:45:23 <lbragstad> #topic ktychkova to summarize work with Apache Fortress and keystone 16:45:36 <lbragstad> #link http://directory.apache.org/fortress/ 16:45:48 <lbragstad> #link http://xuctarine.blogspot.ru/2016/08/apache-fortress-easiest-way-to-get-full.html 16:45:56 <ktychkova> ok 16:45:56 <ktychkova> so Apache Fortress is RBAC implementation with a web interface to manage policies 16:46:19 <ktychkova> The point is: Apache Fortress should not be some default thing in the OpenStack 16:46:19 <ktychkova> But it would be nice to support 3rd party apps for the RBAC 16:46:19 <ktychkova> It doesn't require any changes in Keystone, only in oslo.policy 16:46:58 <ayoung> ktychkova, so oslo.policy is doing more than just RBAC 16:47:06 <ayoung> most important, it is doing the scope check 16:47:19 <ruan_06> ktychkova: you mean externalize authorization to Fortress? 16:47:19 <ayoung> is that to be done in Fortress, or left in a static file? 16:47:40 <ktychkova> ruan_06: yes 16:47:54 <ayoung> https://blueprints.launchpad.net/keystone/+spec/assignments-in-fortress was posted about a year ago 16:48:21 <ayoung> #link more recent http://xuctarine.blogspot.com/2016/06/apache-fortress-instead-of-policyjson.html 16:48:32 <ayoung> #link http://xuctarine.blogspot.com/2016/06/apache-fortress-instead-of-policyjson.html 16:48:40 <ayoung> more recent doc explaining a POC 16:49:03 <ayoung> ktychkova, is that your blog? 16:49:14 <ktychkova> ayoung: yes 16:50:26 <ruan_06> that's a good idea to externalize authorization 16:51:23 <lbragstad> ktychkova it looks like the changes you made to keystone were minimal - most of the work was in oslo.policy, right? 16:51:34 <ktychkova> right 16:51:46 <ktychkova> no changes in Keystone 16:51:55 <lbragstad> just configuration 16:52:18 <ruan_06> ktychkova: where to store role-assignment information? 16:52:24 <lbragstad> ktychkova i assume you had to duplicate all of the policy from policy.json into AF 16:52:52 <ktychkova> yes, AF stores everything in OpenLDAP 16:53:09 <ayoung> ktychkova, is it using RFC schemas, or something custom? 16:53:34 <ktychkova> custom, i guess 16:53:38 <ayoung> Is this something we could describe to someone with a different LDAP server and say that the implementation would be done the same way? 16:53:56 <thinrichs> Is every request sent to oslo.policy hopping over the network to ask Fortress? Or is there some caching going on? 16:54:07 <ayoung> ktychkova not necessarily custom. I did the initial LDAP work and there is a scheme in the RFS to do RVBAC 16:54:09 <ayoung> RBAC 16:54:17 <ayoung> organizationalRole IIRC 16:54:51 <lbragstad> ktychkova is https://review.openstack.org/#/c/237521/ the only patch you needed to get things working with oslo.policy? 16:54:59 <ktychkova> yes 16:55:51 <lbragstad> well - that's cool 16:56:33 <ktychkova> ayoung: I'm not sure about schemas, it was out of the scope of my research 16:56:33 <ktychkova> I used Apache Fortress as is 16:56:49 <thinrichs> ktychkova: Is every request sent to oslo.policy hopping over the network to ask Fortress? Or is there some caching going on? 16:57:02 <ayoung> So, I have a couple concerns 16:57:04 <lbragstad> so - i guess if we wanted to do this today, we'd need to go through the following. 1.) propose a spec to oslo.policy for https://review.openstack.org/#/c/237521/ 2.) formally document AF process in keystone 16:57:13 <ayoung> the biggest one is how Fortrass treats roles 16:57:23 <ayoung> are they global, or does it have the concept of a scope? 16:57:25 <ktychkova> no caching in my patch, but it is PoC 16:58:09 <lbragstad> two minute warning 16:58:13 <ayoung> question is whether it is possible to cache. 16:58:14 <ktychkova> ayoung: what do you mean "scope"? 16:58:25 <ayoung> ktychkova, a role is assigned to a user "on a project" in openstackl 16:58:36 <ayoung> so the member role is not a global role 16:58:37 <thinrichs> ayoung: right question: can we cache? 16:59:17 <thinrichs> ktychkova: To be clear I think that's a cool POC! 16:59:23 <ayoung> thinrichs, I think the answer is No. Only identical request can be cached 16:59:48 <ayoung> each request for a different user or a different operation requires its own decision 16:59:48 <lbragstad> alright - let's continue our discussion in #openstack-keystone 16:59:55 <lbragstad> #endmeeting