Mastering Access Token Acquisition: Client Credentials Flow

This blog post is part of a series. In this one we’ll highlight the client credentials flow. Check out the other posts about the other authorization flows:

Another significant authentication flow within the realm of OAuth 2.0 is the client credentials flow. In contrast to the authorization code flow, the client credentials flow operates without requiring any user interaction.

In the client credentials flow, the process of obtaining an access token is remarkably streamlined. With just a single POST request to the designated token endpoint, and the inclusion of your application’s client ID and client secret, you can acquire the access token. This efficiency is particularly advantageous in scenarios where the application is interacting with APIs or services on behalf of itself, rather than representing a user.

One of the core benefits of the client credentials flow is its simplicity. The minimal requirements of a client ID and client secret contribute to an expedited authorization process, which is especially valuable when rapid token acquisition is essential for maintaining application functionality.

However, it’s important to note that this efficiency comes with trade-offs. One significant distinction of the client credentials flow is that it does not yield a refresh token. Refresh tokens, as obtained through other flows, allow for prolonged sessions without the need for repeated user authentication. In the client credentials flow, the absence of refresh tokens means that when the access token expires, the application must reauthenticate and obtain a new access token using the client credentials (client ID and client secret.

You can do a POST request to the ‘https://login.microsoft.com/[YOUR_TENANT_ID]/oauth2/v2.0/token’ with the following parameters in the body of the request:

  • client_id: the id of your client, can be found in the home screen of your app registration.
  • client_secret: The client secret of your client id. This is something you can generate in the Certificates & secrets section of your app registration in Azure.
  • grant_type: client_credentials
  • scope: the scope must be the resource identifier of the application against which you want to use your access token, added with .default. For Microsoft Graph this would be for example ‘https://graph.microsoft.com/.default’.

If everything goes right, you get a json back which contains your access token:

As a reader commented as a valid point on a previous blogpost, security must always taken into account when using this kind of authorization flows.

Client secrets are pivotal in OAuth 2.0 for client authentication, but their security varies between server-side and client-side contexts.

In server-side usage, client secrets are better protected as they can be stored securely in for example a configuration file or with Azure Key Vault. However, in the client-side scenario, exposing secrets in code increases vulnerability. To enhance security, it’s recommended to limit client-side exposure, employing token-based flows where possible or opting for server-side handling of sensitive operations.