Client Credentials
Obtaining an access token for a privileged API client
Introduction
In this guide you will learn how an application can use a provided client id and client secret to obtain an OAuth Access Token using the client_credentials grant flow.
An API client uses the client_credentials grant flow when it needs to perform actions without delegated authority from an authenticated user.
The client_credentials grant flow is very simple. The client sends its client ID and client secret to the IBM Security Verify OAuth 2.0 token endpoint and an Access Token is returned.
Pre-requisites
Before an application can obtain an Access Token using the the client credentials grant flow, you must obtain a client id and client secret for your application. If you have administrator access to your Verify tenant, check out Create a privileged API Client. Otherwise, you'll need to ask an administrator to do this for you.
To use the curl examples in this guide you will need the curl
utility to call make HTTP calls to REST APIs. Curl is pre-installed on most Linux systems and on MacOS. However, if necessary, you can download curl here.
To use the curl+jq examples in this guide you will also need the jq
utility to parse JSON responses from REST API calls. You can download jq here.
Variables
The following variables are needed to run the flow described in this guide:
Variable | Example Value | Description |
---|---|---|
tenant_url | tenant.verify.ibm.com | The URL of your IBM Security Verify tenant. |
client_id | 12345678-1234-1234-1234-123456789012 | The Client ID generated by IBM Security Verify when the API client is created. |
client_secret | abcd1234 | The Client Secret generated by IBM Security Verify when the API client is created. |
If you're going to use these variables on the command line with curl, you should export them with these commands:
export tenant_url=tenant.verify.ibm.com
export client_id=12345678-1234-1234-1234-123456789012
export client_secret=abcd1234
Run the flow
The client credentials flow is a simple flow with one call to the OAuth Token endpoint.
The HTTP request has the following format:
POST /v1.0/endpoint/default/token HTTP/1.1
Host: {tenant_url}
Content-Type: application/x-www-form-urlencoded
Content-Length: xxx
grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}
The REST API response has the following format:
{
"access_token":"xxxxxxxxxxxxxxxxxxxxxxx",
"grant_id":"xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"token_type":"Bearer",
"expires_in":7200
}
The access token can be extracted from the access_token element of the response.
No refresh token is returned
No refresh token is returned when using the client_credentials grant type. When the Access Token expires, the client simply requests a new token by running the client_credentials flow again.
Using curl to make the request
You can make the token request with curl
:
curl -X POST https://${tenant_url}/v1.0/endpoint/default/token -d "client_id=${client_id}&client_secret=${client_secret}&grant_type=client_credentials"
The JSON response is returned to the console. You can copy the access token from here.
Use jq to parse the response
If you have the jq
utility, you can use this to parse the JSON response and extract the access_token value. This can then be directly populated into the access_token
environment variable for future use:
export access_token=`curl -X POST https://${tenant_url}/v1.0/endpoint/default/token -d "client_id=${client_id}&client_secret=${client_secret}&grant_type=client_credentials" | jq -r .access_token`
echo ${access_token}
Using JavaScript
You can run the client_credentials grant type flow using any language that supports making HTTP requests. Here is JavaScript code that will get an access token:
//Pre-requisites
//var axios = require('axios');
//var qs = require('qs');
//var tenant_url = "Tenant URL";
//var client_id = "Client ID";
//var client_secret = "Client Secret";
var data = {
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret
};
var request = {
method: 'post',
url: 'https://' + tenant_url + '/oidc/endpoint/default/token',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data : qs.stringify(data)
};
axios(request).then((response) => {
var tokenData = response.data;
var access_token = tokenData.access_token;
console.log(access_token);
//Next code here.
}).catch((error) => {
console.log(error);
});
The expires_in value is the number of seconds until the token expires but note that the time the token was generated is not recorded. It is a good idea to convert this time to an absolute expiry time when receiving a new token.
// Add absolute expiry time to the token data.
// Calculated from current time and expires_in
var date = new Date();
tokenData.expirytime = date.getTime() + (tokenData.expires_in * 1000);
Jon Harry, IBM Security
Updated about 1 year ago