RBAC With API Gateway and Open Coverage Agent (OPA)
With varied entry management fashions and implementation strategies accessible, establishing an authorization system for backend service APIs can nonetheless be difficult. Nevertheless, the last word purpose is to make sure that the right particular person has applicable entry to the related useful resource. On this article, we’ll talk about methods to allow the Function-based entry management (RBAC) authorization mannequin in your API with open-source API Gateway Apache APISIX and Open Policy Agent (OPA).
What Is RBAC?
Role-based access control (RBAC)and attribute-based access control (ABAC) are two generally used entry management fashions used to handle permissions and management entry to sources in laptop programs. RBAC assigns permissions to customers primarily based on their function inside a company. In RBAC, roles are outlined primarily based on the capabilities or obligations of customers, and permissions are assigned to these roles. Customers are then assigned to a number of roles, and so they inherit the permissions related to these roles. Within the API context, for instance, a developer function may need permission to create and replace API sources, whereas an end-user function would possibly solely have permission to learn or execute API sources.
Principally, RBAC assigns permissions primarily based on consumer roles, whereas ABAC assigns permissions primarily based on attributes related to customers and sources.
In RBAC, a coverage is outlined by the mixture of a consumer’s assigned function, the actions they’re approved to carry out, and the sources on which they will carry out these actions.
What Is OPA?
OPA (Open Policy Agent) is a coverage engine and a set of instruments that present a unified method to coverage enforcement throughout a complete distributed system. It lets you outline, handle, and implement insurance policies centrally from a single level. By defining insurance policies as code, OPA allows simple overview, enhancing, and roll-back of insurance policies, facilitating environment friendly coverage administration.

OPA gives a declarative language referred to as Rego, which lets you create and implement insurance policies all through your stack. While you request a coverage determination from OPA, it makes use of the foundations and information that you’ve offered in a .rego
file to guage the question and produce a response. The question result’s then despatched again to you because the coverage determination. OPA shops all of the insurance policies and the info it wants in its in-memory cache. In consequence, OPA returns outcomes shortly. Right here is an instance of a easy OPA Rego file:
bundle instance
default permit = false
permit
enter.methodology == "GET"
enter.path =="/api/useful resource"
enter.consumer.function == "admin"
On this instance, we’ve got a bundle referred to as “instance” that defines a rule referred to as “permit”. The “permit” rule specifies that the request is allowed if the enter methodology is “GET”, the requested path is /api/useful resource
, and the consumer’s function is “admin”. If these circumstances are met, then the “permit” rule will consider as “true”, permitting the request to proceed.
Why Use OPA and API Gateway for RBAC?
API Gateway gives a centralized location to configure and handle API, and API customers. It may be used as a centralized authentication gateway by avoiding having every particular person service implement authentication logic contained in the service itself. Then again, OPA provides an authorization layer and decouples the coverage from the code by creating a definite profit for authorization. With this mixture, you may add permissions for an API useful resource to a job. Customers may be related to a number of consumer roles. Every consumer function defines a set of permissions (GET, PUT, DELETE) on RBAC sources (outlined by URI paths). Within the subsequent part, let’s learn to obtain RBAC utilizing these two.

How you can Implement RBAC With OPA and Apache APISIX
In Apache APISIX, you may configure routes and plugins to outline the habits of your API. You should use the APISIX opa plugin to implement RBAC insurance policies by forwarding requests to OPA for decision-making. Then OPA makes an authorization determination primarily based on customers’ roles and permissions in real-time.
Assume that we’ve got Conference API the place you may retrieve/edit occasion periods, matters, and speaker data. A speaker can solely learn their very own periods and matters whereas the admin can add/edit extra periods and matters. Or attendees can depart their suggestions in regards to the speaker’s session through a POST request to /speaker/speakerId/session/suggestions
and the speaker can solely see by requesting the GET methodology of the identical URI. The under diagram illustrates the entire state of affairs:

- API shopper requests a route on the API Gateway with its credential resembling a JWT token within the authorization header.
- API Gateway sends shopper information with a JWT header to the OPA engine.
- OPA evaluates if the buyer has a proper to entry the useful resource through the use of insurance policies (roles and permissions) we specify within the .rego file.
- If the OPA determination is allowed, then the request shall be forwarded to the upstream Convention service.
Subsequent, we set up, configure APISIX, and outline insurance policies in OPA.
Stipulations
- Docker is used to putting in the containerized etcd and APISIX.
- curl is used to ship requests to APISIX Admin API. You may as well use instruments resembling Postman to work together with the API.
Step 1: Set up Apache APISIX
APISIX might be simply put in and began with the next quickstart script:
curl -sL https://run.api7.ai/apisix/quickstart | sh
Step 2: Configure the Backend Service (Upstream)
To route requests to the backend service for the Convention API, you’ll must configure it by including an upstream server in Apache APISIX through the Admin API.
curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -X PUT -d '
"identify":"Conferences API upstream",
"desc":"Register Conferences API because the upstream",
"sort":"roundrobin",
"scheme":"https",
"nodes":
"conferenceapi.azurewebsites.internet:443":1
'
Step 3: Create an API Shopper
Subsequent, we create a shopper (a brand new speaker) with the username jack
in Apache APISIX. It units up the jwt-auth plugin for the buyer with the required key and secret. This may permit the buyer to authenticate utilizing a JSON Web Token (JWT).
curl http://127.0.0.1:9180/apisix/admin/customers -X PUT -d '
"username": "jack",
"plugins":
"jwt-auth":
"key": "user-key",
"secret": "my-secret-key"
'
Step 4: Create a Public Endpoint to Generate a JWT Token
You additionally must arrange a brand new Route that generates and indicators the token utilizing the public-api plugin. On this state of affairs, API Gateway acts as an id supplier server to create and confirm the token with our shopper jack’s key. The id supplier might be additionally another third-party companies resembling Google, Okta, Keycloak, and Ory Hydra.
curl http://127.0.0.1:9180/apisix/admin/routes/jas -X PUT -d '
"uri": "/apisix/plugin/jwt/signal",
"plugins":
"public-api":
'
Step 5: Declare a New JWT Token for the API Shopper
Now we will get a brand new token for our speaker Jack from the API Gateway utilizing the general public endpoint we created. The next curl command generates a brand new token with Jack’s credentials and assigns function, and permission within the payload.
curl -G --data-urlencode 'payload="function":"speaker","permission":"learn"' http://127.0.0.1:9080/apisix/plugin/jwt/signal?key=user-key -i
After you run the above command, you’ll obtain a token as a response. Save this token someplace — later we’re going to use this token to entry our new API Gateway endpoint.
Step 6: Create a New Plugin Config
This step includes configuring APISIX’s 3 plugins: proxy-rewrite, jwt-auth, and opa plugins.
curl "http://127.0.0.1:9180/apisix/admin/plugin_configs/1" -X PUT -d '
"plugins":
"jwt-auth":
,
"proxy-rewrite":
"host":"conferenceapi.azurewebsites.internet"
'
- The
proxy-rewrite
plugin is configured to proxy requests to theconferenceapi.azurewebsites.internet
host. - OPA authentication plugin is configured to make use of the OPA coverage engine working at http://localhost:8181/v1/data/rbacExample. Additionally, APISIX sends all consumer-related data to OPA. We are going to add this coverage .
rego
file within the Opa configuration part.
Step 7: Create a Route for Convention Periods
The ultimate step is to create a brand new route for Conferences API speaker periods:
curl "http://127.0.0.1:9180/apisix/admin/routes/1" -X PUT -d '
"identify":"Conferences API speaker periods route",
"desc":"Create a brand new route in APISIX for the Conferences API speaker periods",
"strategies": ["GET", "POST"],
"uris": ["/speaker/*/topics","/speaker/*/sessions"],
"upstream_id":"1",
"plugin_config_id":1
'
The payload incorporates details about the route, resembling its identify, description, strategies, URIs, upstream ID, and plugin configuration ID. On this case, the route is configured to deal with GET and POST requests for 2 completely different URIs, /speaker/matters
and /speaker/periods
. The “upstream_id” discipline specifies the ID of the upstream service that may deal with incoming requests for this route, whereas the “plugin_config_id” discipline specifies the ID of the plugin configuration for use for this route.
Step 8: Check the Setup With out OPA
To this point, we’ve got arrange all the mandatory configurations for APISIX to direct incoming requests to Convention API endpoints, solely permitting approved API customers. Now, every time an API shopper desires to entry an endpoint, they have to present a JWT token to retrieve information from the Convention backend service. You’ll be able to confirm this by hitting the endpoint and the area deal with we’re requesting now’s our customized API Gateway however not an precise Convention service:
curl -i http://127.0.0.1:9080/speaker/1/matters -H 'Authorization: API_CONSUMER_TOKEN'
Step 9: Run OPA Service
The opposite two steps are we run the OPA service utilizing Docker and add our coverage definition utilizing its API which can be utilized to guage authorization insurance policies for incoming requests.
docker run -d --network=apisix-quickstart-net --name opa -p 8181:8181 openpolicyagent/opa:newest run -s
This Docker command runs a container of the OPA picture with the most recent model. It creates a brand new container on the prevailing APISIX community apisix-quickstart-net
with the identify opa
and exposes port 8181
. So, APISIX can ship coverage test requests to OPA straight utilizing the deal with [http://opa:8181](http://opa:8181)
Word that OPA and APISIX ought to run in the identical docker community.
Step 10: Outline and Register the Coverage
The second step on the OPA aspect is it’s essential to outline the insurance policies that shall be used to regulate entry to API sources. These insurance policies ought to outline the attributes required for entry (which customers have which roles) and the permission (which roles have which permissions) which are allowed or denied primarily based on these attributes. For instance, within the under configuration, we’re saying to OPA, test the user_roles
desk to seek out the function for jack
. This data is distributed by APISIX inside enter.shopper.username
. Additionally, we’re verifying the buyer’s permission by studying the JWT payload and extracting token.payload.permission
from there. The feedback describe the steps clearly.
curl -X PUT '127.0.0.1:8181/v1/insurance policies/rbacExample' -H 'Content material-Kind: textual content/plain' -d 'bundle rbacExample # Assigning consumer rolesuser_roles := "jack": ["speaker"], "bobur":["admin"] # Function permission assignments role_permissions := "speaker": ["permission": "read"], "admin": ["permission": "read", "permission": "write"] # Helper JWT Capabilities bearer_token := t t := enter.request.headers.authorization # Decode the authorization token to get a job and permission token = "payload": payload [_, payload, _] := io.jwt.decode(bearer_token) # Logic that implements RBAC default permit = falsepermit # Lookup the record of roles for the consumer roles := user_roles[input.consumer.username] # For every function in that record r := roles[_] # Lookup the permissions record for function r permissions := role_permissions[r] # For every permission p := permissions[_] # Test if the permission granted to r matches the customers request p == "permission": token.payload.permission '
Step 11: Replace the Present Plugin Config With the OPA Plugin
As soon as we outlined insurance policies on the OPA service, we have to replace the prevailing plugin config for the route to make use of the OPA plugin. We specify within the coverage
attribute of the OPA plugin.
curl "http://127.0.0.1:9180/apisix/admin/plugin_configs/1" -X PATCH -d '
"plugins":
"opa":
"host":"http://opa:8181",
"coverage":"rbacExample",
"with_consumer":true
'
Step 12: Check the Setup With OPA
Now we will check all setups we did with OPA insurance policies. In case you attempt to run the identical curl command to entry the API Gateway endpoint, it first checks the JWT token because the authentication course of and sends shopper and JWT token information to OPA to confirm the function and permission because the authorization course of. Any request with no JWT token in place or allowed roles shall be denied.
curl -i http://127.0.0.1:9080/speaker/1/matters -H 'Authorization: API_CONSUMER_TOKEN'
Conclusion
On this article, we realized methods to implement RBAC with OPA and Apache APISIX. We outlined a easy customized coverage logic to permit/disallow API useful resource entry primarily based on our API shopper’s function and permissions. Additionally, this tutorial demonstrated how we will extract API consumer-related data within the coverage file from the JWT token payload or shopper object despatched by APISIX.