Name spaced roles

Registered by Arvind Tiwari

Introduction:
========

In a large scale cloud establishments, different services (Nova, Swift, Cinder, Keystone etc…..) are managed by separate teams, these teams may operates from different geography and time zones (Let's call them “service deployers” or “service teams”). These teams don't want to depend on another team (Keystone Admin) to manage their service life cycle (e.g. The service deployer of NOVA don’t want to depend on Keystone Admin to manage their service specific entities). Through this BP we want to resolve one of the bottleneck experienced by these teams while managing their service life cycle.

In the current Keystone model, a service typically have two entities created in keystone to become a cloud service, those are “service definition” and endpoint(s). Let's call them "service artifacts"

Service definition: https://github.com/openstack/identity-api/blob/master/openstack-identity-api/v3/src/markdown/identity-api-v3.md#services-v3services

Endpoint: https://github.com/openstack/identity-api/blob/master/openstack-identity-api/v3/src/markdown/identity-api-v3.md#endpoints-v3endpoints

Following are some of service life cycle events which are triggered by business requirements and need updates/addition on these service artifacts

1. Rename service (e.g. Nova to VMS).
2. Move a service endpoint to public from internal.
3. Disable a service endpoint from particular region for maintenance purpose.
4. Add another region by adding new endpoint.

These service artifacts (Service and/or Endpoint(s)) are bound to a service_id, changes made on one service artifact(s) would not affect another service. Right now a change/addition required on service artifacts need a Keystone Admin to step in and make those changes on behalf of service deployer. This is not a desirable model to run a large scale cloud system and creates bottleneck on Keystone Admin. Ideally a service deployers should be allowed to manage life cycle of a particular service through designated Keystone REST APIs.

Problem:
=====
In the current "OpenStack Identity V3" specification Roles (Role Definition) are global entities and shared among all services on cloud infrastructure. A change in Role would screwup smooth functioning of another service. This approach of managing roles is not sufficient to handle some of use case which is extremely required for a large scale cloud establishment and also creates bottleneck on keystone Admin. Example below

1. A service deployer (e.g. NOVA) wants to have a new role setup in keystone for their purpose only.

2. A service deployer want to rename an existing role (e.g. Admin to VM-Admin) and want to reconcile role assignments exists with old role.

3. A service deployer want to hide (disable) a role for further role assignments from particular region. (Not the scope of this BP)

4. A service deployer want to reserve a role for service admins and never what it to be used by service end users. (Not the scope of this BP)

5. Cloud provider want to make all individual service deployers self sufficient, so that they can manage their service artifacts (Service, Endpoints, including Roles) without depending on Keystone.

6. Not friendly for tools (e.g. OpenStack Horizon or any custom tool) who want to filter out the role definitions based on service, this limitation may cause confusion for the admins while doing the role assignment. (e.g. Foo role which is good for FooSvc will be visible for role assignment on Bar service).

7. There is no way a middle-ware can filter out unwanted role from the validate token response, which can cause https://bugs.launchpad.net/keystone/+bug/890411.

8. There is no way a use can request service scoped token. (get token scoped to project "xyx" for nova service)

9. Dependency on Keystone Admin for managing service life cycle is not scalable as well as not an agile process.

10. A cloud provider may have to support service (PaaS/SaaS) which are not an OpenStack services but follows RBAC model for Authz. These service wants to have roles created in Keystone and they want to manage the roles entity without depending on Keystone Admin.

Solution:
=====

ayoung: long discussion about this at the summit. The solution below is the right general approach, with the following caveats:
1. Services and Endpoints are only two possible ways to scope a role. There very well may be others in the future.
2. Even though a role may defined in the context of a service, there is nothing that should limit assigning that role only within the context of the service.

Service and Endpoint data model are scoped to an id (service_id), which represents a service in cloud infrastructure. Entities created with these data models are scoped to a particular service and created only when a new service what to on-board over/under the cloud. An update made on these entities for a particular service should not affect another service state or smooth functioning of other service.

Role (or Role definition): https://github.com/openstack/identity-api/blob/master/openstack-identity-api/v3/src/markdown/identity-api-v3.md#roles-v3roles

All the above mentioned problem can be resolved by namescaping scoping roles (role definition). Since the problem of namespacing is open ended, it makes sense to allow nesting of namespaces. Instead of inveting a new abstraction to cover the namespaceing of roles, we will instead allow one role to be nested inside another role. Thus, if one role is named "keystone" and it has nested inside a role name "manager" the effective role would be the "keystone","manager" or, potentially, "keystone:manager"

The ability to define new roles is itself an RBAC protected resource. Role Definitions will be managed resources, and contained within projects. Thus, it may be that the default set of roles stays Managed by users with the role "admin" in the the default domain, but a project named "keystone" would also containt the role "keystone" and a user with the role "admin" on the Keystone proejct would be able to create new subroles roles under the role "keystone."

**Scoping roles to a service does not mean a roles name (e.g. Admin) cannot be global or can not be used by another service. Multiple services can use same role name by creating a roles entity with same name scoped to that service.**

This way we can envision a real "Service Deployer" user (an identity in Keystone) scoped to a particular service and manages service life cycle for a service without depending on Keystone Admin.

Note: Imagine a "Service Deployer" is special user account created in Keystone administrative domain with certain privilege so that he/she can manage only a specified service. Keystone has to control the access on these entities, so that deployer of one service can not mess-up with another service artifacts. (How? need some enhancement )

Benefit:
====
1. All the required entities Service, Endpoint(s) and Role(s) are bound to a service_id and logically scoped to a service.

2. This way a service deployer can manage the service life cycle without depending on keystone Admin.

3. No data migration needed to handle problem #2

4. Keystone can create a role (e.g. svc-deployer scoped to services) and fine grained RBAC policy can be defined around the service_id to protect Foo-service from accidental update from deployer of Bar-service (or any malicious user). (e.g. role=svc-deployer and service_id=foo-svcId)

5. Apart from other problems, service deployer will achieve autonomy and don’t have to deal with keystone bottleneck issues.

6. Possible to have project and service scoped token.

Blueprint information

Status:
Complete
Approver:
None
Priority:
Undefined
Drafter:
Arvind Tiwari
Direction:
Needs approval
Assignee:
Arvind Tiwari
Definition:
Obsolete
Series goal:
Accepted for icehouse
Implementation:
Unknown
Milestone target:
None
Completed by
Dolph Mathews

Related branches

Sprints

Whiteboard

https://review.openstack.org/#/c/61897

Services can already require "service-name:role-name" via policy enforcement if they prefer, making everything here redundant AFAICT.

ayoung: No, as that is only on the "enforcing" side. There is nothing that allows the creationg of "service-name:role-name" in keystone. This is mostly about how to define the roles so that, when the user creates a token, they get the proper role assignments

atiwari:
If "service-name:role-name" is the role name we are thinking of it is not going to address some of the issues mentined in the BP. at least
1. Role name has to change if Service name changes.
2. There is no fix service_id in role definition around which we can setup policy in keystone.

David Chadwick
This blueprint seems to be confusing multiple issues and lumping them together under some vague concept of role scoping (I say vague because it is never spelt out exactly what a role scope is).
<< atiwari: Role scoping means linking a role definition (entity in keystone DB) to a service. Same as Service definition and endpoints are link (or scoped) to a service using a service_id field.
Right now it seems, services which are ultimate consumer of role does not have right to choose a role name, because role entities (in keysone DB) are not scoped to services.
>>

1. There is the issue of naming roles. Naming roles should have nothing to do with a role's permissions
<< atiwari: I want to link role with service so changing role "Admin" to "VM-Admin" will not affect other services. And RBAC policy can be defined to protect who can change "Admin" to "VM-Admin".
>>

2. There is the issue of what permissions a role has. This should be completely separate from a role's name
<< atiwari: Correct but Role definition data model has to have some extra information, so that RBAC policy can be defined. service_id linkage is give that information.
It has nothing to do with Role permission, which is governed by policy in service side (e.g. Nova define privilege for role "Admin" and Swift has it own understanding of Admin role).
>>

3. There is the issue of scoping of roles. I dont know precisely what you mean by a role scope, but presumably it is some sort of limit on the permissions that the role has. A permission is an action on an object. So you probably want to limit the objects that an action can be performed on. If this is the case, then you should be very clear that when you refer to the scope of a role, you are referring to the collection of objects that a role can have permissions assigned for.
<<atiwari: Let me explain, By scoping a role I mean linking a role entity to a service which is nothing to do with role permission. So if Nova and Swift both want to have role with name "Admin" then there will be two separate entities created in DB one for Nova and another for Swift. Thant way if in any point of time Nova want to rename his role name to "Nova-Admin" it would not be an issue for Swift service. Currently "Admin" role name is shared and any change in role name wd trigger policy update for all service who are using the "Admin" role name.
My proposal in: https://etherpad.openstack.org/p/service-scoped-role-definition
>>

Proposed solutions
1. Roles should be named hierarchically, and this makes their names globally unique. Currently all role names are unique since they are simple strings taken from the same name space. But if we introduce hierarchical role names, then an object that already has a global name can create a new role and prepend its own name to the role name. This could apply to domains, projects, services etc. They all could create their own role names. So if domain A creates a role named admin, the globally unique name for the role would be "domain.A.admin". If project B creates a role named admin then its globally unique name would be "project.B.admin". If service A creates a role named admin then the globally unique role name would be "service.A.admin". This is a completely general model and will ensure that no role names will ever clash when they are created by different authorities. Note that the naming of roles does not imply any restrictions on their permissions ie. the role "project.B.admin" could be assigned permissions to run jobs in domain A, delete files in Swift for project A etc.
<<atiwari: Let me take a "Nova" service for example, as per your comment "Admin" for Nova will be "service.nova.admin". Problem with this naming convention is you have to rename your roles if you want to rename your service. Let say I want to rename "Nova" to "VMS" then all role definition under ""service.nova" name space has to renamed to "service.vms". The same issue goes with project or domain roles.
Lets take project roles, as per below link projects can have same names in two domains. That means two projects with same (e.g. myProject) name (in different domains) can not have role name admin. Because if one project have role "project.myProject.Admin" no other project can define the same.
https://github.com/openstack/identity-api/blob/master/openstack-identity-api/v3/src/markdown/identity-api-v3.md#projects-v3projects
>>
2. Assigning permissions to roles can only be done by entities that already have the permissions they wish to assign. It should not be possible for an administrator, user or service to assign a permission to a role that he/she/it does not already have. Software should check that when a role is assigned a permission, the assigner has the permission that is being assigned.
<<atiwari: This is debatable topic and out of scope for this BP. Note: In keystone permission is defined by policy and policy can be edited by any body who has access to environment, system (keystone) can not able to verify who made the policy change.
>>
3. Scoping of role permissions to a set of objects should be done by the entity that creates the role. The object scope would be held as meta data by Keystone. It should not be reflected in the name of the role, as this would get too messy. Rather the role's object scope would be part of the meta data, and when an entity wishes to assign a permission to a role, the software will check that the object in the permission is contained in the object scope of the role, otherwise the assignment is rejected. So for example, a service could create a role, and scope the role to itself (meaning that only operations on the service can be assigned to the role). Or the same service could create a role and not scope it at all (meaning that any permission can be assigned to the role)
<< atiwari: This BP has nothing to do with role permission. Permissions are mapped to roles at service side, that is how same role name has different meaning in two systems (E.g. role name "Admin" for Nova and Swift)
All I am trying to advocate here is concrete linking of role definition to a service. So that roles "Admin(Nova)" and "Admin(Swift)" will be two separate entities in keystone DB.
>>

Marked obsolete and untargeted as the API proposal has been rejected. -Dolph

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.