Hi So I don't doubt there are many ways of articulating the targeted objects - and a more comprehensive solution might involve the mapping you mention (although that's definitely not a Havana discussion!).
We do, however, have an existing serious hole in our current apis & policy protection that limits the ability of a cloud provider to delegate admin responsibility for a domain to a customer, while still ensuring they maintain certain roles over all projects created in that customer domain (without the ability of the customer admin removing them!). This is the use case I am trying to solve first and foremost. This is a subset of the general problem, and using the domain as the container to specify applying to all current and future projects (which I call inheritance) is, I believe, the most appropriate. However, as we agreed, this should be an extension, since we are likely to settle on a more comprehensive re-write of these APIs for IceHouse. As per the keystone IRC meeting, I have now done the following: 1) Removed all mention of multiple target objects (and hence inheritance) from the newly proposed GET /role-assignment API (that replaces the various broken ones we have removed from the spec). This updated API is now available for review at: https://review.openstack.org/#/c/32394/8 2) Moved the "inherit roles from parent domain" extension to role assignment setting to an extension. This API is available for review at: https://review.openstack.org/#/c/29781/15 I think this is a good way to proceed, unless anyone has significant objections. Henry On 19 Jun 2013, at 15:36, Adam Young wrote: > The more I think about it, the more I think that tying the inheritance to the > domain assignment is the wrong solution. > > David/Kristy originally had the Mapping blueprint and patch. It contained > the ability to provide arbitrary rules for mapping from the identity > attributes to the roles. I think that it is time to implement that. > > It would be more correct to say that all users in a specific group (fetched > out of Identity/LDAP) would get a specific role in a project than to say that > a user with a domain role should therefore inherit a role in all projects. > > When creating a scoped token, we need to query a subset of the users identity > information. I think that the right direction for this query to flow would > be: > > project->roles->role-mappings->groups > > as opposed to what we do now, which is to do a global query: give me all > groups for this user and select which ones apply. For LDAP/SQL Identity > backends we want to trigger the miniaml query which is "let me know if the > user is in groups G1, G2, G3..." as those are the groups that potentially > apply to role assignments for this project. > > > So I'd like to redefine the problem definition here: > > "Provide a mechanism by which role assignments can be specified for more than > one project." One such rule would obviously be "all projects in domain D1" > > But it should be based on groups, not on domain role assignments. > > > > > On 06/10/2013 11:41 AM, David Chadwick wrote: >> >> >> On 10/06/2013 16:02, Henry Nash wrote: >>> Hi David, >>> >>> I wasn't suggesting that we encode "inhertitness" in the name, just >>> that if you want to have a role that is non-inherited and one that is >>> inherited that relate to the same type of permission, then since role >>> name must be globally unique, then the two roles must have different >>> names....hence potentially leading to the complication in the policy >>> file. >> >> I dont see why different role names would lead to complications in the >> policy file, since policies are there to assign different permissions to >> different roles. >> >> What can happen is that policy files can get very large and complex, but >> that can happen regardless of whether roles are inherited or not, and >> mistakes can be made by assigning the wrong roles to users or the wrong >> permissions to roles, but again this is independent of the role definition. >> >> regards >> >> David >>> >>> Henry On 10 Jun 2013, at 15:57, David Chadwick wrote: >>> >>>> Hi Henry >>>> >>>> on the definition of inherited roles, I dont think this should be >>>> part of the role name, but rather, each role should have meta >>>> information attached to it, in its role table definition, that >>>> indicates the properties of the role definition. In this way, you >>>> can make the role definition extensible by adding new columns to >>>> the table as and when needed e.g. if in future you want to have >>>> global roles inherited by domains, you add a new column, say >>>> GlobalToDomain, which could be a boolean with a default value of >>>> false, and with a value true indicating that it is inherited from >>>> global to domain. All pre-existing roles would not be of this type, >>>> and therefore all pre-existing code would work without this new >>>> inheritance. >>>> >>>> I would not alter the role-user assignment API as this should >>>> simply specify the role and user and project. The code may need >>>> enhancing in the future, if new types of inheritance are added, in >>>> order to cater for cases where the role is wrongly specified by the >>>> administrator i.e. it does not apply to the project in question >>>> through lack of inheritance. >>>> >>>> regards >>>> >>>> David >>>> >>>> On 08/06/2013 11:38, Henry Nash wrote: >>>>> So on the idea of using the role def for inheritance definition, >>>>> there were a couple of things that concerned me about it: >>>>> >>>>> 1) While it definitely can simply the api changes required for >>>>> the current requirements, I worry that we are passing the >>>>> complexity on to the creation of the policy file. Since the role >>>>> names of an inherited and non-inherited role will obviously have >>>>> to be different, is there a danger that policy files end up with >>>>> lots of rules that have "role: xxxx and role: xxxx_inherited"? I >>>>> guess we can make the argument that since (with today's >>>>> requirements at least) the only objects that will end of >>>>> inheriting an assignment will be projects, the likelihood is that >>>>> the api lines in the policy file that contains inherited and >>>>> non-inherited will be different, hence avoiding the problem. >>>>> However, if, in the future, we were to expand inheritance to >>>>> support all domains, or all projects in all domains, then this >>>>> problem would arise for domain-relevant apis lines in the policy >>>>> file. >>>>> >>>>> 2) If, again, in the future we support inheritance across all >>>>> domains/projects - would we need to more fine grained control of >>>>> the inheritance? For instance, we want a role that was inherited >>>>> by all domains, but not the projects in each domain? Perhaps, >>>>> one could imagine expanding the role-def to somehow indicate this >>>>> (maybe rather than just having a simple "inherited" boolean, we >>>>> specify "project_inherited", to which we could, in the future, >>>>> add "domain_inherited"?). We also have the problem of how you >>>>> assign such a role? I guess you would still need some kind of >>>>> modification to the assignment APIs to indicate "all domains" >>>>> (perhaps the "domains/*" that was suggested)? >>>>> >>>>> I'd be interested in views on the above - I'm Ok fi we decide >>>>> that role-def is the right way to go, but want to make sure we >>>>> clearly understand how we would expand this in the future. >>>>> >>>>> Henry On 7 Jun 2013, at 18:12, Dolph Mathews wrote: >>>>> >>>>>> >>>>>> >>>>>> On Thu, Jun 6, 2013 at 5:48 AM, David Chadwick >>>>>> <[email protected] <mailto:[email protected]>> >>>>>> wrote: >>>>>> >>>>>> Hi Henry >>>>>> >>>>>> My take on this is that whether a role is automatically >>>>>> inheritable or not should be an attribute of the role itself, >>>>>> and should be independent of who the role is assigned to. >>>>>> Therefore when the role is initially defined, it should be >>>>>> stated by the Keystone admin whether it is an inherited role or >>>>>> not. >>>>>> >>>>>> Role assignment is a separate issue and should not be confused >>>>>> with the basic definition of the role. Role assignment should >>>>>> simply be a matter of naming the subject (domain, project or >>>>>> user) and the role. If you dont want the role to be inherited >>>>>> then use a non-inheritable role. >>>>>> >>>>>> The problem with all the APIs below is that they conflate role >>>>>> definition and role assignment together in the same API call. >>>>>> There should be no need to have user_ids in the definition of >>>>>> a role. Similarly there should be no mention of inherited in >>>>>> the assignment of a role to a user. >>>>>> >>>>>> regards >>>>>> >>>>>> David >>>>>> >>>>>> +1; I really like the simplicity of this approach, and it >>>>>> sounds like something we can migrate to easily (e.g. default >>>>>> inheritable=False for existing roles). Then global role >>>>>> assignments would follow an API like: >>>>>> >>>>>> GET /users/{user_id}/roles # list global roles HEAD >>>>>> /users/{user_id}/roles/{inheritable_role_id} # check if a >>>>>> global role is assigned PUT >>>>>> /users/{user_id}/roles/{inheritable_role_id} # assign a global >>>>>> role DELETE /users/{user_id}/roles/{inheritable_role_id} # >>>>>> revoke a global role >>>>>> >>>>>> where a non-inheritable role assigned a user without a domain >>>>>> or project for context wouldn't make any sense. In fact, >>>>>> assigning an inheritable role to a user on a project wouldn't >>>>>> be very useful (as it wouldn't inherit to anything in the core >>>>>> API), but I don't see a reason to deny it. >>>>>> >>>>>> >>>>>> On 05/06/2013 15:31, Henry Nash wrote: >>>>>> >>>>>> Hi >>>>>> >>>>>> As per the discussion during the keystone IRC meeting >>>>>> yesterday, I have been reviewing the proposals for this >>>>>> functionality. There have been two objections to the current >>>>>> proposal (which can be found here: >>>>>> https://review.openstack.org/#__/c/29781/10 >>>>>> <https://review.openstack.org/#/c/29781/10>), which are: >>>>>> >>>>>> 1) The api changes should allow for a logical, generic future >>>>>> extension for support of inherited roles across all domains >>>>>> etc., should we chose to go that route 2) The use of a single >>>>>> api to list the various grants, filtered by a query string if >>>>>> necessary. >>>>>> >>>>>> My proposal for handling these two objections is as follows: >>>>>> >>>>>> 1) API extensions. >>>>>> >>>>>> There are several aspects of inherited roles that we are trying >>>>>> to cement, which are: >>>>>> >>>>>> a) The are dynamic - i.e. this isn't a case of a short hand for >>>>>> saying add this role to all the current projects in the domain >>>>>> - rather it is a role assignment that is attached to the domain >>>>>> but is added to the effective roles of any project (now and in >>>>>> the future) that exists in this domain b) The are separate from >>>>>> a role that is on the domain itself - i.e. we need to ensure >>>>>> that we keep separate inherited and non-inherited roles. c) >>>>>> Maintain the philosophy that If you can create a role >>>>>> assignment with a given API, there should be an equivalent to >>>>>> read it back and delete it (i.e. you mustn't have the case >>>>>> where, for instance you can list a grant, but can't delete it >>>>>> at the conceptual level) >>>>>> >>>>>> The current proposal had been to do this by adding an >>>>>> "inherited" component of the url for create, check and delete >>>>>> grants to a domain, e.g. >>>>>> >>>>>> PUT /domains/{domain_id}/users/{__user_id}/roles/{role_id} PUT >>>>>> /domains/{domain_id}/users/{__user_id}/roles/{role_id}/__inherited >>>>>> >>>>>> >> GET /domains/{domain_id}/users/{__user_id}/roles/{role_id} >>>>>> GET >>>>>> /domains/{domain_id}/users/{__user_id}/roles/{role_id}/__inherited >>>>>> >>>>>> >> DELETE /domains/{domain_id}/users/{__user_id}/roles/{role_id} >>>>>> DELETE >>>>>> /domains/{domain_id}/users/{__user_id}/roles/{role_id}/__inherited >>>>>> >>>>>> >> etc. >>>>>> >>>>>> A counter proposal has been made to expand this, along this >>>>>> lines of: >>>>>> >>>>>> Role applicable to all projects within a domain PUT >>>>>> /domains/{domain_id}/users/{__user_id}/roles/{role_id}/__projects >>>>>> >>>>>> >>>>>> >> Roles inherited by all projects in all domains >>>>>> PUT /usrs/{user_id}/roles/{role___id}/projects >>>>>> >>>>>> Roles inherited by all domains, at the domain level PUT >>>>>> /usrs/{user_id}/roles/{role___id}/domains >>>>>> >>>>>> While I understand the desire to have extensibility if we wish >>>>>> to provide more "global-ness" of roles, I think the above >>>>>> proposal is less clear about whether these assignments are >>>>>> dynamic (see item a) above). How about this as a counter >>>>>> proposal: >>>>>> >>>>>> Role applicable inherited by all projects within a domain (this >>>>>> is the same as the current proposal) PUT >>>>>> /domains/{domain_id}/users/{__user_id}/roles/{role_id}/__inherited >>>>>> >>>>>> >>>>>> >> Roles inherited by all projects in all domains - if we were to >>>>>> ever support this (not part of the current proposal) PUT >>>>>> /domains/users/{user_id}/__roles/{role_id}/inherited >>>>>> >>>>>> Roles inherited by all domains, at the domain level - if we >>>>>> were to ever support this (not part of the current proposal) >>>>>> PUT /domains/users/{user_id}/__roles/{role_id}/inherited >>>>>> >>>>>> To go along with the above, you would have the respective GET, >>>>>> CHECK & DELETE versions of those apis. >>>>>> >>>>>> 2) Single vs multiple apis I think this comment is actually >>>>>> misplaced in the gerrit review, and is intended to directed at >>>>>> the api extensions I proposed to allow the list of a users >>>>>> "effective" roles on a project (i.e. directly assigned, those >>>>>> by virtue of group membership and inheritance from the parent >>>>>> domain). For this, I proposed adding an optional "effective" >>>>>> query parameter to each of: >>>>>> >>>>>> List user's roles on project: `GET >>>>>> /projects/{project_id}/users/{__user_id}/roles List group's >>>>>> roles on project: `GET >>>>>> /projects/{project_id}/groups/__{group_id}/roles Check user's >>>>>> role on project: `GET >>>>>> /projects/{project_id}/users/{__user_id}/role/{role_id} Check >>>>>> group's roles on project: `GET >>>>>> /projects/{project_id}/groups/__{group_id}/role/{role_id} >>>>>> >>>>>> e.g. GET >>>>>> /projects/{project_id}/users/{__user_id}/roles?effective >>>>>> ...would get you the effective roles the user has on that >>>>>> project, as opposed to only the directly assigned ones if you >>>>>> issue the call without the "effective" query parameter. >>>>>> >>>>>> Dolph and I had already been discussing that the existing v3 >>>>>> api of: >>>>>> >>>>>> GET /users/{user_id}/roles >>>>>> >>>>>> ...which is meant to return all the role assignments for a >>>>>> user, but is in fact broken in the current Grizzly code (it >>>>>> always returns an error). So I agree with the proposal that we >>>>>> should scrap the "effective" query parameter for the specific >>>>>> list/check calls for the project - and instead properly >>>>>> implement the "get all assignments for a user" call. I propose >>>>>> the amended spec for this call is: >>>>>> >>>>>> #### List a user's effective role assignments: `GET >>>>>> /users/{user_id}/role-__assignments` >>>>>> >>>>>> query_string: page (optional) query_string: per_page (optional, >>>>>> default 30) query_string: id, project_id, domain_id >>>>>> >>>>>> Response: >>>>>> >>>>>> Status: 200 OK >>>>>> >>>>>> [ { "id": "--role-id--", "name": "--role-name--", "project_id": >>>>>> "--project-id--", "source": { "direct": true, (optional) >>>>>> "domain_inherited: "--domain-id--", (optional) >>>>>> "group_membership: "--group-id--" (optional) } }, { >>>>>> "domain_id": "--domain-id--", "id": "--role-id--", "name": >>>>>> "--role-name--", "source": { "direct": true, (optional) >>>>>> "group_membership: "--group-id--" (optional) } } ] >>>>>> >>>>>> The "source" structure must have at least one of the values >>>>>> given above (and could have more than one, e.g. both >>>>>> domain_inherited and global_membership for a project where the >>>>>> role is due to a group role that is inherited from the domain). >>>>>> If were even to support global roles across all domains, then >>>>>> we would extend the "source structure" accordingly. I'm open >>>>>> to other options for the above format. however, so comments >>>>>> welcome. >>>>>> >>>>>> Does this sounds like a reasonable plan overall? >>>>>> >>>>>> Henry >>>>>> >>>>>> >>>>>> >>>>>> _________________________________________________ OpenStack-dev >>>>>> mailing list [email protected].__org >>>>>> <mailto:[email protected]> >>>>>> http://lists.openstack.org/__cgi-bin/mailman/listinfo/__openstack-dev >>>>>> >>>>>> >> <http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev> >>>>>> >>>>>> >>>>>> _________________________________________________ OpenStack-dev >>>>>> mailing list [email protected].__org >>>>>> <mailto:[email protected]> >>>>>> http://lists.openstack.org/__cgi-bin/mailman/listinfo/__openstack-dev >>>>>> >>>>>> >> <http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev> >>>>>> >>>>>> >>>>>> _______________________________________________ OpenStack-dev >>>>>> mailing list [email protected] >>>>>> <mailto:[email protected]> >>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >>>>> >>>>> >>>>> >>>>> >>>>>> >> _______________________________________________ >>>>> OpenStack-dev mailing list [email protected] >>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >>>>> >>>> >>> >> >> _______________________________________________ >> OpenStack-dev mailing list >> [email protected] >> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev > > > _______________________________________________ > OpenStack-dev mailing list > [email protected] > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev > _______________________________________________ OpenStack-dev mailing list [email protected] http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
