Enable Role-Based Access Control for APIs

You can enable role-based access control (RBAC) using the Auth0 Dashboard or the Management API. This enables the API Authorization Core feature set.

When RBAC is enabled, the scope claim of the access token includes an intersection of the requested permissions and the permissions assigned to the user, regardless of whether permissions are also included in the access token. When RBAC is disabled, an application can request any permission defined for the API, and the scope claim includes all requested permissions.

Dashboard

  1. Go to Dashboard > Applications > APIs and click the name of the API to view.

    Dashboard Applications APIs List

  2. Scroll to RBAC Settings and enable the Enable RBAC toggle.

    Auth0 Dashboard API Settings RBAC toggle

  3. To include all permissions assigned to the user in the permissions claim of the access token, enable the Add Permissions in the Access Token toggle, and click Save. Including permissions in the access token allows you to make minimal calls to retrieve permissions, but increases token size. Once you’ve enabled the Add Permissions in the Access Token toggle, Auth0 also updates your token dialect based on the access token profile you’ve set for the API:

    • If your token dialect is access_token, Auth0 updates it to access_token_authz, which is equivalent to the access_token profile with the permissions claim included.

    • If your token dialect is rfc9068_profile, Auth0 updates it to rfc9068_profile_authz, which is equivalent to the rfc9068_profile with the permissions claim included.

    To learn more about the available token dialects, read Token dialect options.

Management API

To enable RBAC using the Management API, make a PATCH request to the Update a resource server endpoint. In the PATCH request, set enforce_policies to true:


curl --request PATCH \
  --url 'https://{yourDomain}/api/v2/resource-servers/API_ID' \
  --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
  --header 'cache-control: no-cache' \
  --header 'content-type: application/json' \
  --data '{ "enforce_policies": "true", "token_dialect": "TOKEN_DIALECT" }'

Was this helpful?

/
var client = new RestClient("https://{yourDomain}/api/v2/resource-servers/API_ID");
var request = new RestRequest(Method.PATCH);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
request.AddHeader("cache-control", "no-cache");
request.AddParameter("application/json", "{ \"enforce_policies\": \"true\", \"token_dialect\": \"TOKEN_DIALECT\" }", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Was this helpful?

/
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://{yourDomain}/api/v2/resource-servers/API_ID"

	payload := strings.NewReader("{ \"enforce_policies\": \"true\", \"token_dialect\": \"TOKEN_DIALECT\" }")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("content-type", "application/json")
	req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
	req.Header.Add("cache-control", "no-cache")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Was this helpful?

/
HttpResponse<String> response = Unirest.patch("https://{yourDomain}/api/v2/resource-servers/API_ID")
  .header("content-type", "application/json")
  .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
  .header("cache-control", "no-cache")
  .body("{ \"enforce_policies\": \"true\", \"token_dialect\": \"TOKEN_DIALECT\" }")
  .asString();

Was this helpful?

/
var axios = require("axios").default;

var options = {
  method: 'PATCH',
  url: 'https://{yourDomain}/api/v2/resource-servers/API_ID',
  headers: {
    'content-type': 'application/json',
    authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
    'cache-control': 'no-cache'
  },
  data: {enforce_policies: 'true', token_dialect: 'TOKEN_DIALECT'}
};

axios.request(options).then(function (response) {
  console.log(response.data);
}).catch(function (error) {
  console.error(error);
});

Was this helpful?

/
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"content-type": @"application/json",
                           @"authorization": @"Bearer MGMT_API_ACCESS_TOKEN",
                           @"cache-control": @"no-cache" };
NSDictionary *parameters = @{ @"enforce_policies": @"true",
                              @"token_dialect": @"TOKEN_DIALECT" };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/api/v2/resource-servers/API_ID"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];

Was this helpful?

/
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://{yourDomain}/api/v2/resource-servers/API_ID",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PATCH",
  CURLOPT_POSTFIELDS => "{ \"enforce_policies\": \"true\", \"token_dialect\": \"TOKEN_DIALECT\" }",
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer MGMT_API_ACCESS_TOKEN",
    "cache-control: no-cache",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

Was this helpful?

/
import http.client

conn = http.client.HTTPSConnection("")

payload = "{ \"enforce_policies\": \"true\", \"token_dialect\": \"TOKEN_DIALECT\" }"

headers = {
    'content-type': "application/json",
    'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
    'cache-control': "no-cache"
    }

conn.request("PATCH", "/{yourDomain}/api/v2/resource-servers/API_ID", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))

Was this helpful?

/
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://{yourDomain}/api/v2/resource-servers/API_ID")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Patch.new(url)
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
request["cache-control"] = 'no-cache'
request.body = "{ \"enforce_policies\": \"true\", \"token_dialect\": \"TOKEN_DIALECT\" }"

response = http.request(request)
puts response.read_body

Was this helpful?

/
import Foundation

let headers = [
  "content-type": "application/json",
  "authorization": "Bearer MGMT_API_ACCESS_TOKEN",
  "cache-control": "no-cache"
]
let parameters = [
  "enforce_policies": "true",
  "token_dialect": "TOKEN_DIALECT"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/api/v2/resource-servers/API_ID")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Was this helpful?

/

Replace API_ID, MGMT_API_ACCESS_TOKEN, and TOKEN_DIALECT with their respective values, as shown in the following table:

Parameter Description
API_ID ID of the API for which you want to enable RBAC.
MGMT_API_ACCESS_TOKEN Access Token for the Management API with the scope update:resource_servers.
TOKEN_DIALECT Dialect of the access token for the specified API. To learn more, read Token dialect options.

Token dialect options

Auth0 supports the following token dialects:

Value Description
access_token The Auth0 default token profile generates an access token formatted as a JSON Web Token (JWT). In the scope claim of the access token, includes an intersection of the requested permissions and the permissions assigned to the user. No permissions claim is passed. To learn more, read Access Token Profiles.
access_token_authz The Auth0 default token profile (access_token) with the permissions claim. In the scope claim of the access token, includes an intersection of the requested permissions and the permissions assigned to the user. In the permissions claim of the access token, includes all permissions assigned to the user. Allows you to make minimal calls to retrieve permissions, but increases token size.
rfc9068_profile The RFC 9068 token profile generates an access token formatted as a JWT following the IETF JWT Profile for OAuth 2.0 Access Tokens (RFC 9068). In the scope claim of the access token, includes an intersection of the requested permissions and the permissions assigned to the user. No permissions claim is passed. To learn more, read Access Token Profiles.
rfc9068_profile_authz The RFC 9068 token profile (rfc9068_profile) with the permissions claim. In the scope claim of the access token, includes an intersection of the requested permissions and the permissions assigned to the user. In the permissions claim of the access token, includes all permissions assigned to the user. Allows you to make minimal calls to retrieve permissions, but increases token size.

Learn more