An important part of managing APIs across their lifecycle is fine‑grained control over API access and traffic routing. Access tokens have emerged as the de facto standard for managing access to APIs. One of the advantages of authentication schemes based on JSON Web Tokens (JWTs) is being able to leverage the claims in the JWT to implement that fine level of access control. Permissions can be encoded as custom claims, which API owners can use to control access to their APIs. Once the API proxy has validated the JWT, it has access to all the fields in the token as variables and can base access decisions on them.
In a previous post, we discussed how API Connectivity Manager can help operators and developers work better together. The teams from different lines of business that own and operate APIs need full control as they develop and enhance the experience of their APIs and services.
API Connectivity Manager provides policies that enable API owners to configure service‑level settings like API authentication, authorization, and additional security requirements. In this post we show how API owners can use the Access Control Routing policy to enforce fine‑grained control for specific routes and further fine‑tune it to apply per HTTP method and per route based on specific claims in the token.
You must have a trial or paid subscription of F5 NGINX Management Suite, which includes Instance Manager and API Connectivity Manager along with NGINX Plus as an API gateway and NGINX App Protect to secure your APIs. To get started, request a free, 30-day trial of NGINX Management Suite.
For instructions on how to install NGINX Management Suite and API Connectivity Manager, see the Installation Guide.
Let’s say we have published a warehouse API proxy with several endpoints such as inventory, orders, and so on. Now we want to introduce a new service called pricing, but make it accessible only to a few clients who have signed up for a beta trial. Such clients are identified by a claim called betatester
. In this sample access token, that claim is true
for the user identified in the sub
claim, user1@abc.com
.
Header
{
"kid": "123WoAbc4xxxX-o8LiartvSA9zzzzzLIiAbcdzYx",
"alg": "RS256"
}
Payload
{
"ver": 1,
"jti": "AT.xxxxxxxxxxxx",
"iss": "https://oauthserver/oauth2/",
"aud": "inventoryAPI",
"iat": 1670290877,
"exp": 1670294477,
"cid": "AcvfDzzzzzzzzz",
"uid": "yyyyyyyWPXulqE4x6",
"scp": [
"apigw"
],
"auth_time": 1670286138,
"sub": "user1@abc.com",
"betatester": true,
"domain": "abc"
}
For user2@abc.com
, who was not chosen for the beta program, the betatester
claim is set to
false:
"sub": "user2@abc.com","betatester": false,
Now we configure the Access Control Routing policy (access-control-routing) to grant access to the pricing service for users whose JWT contains the betatester
claim with value true
.
For brevity, we show only the policy payload. This policy works only with token‑based policies in API Connectivity Manager, such as JWT Assertion and OAuth2 Introspection.
"policies": { "access-control-routing": [
{
"action": {
"conditions": [
{
"allowAccess": {
"uri": "/pricing"
},
"when": [
{
"key": "token.betatester",
"matchOneOf": {
"values": [
"true"
]
}
}
]
}
],
"returnCode": 403
}
}
]
}
Once we apply the policy, the API proxy validates the claims in the JWT for authenticated users, performing fine‑grained access control to route requests from user1@abc.com
requests and reject requests from user2@abc.com
.
We can further fine‑tune the access-control-routing policy to control which users can use specific HTTP methods. In this example, the API proxy allows only admins (users whose token includes the value Admin
) to use the DELETE
method.
"policies":{ "access-control-routing":[
"action":{
"conditions":[
{
"when":[
{
"key":"token.{claims}",
"matchOneOf":{
"values":[
"Admin"
]
}
}
],
"allowAccess":{
"uri":"/v1/customer",
"httpMethods":[
"DELETE"
]
},
"routeTo" : {
"targetBackendLabel" : ""
}
}
]
}
]
}
Yet another use of the access-control-routing policy is to make routing decisions based on header values in incoming requests. API owners can configure rules or conditions which specify the values in the header that must be matched for the request to be routed. Requests are forwarded if they contain the header and dropped if they do not.
In this example, a request is routed to the /seasons endpoint only when the version
request header has value v1
. The returnCode
value specifies the error code to return when version
is not v1
– in this case, it’s 403
(Forbidden)
.
"access-control-routing": [ {
"action": {
"conditions": [
{
"allowAccess": {
"uri": "/seasons"
},
"when": [
{
"key": "header.version",
"matchOneOf": {
"values": [
"v1"
]
}
}
]
}
],
"returnCode": 403
}
}
]
In this sample curl
request, we send a request to the seasons service with the version
header set to v2
:
curl -H "version: v2" http://example.com/seasons
Because the value of the version
header is not v1
as required by the policy, the service returns status code 403
.
You can include multiple rules in an access-control-routing policy to control routing based on one, two, or all three of the criteria discussed in this post: JWT claims, valid methods, and request header values. A request must match the conditions in all rules to be routed; otherwise, it is blocked.
API Connectivity Manager enables API owners to control and enhance the experience of their APIs and services with API‑level policies that apply fine‑grained access control and make dynamic routing decisions.
To get started with API Connectivity Manager, request a free, 30-day trial of NGINX Management Suite.
"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."