Set up a Client Credentials Grant using the Management API

If you do not want to use the Auth0 Dashboard to enable API Authorization, you can achieve the same results using the Auth0 Management API.

You will need the following:

  • A Management APIv2 token. For details on how to get one refer to The Auth0 Management APIv2 Token.
  • The Client information (Client_Id and Client_Secret) for the Non Interactive Client that should already be created and visible in your Auth0 dashboard.

1. Create your Resource Server

Let's start by creating the Resource Server. This is the entity that represents the API that you want to issue access tokens for, identified by a friendly name and a URN identifier.

The following restrictions apply to the identifier:

  • It must be a valid URN.
  • It cannot be modified after creation.
  • It must be unique throughout your tenant.

We recommend using your public API endpoint as an identifier.

To create a Resource Server send a POST request to the /resource-servers endpoint of the Management APIv2.

The following example uses "My Sample API" as the name and "https://my-api-uri" as the identifier.


curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers' \
  --header 'content-type: application/json' \
  --data '{"name":"My Sample API","identifier": "https://my-api-urn","signing_alg": "RS256","scopes": [{ "value": "sample-scope", "description": "Description for Sample Scope"}]}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"name\":\"My Sample API\",\"identifier\": \"https://my-api-urn\",\"signing_alg\": \"RS256\",\"scopes\": [{ \"value\": \"sample-scope\", \"description\": \"Description for Sample Scope\"}]}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

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

func main() {

	url := "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers"

	payload := strings.NewReader("{\"name\":\"My Sample API\",\"identifier\": \"https://my-api-urn\",\"signing_alg\": \"RS256\",\"scopes\": [{ \"value\": \"sample-scope\", \"description\": \"Description for Sample Scope\"}]}")

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

	req.Header.Add("content-type", "application/json")

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

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

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

}
HttpResponse<String> response = Unirest.post("https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers")
  .header("content-type", "application/json")
  .body("{\"name\":\"My Sample API\",\"identifier\": \"https://my-api-urn\",\"signing_alg\": \"RS256\",\"scopes\": [{ \"value\": \"sample-scope\", \"description\": \"Description for Sample Scope\"}]}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers",
  "method": "POST",
  "headers": {
    "content-type": "application/json"
  },
  "processData": false,
  "data": "{\"name\":\"My Sample API\",\"identifier\": \"https://my-api-urn\",\"signing_alg\": \"RS256\",\"scopes\": [{ \"value\": \"sample-scope\", \"description\": \"Description for Sample Scope\"}]}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers',
  headers: { 'content-type': 'application/json' },
  body: 
   { name: 'My Sample API',
     identifier: 'https://my-api-urn',
     signing_alg: 'RS256',
     scopes: 
      [ { value: 'sample-scope',
          description: 'Description for Sample Scope' } ] },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"name": @"My Sample API",
                              @"identifier": @"https://my-api-urn",
                              @"signing_alg": @"RS256",
                              @"scopes": @[ @{ @"value": @"sample-scope", @"description": @"Description for Sample Scope" } ] };

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

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[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];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"name\":\"My Sample API\",\"identifier\": \"https://my-api-urn\",\"signing_alg\": \"RS256\",\"scopes\": [{ \"value\": \"sample-scope\", \"description\": \"Description for Sample Scope\"}]}",
  CURLOPT_HTTPHEADER => array(
    "content-type: application/json"
  ),
));

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

curl_close($curl);

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

conn = http.client.HTTPSConnection("")

payload = "{\"name\":\"My Sample API\",\"identifier\": \"https://my-api-urn\",\"signing_alg\": \"RS256\",\"scopes\": [{ \"value\": \"sample-scope\", \"description\": \"Description for Sample Scope\"}]}"

headers = { 'content-type': "application/json" }

conn.request("POST", "/YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers", payload, headers)

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

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers")

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

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request.body = "{\"name\":\"My Sample API\",\"identifier\": \"https://my-api-urn\",\"signing_alg\": \"RS256\",\"scopes\": [{ \"value\": \"sample-scope\", \"description\": \"Description for Sample Scope\"}]}"

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

let headers = ["content-type": "application/json"]
let parameters = [
  "name": "My Sample API",
  "identifier": "https://my-api-urn",
  "signing_alg": "RS256",
  "scopes": [
    [
      "value": "sample-scope",
      "description": "Description for Sample Scope"
    ]
  ]
]

let postData = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: nil)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/resource-servers")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

NOTE: You can include multiple scopes. This array represents the universe of scopes your API will support. You can modify this later by issuing a PATCH operation.

Sample response:

{
    "id": "56f0131ffdf1c311694f4cc7",
    "name": "My Sample API",
    "identifier": "https://my-api-urn",
    "scopes": [
        {
            "value": "sample-scope",
            "description": "Description for Sample Scope"
        }
    ],
    "signing_alg": "RS256",
    "signing_secret": "FF1prn9UxZotnolsDVwEJhqqyRmwdSu5",
    "token_lifetime": 86400
}

Note the following:

  • The identifier value (https://my-api-urn) will be used from now on as the audience for any OAuth 2.0 grant, that wants to access this API.
  • The algorithm that your API will use to sign tokens will be the RS256 (signing_alg).
  • The secret used to sign the tokens will be FF1prn9UxZotnolsDVwEJhqqyRmwdSu5 (signing_secret).
  • The generated tokens will expire after 86400 seconds (token_lifetime).

2. Authorize the Client

Now that the API and the Client are defined in Auth0, you can create a trust relationship between them. To do so authorize the Client to access the API, while defining the scopes that should be given to the Client (meaning the actions the Client will be able to perform on the API).

To authorize your Client send a POST request to the /client-grants endpoint of the Management APIv2.

The following example authorizes the Client with Id YOUR_CLIENT_ID, to access the API with Identifier https://my-api-urn, while granting the scope sample-scope.


curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants' \
  --header 'content-type: application/json' \
  --data '{"client_id": "YOUR_CLIENT_ID","audience": "https://my-api-urn","scope":["sample-scope"]}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"client_id\": \"YOUR_CLIENT_ID\",\"audience\": \"https://my-api-urn\",\"scope\":[\"sample-scope\"]}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

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

func main() {

	url := "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants"

	payload := strings.NewReader("{\"client_id\": \"YOUR_CLIENT_ID\",\"audience\": \"https://my-api-urn\",\"scope\":[\"sample-scope\"]}")

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

	req.Header.Add("content-type", "application/json")

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

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

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

}
HttpResponse<String> response = Unirest.post("https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants")
  .header("content-type", "application/json")
  .body("{\"client_id\": \"YOUR_CLIENT_ID\",\"audience\": \"https://my-api-urn\",\"scope\":[\"sample-scope\"]}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants",
  "method": "POST",
  "headers": {
    "content-type": "application/json"
  },
  "processData": false,
  "data": "{\"client_id\": \"YOUR_CLIENT_ID\",\"audience\": \"https://my-api-urn\",\"scope\":[\"sample-scope\"]}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants',
  headers: { 'content-type': 'application/json' },
  body: 
   { client_id: 'YOUR_CLIENT_ID',
     audience: 'https://my-api-urn',
     scope: [ 'sample-scope' ] },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"client_id": @"YOUR_CLIENT_ID",
                              @"audience": @"https://my-api-urn",
                              @"scope": @[ @"sample-scope" ] };

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

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[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];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"client_id\": \"YOUR_CLIENT_ID\",\"audience\": \"https://my-api-urn\",\"scope\":[\"sample-scope\"]}",
  CURLOPT_HTTPHEADER => array(
    "content-type: application/json"
  ),
));

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

curl_close($curl);

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

conn = http.client.HTTPSConnection("")

payload = "{\"client_id\": \"YOUR_CLIENT_ID\",\"audience\": \"https://my-api-urn\",\"scope\":[\"sample-scope\"]}"

headers = { 'content-type': "application/json" }

conn.request("POST", "/YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants", payload, headers)

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

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants")

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

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request.body = "{\"client_id\": \"YOUR_CLIENT_ID\",\"audience\": \"https://my-api-urn\",\"scope\":[\"sample-scope\"]}"

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

let headers = ["content-type": "application/json"]
let parameters = [
  "client_id": "YOUR_CLIENT_ID",
  "audience": "https://my-api-urn",
  "scope": ["sample-scope"]
]

let postData = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: nil)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN.auth0.com/api/v2/client-grants")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

Sample response:

{
    "id": "cgr_JGa6ZckLjnt60rWe",
    "client_id": "YOUR_CLIENT_ID",
    "audience": "https://test-api",
    "scope": [
        "sample-scope"
    ]
}

3. That's it!

Now that all the elements are in place, you can request access tokens for your API from Auth0.

For details on how to do so, refer to Execute a Client Credentials Grant.