Identity Pools

Protect API using Role-Based Access Control (RBAC) with Identity Pools Pt. 2

This article is the second part of the Protect API using Role-Based Access Control (RBAC) with Identity Pools blog series. You will deploy APIs behind a gateway, set up a role-based authorization policy, and call the APIs to check access control enforcement.

I Need to Go Back to the First Part

Looking for the first part of the series? Search no more.

Plan of Attack

In the first part of the series, you had prepared Identity Pools with users that have roles assigned. Since we have the pools, authentication context, and token claims already prepared, now, we can proceed and:

  1. Deploy API gateway and APIs.

  2. Define an authorization policy with role restriction.

  3. Test the access control enforcement using the command line.

Deploy API Gateway and APIs

In the grand finale of this series, you will be confirming the access control enforcement. For that, first, we need to deploy an API gateway and some APIs that we will call later on. You can, of course, use any of the gateways you had already integrated with your Cloudentity workspace. If you have not deployed any gateways and integrated them with your workspace using Cloudentity authorizers yet, do not worry. There is plenty of integrations to choose from.

Deploying gateways, integrating them with Cloudentity, and deploying APIs is of no concern of this blog series. We will, however, deploy Cloudentity Pyron Gateway, Pyron Authorizer and some sample APIs provided by Cloudentity.

I Want to Use Different Gateway

If you want to use a different gateway and autorizer, visit our How-Tos and choose one of the below gateways/service meshes, and deploy them with APIs:

Then, in the next sections, just adjust the cURL commands to call the APIs you have deployed behind the gateway of your choice.

Deploy Pyron Gateway, Authorizer, and Sample APIs

  1. Create Pyron Authorizer and deploy the gateway, authorizer, and sample APIs

  2. In your terminal, confirm that everything works as expected and call the /pet/{petId} API using the following command:

    curl http://localhost:8080/pets/pet/1 -v
    

    You should receive the response with the HTTP 200 status as illustrated below:

    *   Trying ::1:8080...
    * Connected to localhost (::1) port 8080 (#0)
    > GET /pets/pet/1 HTTP/1.1
    > Host: localhost:8080
    > User-Agent: curl/7.77.0
    > Accept: */*
    < HTTP/1.1 200 OK
    

Great job! We have successfully deployed an API behind the Pyron Gateway and installed the Cloudentity Pyron Authorizer.

Restrict Access with Role-Based Authorization Policy

Define Policy

Cloudentity authorization policies provide multilevel authorization as the response to modern access control requirements. With our platform you can either create a Cloudentity policy using a visual editor, or create policies in REGO language.

In this section, you will create a Cloudentity authorization policy using the visual editor. The policy will be checking whether the authentication context for the authenticated user contains the roles attribute with value set to admin.

  1. Within your workspace, navigate to Authorization » Policies » + CREATE POLICY.

  2. Define the following policy:

    1. Set the policy type to API request.

    2. Set the policy name to only-admins

      As you can see, the policy ID is set for you automatically. It is created out of your authorization server (workspace) identifier and the policy name. You can change it, of course, but let’s leave it as it is for the purpose of this article.

    3. Set the policy language to Cloudentity.

    Result

    You are taken to the policy creation visual editor.

  3. Remove the default Fail validator.

  4. Select the + button to add a policy validator.

  5. From the attributes list, select AuthN Context » ADD FIELD.

  6. Add the following condition:

    • Set the Field/Attribute (Access Token context) to User roles (this is the roles authN context attribute we’ve added in the Configure Authentication Context and Add Claim to Tokens section of the first blog post)

    • Select contains,set the target to the admin value, and press ENTER.

    • Save your condition.

    Result

    You have added a validator to your policy that checks if authnCtx.roles contains admin value.

  7. Select the tick icon and SAVE.

Assign Authorization Policy to API

  1. Navigate to Enforcement » APIs.

  2. Select the API of your choice from the list that has the Unrestricted (No Policy) label assigned.

    If you already have any other APIs deployed and protected on your tenant and want to test the enforcement with the new policy, feel free to do so!

    For the purpose of this article, we will select the /pet/{petId} endpoint of the petstore service we deployed in the previous sections.

  3. Select the only-admins authorization policy from the list and save.

Verify RBAC Using Command Line

Now, we are going to verify if our policy works and the user roles we defined are taken into account.

  1. Call the API you decided to protect with the policy in the second step of the Assign Authorization Policy to API section.

    Example:

    curl http://localhost:8080/pets/pet/1 -v
    

    Result:

    *   Trying ::1:8080...
    * Connected to localhost (::1) port 8080 (#0)
    > GET /pets/pet/1 HTTP/1.1
    > Host: localhost:8080
    > User-Agent: curl/7.77.0
    > Accept: */*
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 403 Forbidden
    < content-length: 0
    <
    * Connection #0 to host localhost left intact
    

    As you can see, the access is denied. This time, it happens because we did not include an access token in our request to the /pet/{petId} endpoint protected by our authorization policy.

  2. Get a raw access token from the Demo Application.

    If you need help, go back to the Verify Contents of Minted Access Tokens section of the first part of the series.

  3. Add the Authorization: Bearer $AT request header to your request where the $AT variable stands for the raw access token you got in the second step and call the /pet/{petId} API:

    Example:

    curl http://localhost:8080/pets/pet/1 -v -H "Authorization: Bearer $AT"
    

    Result:

    *   Trying ::1:8080...
    * Connected to localhost (::1) port 8080 (#0)
    > GET /pets/pet/1 HTTP/1.1
    > Host: localhost:8080
    > User-Agent: curl/7.77.0
    > Accept: */*
    > Authorization: Bearer $AT
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < Content-Type: text/plain
    < Date: Thu, 06 Oct 2022 22:34:57 GMT
    < content-length: 1933
    <
    Request served by fac31687f498
    
    HTTP/1.1 GET /pet/1
    
    Host: echo-service:4000
    Accept: */*
    Authorization: Bearer $AT
    Content-Length: 0
    Uber-Trace-Id: 90a6bef0a1f9ca0a:9faec293c698fdc9:90a6bef0a1f9ca0a:1
    User-Agent: curl/7.77.0
    X-Forwarded-For: 172.19.0.1
    X-Forwarded-Host: localhost:8080
    X-Forwarded-Proto: http
    X-Real-Ip: 172.19.0.1
    * Connection #0 to host localhost left intact
    

    As you can see, we got the HTTP 200 OK status. Our request was successful since we included a valid access token that did contain the roles claim with the value coming from the authN context.

  4. Now, let’s get rid of our user’s admin privileges. Navigate to your tenant level configuration for Identity Pools, select the Users tab.

  5. Select your user and within their metadata delete the admin role.

    Optionally, change the value of the role to, for example, user.

  6. Get a raw access token from the Demo Application again - this time it does not include the roles claim set to admin.

    If you need help, go back to the Verify Contents of Minted Access Tokens section of the first part of the series.

  7. Add the Authorization: Bearer $AT request header to your request where the $AT variable stands for the raw access token you got in the second step and call the /pet/{petId} API:

    Example:

    curl http://localhost:8080/pets/pet/1 -v -H "Authorization: Bearer $AT"
    

    Result:

    *   Trying ::1:8080...
    * Connected to localhost (::1) port 8080 (#0)
    > GET /pets/pet/1 HTTP/1.1
    > Host: localhost:8080
    > User-Agent: curl/7.77.0
    > Accept: */*
    > Authorization: Bearer $AT
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 403 Forbidden
    < content-length: 0
    <
    * Connection #0 to host localhost left intact
    

    Since the access token we got from the Demo Application this time did not have the roles claim set to admin the request is denied by the Pyron Authorizer.

Congratulations! You have successfully configured and enforced RBAC

Your APIs are now protected with Role-Based Access Control.

Video

Summary

You have successfully completed the Protect API using Role-Based Access Control (RBAC) with Identity Pools series! You deployed some sample APIs behind a gateway and installed Cloudentity authorizer. You created a role-based authorization policy and confirmed that your APIs are now fully protected by this policy and the Cloudentity authorizer.

What Next in the Menu

Now that you have full working knowledge on how to set up Identity Pools, Identity Schemas, User Metadata, deploy APIs behind gateways, and set up role-based access control, you can change the protected APIs from the Quickstart demo to your real setup. If you have any other gateways deployed with APIs, you can extend the authorization perimeter with Role-Based Access Control over all APIs that need it. Is that all? Of course, not.

Since this article introduced you to RBAC scenarios and now you know how to set it up, you do not need to limit yourself just to Identity Pools. It is possible that you use different IDPs for different types of users like partners, customers, end-users, and more. Cloudentity provides you with connectors to many major Identity Sources. If your IDP uses user groups or roles, you already know the pattern for how to map the attributes from your IDP to common authN context and then map it to token claims. By aggregating the IDPs and normalizing the tokens you use, different types of applications can access the same resources without any hassle. With Cloudentity-standardized authN context schema, the RBAC policy you created will work with any IDP you integrate with Cloudentity!

Additionally, if your IDP does not support user groups/roles and you are using an external system for that functionality, you can use Cloudentity Extension Scripts and either modify the authN context after user authentication or enrich token claims

Updated: Nov 2, 2023