Bug 1041953

Summary: [RFE][keystone]: Service_id binding with role definition
Product: Red Hat OpenStack Reporter: RHOS Integration <rhos-integ>
Component: RFEsAssignee: RHOS Maint <rhos-maint>
Status: CLOSED UPSTREAM QA Contact:
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: unspecifiedCC: markmc, yeylon
Target Milestone: ---Keywords: FutureFeature
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
URL: https://blueprints.launchpad.net/keystone/+spec/serviceid-binding-with-role-definition
Whiteboard: upstream_milestone_none upstream_status_unknown upstream_definition_new
Fixed In Version: Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-03-19 17:07:23 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description RHOS Integration 2013-12-12 20:16:16 UTC
Cloned from launchpad blueprint https://blueprints.launchpad.net/keystone/+spec/serviceid-binding-with-role-definition.

Description:

###Problem and Proposal###

In the current "OpenStack Identity V3 API" Roles (Role Definition) entities are just a named identifiers, this approach of defining role definition is problematic and does not extend well to support future need of a cloud provider due to

1. Role name has to be unique across all the services which is not an scalable model as cloud provider has to support multiple services where name collision may arise.

    Cloud provider has to support two database services (MySql and PostgreSql) both services can end up with role name collision (e.g. db-admin).
    Service providers has to always come up with descriptive names for the roleDefs (nova-admin, swift-admin etc....)
    Since cloud providers has to always come up with distinct names for the roleDefs, renaming a service may require updating all of the roles which has the service names in them.
    There's no single *enforceable* convention for the role naming. Meaning it is really up to the services to coordinate among themselves to make sure the names are globally unique. This will be difficult for a cloud provider as services are independent of each other . (e.g. PaaS/SaaS like services on top of IaaS cloud)

2. There is no way a middle ware can filter out unwanted roles from token while redirecting request to service (Nova, Swift, etc....), e.g. As mentioned in the bug below, token scoped to a project which has multiple services associated will have all service roles in it. A middle ware which operating on behalf of a service X has no way to filter out roles which not related to service X, unless it make some decision based on descriptive role names.

        https://bugs.launchpad.net/keystone/+bug/890411

3. Not friendly for tools (e.g. OpenStack Horizon or any custom tool) which want to filter out the role definitions based on service, this limitation may cause confusion for the admin while doing the role assignment.

To resolve this issue we want to introduce a notion of seriveId in the roles (role definition) model, this way a role definition will be bound to a service and will resolve all the above mentioned issues.

A role definition entity would look as below with serviceId
{
    "role": {
        "id": "76e72a",
        "links": {
            "self": "http://identity:35357/v3/roles/76e72a"
        },
        "name": "admin",
    "serviceId": "--id--"
    }
}
Note:
1. This proposal is backward compatible since service ID is an optional filed, it does not break existing deployments.
2. There would not be any change in policy infrastructure which is built on top of unique role name as even with this proposal role name will be unique per service.

###Proposed API enhancements###

Create role: POST /roles
Request:

{
    "name": ""
    "serviceId": "--id--"
}

Response:

Status: 201 Created

{
    "id": "--role-id--",
    "links": {
        "self": "http://identity:35357/v3/roles/--role-id--"
    },
    "name": "a role name",
    "serviceId": "--id--"
}
List roles: GET /roles

A "seriveId" filter can be supported with this API which will be helpful for tooling support.
query_string: page (optional) query_string: per_page (optional, default 30) query filter for "name" (optional) or "seriveId" (optional)

Response:

Status: 200 OK

[
    {
        "id": "--role-id--",
        "links": {
            "self": "http://identity:35357/v3/roles/--role-id--"
        },
        "name": "a role name",
        "serviceId": "--id--"
    },
    {
        "id": "--role-id--",
        "links": {
            "self": "http://identity:35357/v3/roles/--role-id--"
        },
        "name": "a role name",
        "serviceId": "--id--"
    }
]
ServiceId can be used as filter where ever it make sense
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

###Impact###

1) All the existing roles (currently no service association) will be migrated to and owned by identity service.

2) service_id is optional in new role creation. If absent, it will be defaulted to identity service.

3) DB migration will be required to migrate existing service role definition to support seriveId.


etherpad link: https://etherpad.openstack.org/serviceid-binding-with-role-definition

Specification URL (additional information):

https://etherpad.openstack.org/serviceid-binding-with-role-definition