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