Bug 1127057

Summary: [RFE][ceilometer]: Enhance Ceilometer API Role Based Access Control in Preparation for Keystone v3 API
Product: Red Hat OpenStack Reporter: RHOS Integration <rhos-integ>
Component: RFEsAssignee: RHOS Maint <rhos-maint>
Status: CLOSED WONTFIX QA Contact:
Severity: high Docs Contact:
Priority: unspecified    
Version: unspecifiedCC: markmc, mburns, pkilambi, srevivo
Target Milestone: Upstream M1Keywords: FutureFeature
Target Release: 7.0 (Kilo)   
Hardware: Unspecified   
OS: Unspecified   
URL: https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3
Whiteboard: upstream_milestone_kilo-1 upstream_definition_new upstream_status_implemented
Fixed In Version: Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-11-18 14:23:28 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description RHOS Integration 2014-08-06 04:04:27 UTC
Cloned from launchpad blueprint https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3.

Description:

Current access control for the API is all or nothing.  A policy.json file is used but it simply determines if the user is admin, granting all privileges, or scoping for a single project.

With upcoming Keystone v3 enhancements we can expand the granularity of access control to allow cross-project access by non-admins.  This functionality will be useful for admins of groups of users/tenants who should not be the admin of the entire system.

We will accomplish this by using a decorator on the API functions.  The decorator will control access based on user/tenant roles and rules specified in the policy json file.

Example of decorator usage in v2 reporting API:
    @wsme_pecan.wsexpose([OldSample], [Query], int)
    @rbac_validate.protected('meters')
    def get_all(self, q=None, limit=None):
        """Return samples for the meter.

        :param q: Filter rules for the data to be returned.
        :param limit: Maximum number of samples to return.
        """
Decorator contains code similar to what's in acl.py already, but sets project/users here instead of various places within the v2.py code:

def protected(controller_class):

    global _ENFORCER
    if not _ENFORCER:
        _ENFORCER = policy.Enforcer()

    def wrapper(f):
        @functools.wraps(f)
        def inner(self, **kwargs):
            pdb.set_trace()
            self._rbac_context = {}
            if not _ENFORCER.enforce('context_is_admin',
                                     {},
                                     {'roles': pecan.request.headers.get('X-Roles', "").split(",")}):
                self._rbac_context['project_id'] = pecan.request.headers.get('X-Project-Id')
                self._rbac_context['user_id'] = pecan.request.headers.get('X-User-Id')
            return f(self, **kwargs)
        return inner
    return wrapper

acl.py could be deprecated since its only function is to determine if a user is admin, and the decorator accomplishes this.

Example policy expansions:

Current policy.json only verifies user is admin:
{
    "context_is_admin":  [["role:admin"]]
}

New rules allow separation of access control by method and expanded roles.  Also compatible with Keystone v3 expanded functionality where domains are supported.
{
    "context_is_admin":  [["role:admin"]],
    "admin_or_cloud_admin": [["rule:context_is_admin"],["rule:admin_and_matching_project_domain_id"]],
    "telemetry:alarm_delete":  [["rule:admin_or_cloud_admin"]]
}


Specification URL (additional information):

None