Client Credentials Flow

Client Credentials Flow

Using the Client Credentials Flow

OAuth 2.0 has a flow called client credentials, that comes in handy when there are requests to your APIs that are not involving a user. Using the Client Credentials flow, it's possible to let servers communicate with your API without modifying the APIs themselves.


This tutorial builds on the configuration setup described in the "First Configuration" and the "Configure an Authenticator" steps under the menu "Getting Started". If you have not gone through those steps yet, you can visit those guides here:

You may run this tutorial on a custom setup also, but keep in mind that names and URLs may be different, as well as the capabilities configured in the profiles.


Token Endpoint

Client Credentials Flow

  1. The Client makes a POST request to the OAuth Server
  2. The OAuth Server issues the Access Token immediately and responds to the client

To learn more about the client parameters of the Client Credentials flow see OAuth Client Credentials Flow.

Setup in Curity

Visit the Profiles screen and click the Token Service. On the right select Clients and click New.

New Client

Give the client an ID (eg. server for system client).

New Client


Scroll down to the Capabilities section and click Add capabilities.


Select the Client Credentials Flow capability and click Next.


Client Authentication

For client authentication select secret and enter a secret. Make sure to remember it since it cannot be retrieved later again (but can be reset).



Set a Scope (Optional)

Set Scope

It's not required for a client to have a scope, but often useful. To set a new scope on the client and to create the scope at the same time, scroll to OAuth/OpenID Settings and click New Scope. Enter the new scope value below and click Save. The scope shows up in the list below as enabled on the client.


Make sure to remember to commit the changes in the Changes -> Commit menu.

Using the Client

To implement or use the client the following steps are needed.

  1. Provide the new client with the client_id (server) and the secret
  2. Before it can call the API, get a new access token
  3. Put the access token in the Authorization header and call the API

Retrieve an access token

curl -k -X POST \
  https://localhost:8443/oauth/v2/oauth-token \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&client_id=server&client_secret=Secr3t!'

Curl against localhosts

When using Curl against localhost and HTTPS you will need to use -k to disable certificate verification.

With scope

If you added a scope you can append that to the form parameters

curl -k -X POST \
  https://localhost:8443/oauth/v2/oauth-token \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&client_id=server&client_secret=Secr3t!&scope=YOUR_SCOPE'

The request is always of content type application/x-www-form-urlencoded. The following parameters should be sent:

  • client_id=server
  • client_secret=Secr3t!
  • grant_type=client_credentials (constant)
  • scope=read (optional, a space separated list of the scopes configured on the client)

This returns a json response with the access token:

    "access_token": "0470b16b-7bf8-4fa3-9ae1-6a10e0f0b699",
    "scope": "read", //only if scope=read was requested
    "token_type": "bearer",
    "expires_in": 299

Call an API with the access token

The token lives for 299 seconds according to the response from the server. This is configurable on the client settings and in the profile. When the token expires the API should respond with a 401 telling the client to get a new token.

To call the API, the token should be added to the request in the Authorization header on the form:

Authorization: Bearer 0470b16b-7bf8-4fa3-9ae1-6a10e0f0b699

I.e. the keyword Bearer a single space and then the token.

The call looks as follows:

curl -X GET \ \
  -H 'authorization: Bearer 0470b16b-7bf8-4fa3-9ae1-6a10e0f0b699'


The Client Credentials call is useful when there is no user involved in the call. It is also very handy during development since it provides a simple way for a client to retrieve an access token to use when calling APIs.