You can implement Role-Based Access Control (RBAC) with Repose using the Authentication and Authorization mechanisms. This guide takes you through the process of setting up RBAC with Repose.

1. Configure the Header Normalization filter

To prevent users from submitting their own roles, you will need to blacklist headers using the Header Normalization filter.

header-normalization.cfg.xml
<header-filters>
...
    <target>
        <blacklist id="ReposeHeaders">
            <header id="X-Authorization"/>
            <header id="X-Identity-Status"/>
            <header id="X-Impersonator-Id"/>
            <header id="X-Impersonator-Name"/>
            <header id="X-PP-Groups" />
            <header id="X-PP-User" />
            <header id="X-Roles"/>
            <header id="X-Tenant-Id"/>
            <header id="X-Tenant-Name"/>
            <header id="X-User-Id"/>
            <header id="X-User-Name"/>
        </blacklist>
    <target>
</header-filters>

Please refer to the Header Normalization filter documentation for more information about the available configuration options.

2. Configure then Authentication filter

The Authentication filter will grab the user’s roles from their authentication token and return those roles to Repose.

Please refer to the Keystone v2 filter documentation for more information about the available configuration options.

3. Configure the RBAC filter

There are two mechanisms for doing the Authorization side. If your API is minimal or your just getting started with it, then you might find the Simple RBAC filter most useful. It uses a very simple Domain Specific Language (DSL) that is similar to what other tools use for this basic mechanism. If on the other had your API is large and/or your authorizations are complex, then you will need the heavy lifting of the API Validator filter.

1. What do you need?

We recommend that you build a table similar to the example below that contains endpoints and the roles that you wish to allow access to those endpoints.

Capability Role

Method name

Endpoint

HTTP Method

a:creator

a:observer

a:admin

Create New Widget

/a/

POST

x

 

x

List Widgets

/a/

GET

 

x

x

Replace Widget

/a/

PUT

x

x

x

Delete Widget

/a/

DELETE

 

 

x

2. Decide on the right filter for you.

From here you have to decide which filter you want to use. There are two options and they both use the same underlying mechanism for enforcement. The only real difference between them is the first option is simple and easy, while the second option has more features which require a little extra configuration.

1. Simple RBAC filter

The Simple RBAC filter is configured using a Domain Specific Language (DSL) similar to the table above.

simple-rbac.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<simple-rbac xmlns="http://docs.openrepose.org/repose/simple-rbac/v1.0">
    <resources>
/path/to/this   GET     role1,role2,role3,role4
/path/to/this   PUT     role1,role2,role3
/path/to/this   POST    role1,role2
/path/to/this   DELETE  role1
/path/to/that   GET,PUT ALL
/path/to/that   ALL     role1
/path/{to}/wild GET     role1
    </resources>
</simple-rbac>

The best part about this filter is that if your API grows or simply becomes to complex for the Simple RBAC filter, then you can easily move to the full API Validator filter later. There is even a setting available to save your Simple RBAC filter configuration in a manner that you can use it immediately with the API Validator filter.

Please refer to the Simple RBAC filter documentation for more information about the available configuration options.

2. API Validator filter

If your API is complex or you simply need or are already using some of the extra features available in the API Validator filter, then this is the choice for you.

1. Enable RAX-Roles

When the enable-rax-roles attribute for the API Validator filter is set to true, the check-headers attribute will also be enabled regardless of your setting.

validator.cfg.xml
<?xml version="1.1" encoding="UTF-8"?>
<validators multi-role-match="true" xmlns='http://openrepose.org/repose/validator/v1.0' version="1">
    <validator role="default"
               default="true"
               wadl="file:///my/wadl/filewithraxroles.wadl"
               dot-output="/tmp/default.dot"
               enable-rax-roles="true"
    />
</validators>
2. Utilize RAX-Roles

In the WADL, include rax:roles with appropriate values to ensure access is controlled as expected. When defining rax:roles at the resource level, be aware that all sub-resources and methods will inherit the roles allowed at the resource level. Multiple roles can be specified by separating the role names with a space. If multiple roles are authorized for a resource and method, the user must have one of the allowed roles but is not required to have all roles. Example API Validator filter configuration for RBAC. The following example shows a section of the API Validator filter and WADL that is configured for RBAC.

api_with_roles.wadl
<application xmlns="http://wadl.dev.java.net/2009/02" xmlns:rax="http://docs.rackspace.com/api">
    <resources base="https://test.api.openstack.com">
        <resource path="/a" rax:roles="a:admin">
            <method name="POST" rax:roles="a:creator">
                <request>
                    <representation mediaType="application/xml"/>
                </request>
            </method>
            <method name="GET" rax:roles="a:observer">
                <request>
                    <representation mediaType="application/xml"/>
                </request>
            </method>
            <method name="PUT" rax:roles="a:observer a:creator">
                <request>
                    <representation mediaType="application/xml"/>
                </request>
            </method>
            <method name="DELETE">
                <request>
                    <representation mediaType="application/xml"/>
                </request>
            </method>
        </resource>
    </resources>
</application>

With the above WADL and API Validator filter configuration, the following behavior will apply with a request with a user that has the a:observer role.

  • GET or PUT is allowed.

  • DELETE will return Forbidden (403) as the DELETE method inherits the a:admin role from its parent resource.

  • PATCH will return Method Not Allowed (405).

  • POST will return a Forbidden (403), as the method is allowed for the resource but the user does not have the a:admin or the a:creator role.

Please refer to the API Validator filter documentation for more information about the available configuration options.

Table 1. Return codes and conditions
Description Response Code Returned When:

Forbidden

403

A requested resource or method requires a specific X-Roles header and that header is not found.

Method Not Allowed

405

The URI is valid, but the method is not appropriate for the URI.

The status codes returned by authorization failures, via rax:roles extensions (403), differs from the statuses returned when roles are defined directly in the validator.cfg.xml (404 and 405).

4. Enable Tenant Culling based on Relevant Roles

1. Do you need only Relevant Tenants?

If your origin service requires the X-Tenant-Id header to contain only the tenant id’s pertinent to the RBAC Authorization roles that were provided in the X-Relevant-Roles header, then enable the Tenant Culling filter.

2. How to enable Tenant Culling

The following example shows a basic System Model that enables the Tenant Culling filter.

system-model.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>

<system-model xmlns="http://docs.openrepose.org/repose/system-model/v2.0">
    <repose-cluster id="repose">
        <nodes>
            <node id="repose_node1" hostname="localhost" http-port="8080"/>
        </nodes>

        <filters>
            <filter name="header-normalization"/>
            <filter name="keystone-v2"/>
            <filter name="simple-rbac"/>
            <filter name="tenant-culling"/>
        </filters>

        <destinations>
            <endpoint id="local" protocol="http" hostname="localhost" root-path="/" port="8000" default="true"/>
        </destinations>
    </repose-cluster>
</system-model>

There is no further configuration of this feature. Simply by including the Tenant Culling filter in the System Model after the Authentication and RBAC filters, it is enabled.

Even though the Header Normalization filter isn’t strictly required for tenant culling to work, it is a good idea to always include it before any Authentication filters.

Please refer to the Tenant Culling filter documentation for more information about this feature.