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