> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Learn how to enable role-based access control (RBAC) for an API using the Auth0 Dashboard or the Management API.

# Enable Role-Based Access Control for APIs

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

You can enable [role-based access control (RBAC)](/docs/manage-users/access-control/rbac) using the <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> or the <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=Management+API">Management API</Tooltip>. This enables the API Authorization Core feature set.

When RBAC is enabled, the `scope` claim of the <Tooltip tip="Access Token: Authorization credential, in the form of an opaque string or JWT, used to access an API." cta="View Glossary" href="/docs/glossary?term=access+token">access token</Tooltip> 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.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  If you configure any [Actions](/docs/customize/actions) that modify access token scopes, they will override the scopes set by RBAC.
</Callout>

## Dashboard

1. Go to [Dashboard > Applications > APIs](https://manage.auth0.com/#/apis) and click the name of the API to view.

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/RDh-UBFSkTEu_d9f/docs/images/cdy7uua7fh8z/3rhmhghYZDSi6YWHRA5yMQ/c71340259481b0b6787d5f3887cfda0f/dashboard-apis-list.png?fit=max&auto=format&n=RDh-UBFSkTEu_d9f&q=85&s=edb5e6192b269761eeeba8135ecd1ff0" alt="Dashboard Applications APIs List" width="1478" height="562" data-path="docs/images/cdy7uua7fh8z/3rhmhghYZDSi6YWHRA5yMQ/c71340259481b0b6787d5f3887cfda0f/dashboard-apis-list.png" />
   </Frame>
2. Scroll to **RBAC Settings** and enable the **Enable RBAC** toggle.

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/tcenw4jcNpftRqWN/docs/images/cdy7uua7fh8z/65tKb6aj0ktc2qXLUVlV3e/641adef615d6af9e5a3b588ff397af87/dashboard-apis-edit_view-settings_rbac-settings.png?fit=max&auto=format&n=tcenw4jcNpftRqWN&q=85&s=73ff19888137d276bf9544c1284f2c5a" alt="Auth0 Dashboard API Settings RBAC toggle" width="1200" height="408" data-path="docs/images/cdy7uua7fh8z/65tKb6aj0ktc2qXLUVlV3e/641adef615d6af9e5a3b588ff397af87/dashboard-apis-edit_view-settings_rbac-settings.png" />
   </Frame>
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](/docs/secure/tokens/access-tokens/access-token-profiles) 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](#token-dialect-options).

## Management API

To enable RBAC using the Management API, make a PATCH request to the [Update a resource server endpoint](https://auth0.com/docs/api/management/v2/resource-servers/patch-resource-servers-by-id). In the PATCH request, set `enforce_policies` to `true`:

<AuthCodeGroup>
  ```bash cURL theme={null}
  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" }'
  ```

  ```csharp C# theme={null}
  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);
  ```

  ```go Go theme={null}
  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))

  }
  ```

  ```java Java theme={null}
  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();
  ```

  ```javascript Node.JS theme={null}
  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);
  });
  ```

  ```php PHP theme={null}
  $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;
  }
  ```

  ```python Python theme={null}
  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"))
  ```

  ```ruby Ruby theme={null}
  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
  ```
</AuthCodeGroup>

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](https://auth0.com/docs/api/management/v2/tokens) 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).          |

### 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)](/docs/secure/tokens/json-web-tokens). 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](/docs/secure/tokens/access-tokens/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)](https://datatracker.ietf.org/doc/html/rfc9068). 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](/docs/secure/tokens/access-tokens/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

* [Manage Role-Based Access Control Users](/docs/manage-users/access-control/configure-core-rbac/rbac-users)
* [Manage Role-Based Access Control Permissions](/docs/manage-users/access-control/configure-core-rbac/manage-permissions)
* [Sample Use Cases: Role-Based Access Control](/docs/manage-users/access-control/sample-use-cases-role-based-access-control)
