OAuth 2.0 framework is widely used for server to server communication involving API calls. Most of the other grant types available in OAuth 2 framework involves a user (resource owner) who provides delegated access to client application. Client credentials grant type is different from other grant types since the client application itself acts as a resource owner and authenticates with the authorization server using client credentials that are obtained during client registration.
OAuth 2 – Client Credentials Flow
Client credentials flow is useful in the scenario where a client application needs to make an API call to the backend server and there is no user session involved. This is a common pattern used in microservices architecture for a federated identity model which nicely decouples authentication domain from the business domain. The client credentials are never shared with other backend services which helps in improving the overall security posture. This flow is also used for establishing secure connectivity with SaaS providers or external vendor APIs that provide OAuth 2 integration for identity and access management.
In the subsequent sections, we’ll look at how OAuth 2 client credentials flow can be used in a scenario where an API needs to integrate with an external service provider to complete a business process. This is a very common security pattern in payments domain due to interconnectivity required with external partners for payment processing.
Client Credentials Flow – External API Connectivity Use Case
An external API provider can implement an authorization server which also support OIDC protocol along with support for client credentials flow. Client credentials flow doesn’t have a user that needs to be authenticated, however we still need to have the client application authenticate itself to authorization server. OpenID specification defines few different client authentication methods that can be implemented by the authorization server. JWT based client credentials (JWS) are quite commonly used which can be either based on a shared secret key (client_secret_jwt) or asymmetric keys (private_key_jwt).
The above diagram provides an overview of how client credentials flow can be used to access protected resources provided by an external API provider. The above example is based on the JWT profile for OAuth 2.0 client credentials and authorization grants. RFC7523 defines how JWT can be used to request an access token when the client has established trust with the authorization server. This trust is established through a client registration process managed through the authorization server.
- Step 1: Client Administrator registers the client application with the authorization server. Successful registration process will result in a generation of a client id. A secret is also generated if using client_secret_jwt for JWT based client authentication. The secret can be used as a shared key to create HS256 token (HMAC SHA algorithm). When using private_key_jwt, the client administrator will be required to generate an asymmetric key pair and register the public key with the authorization server.
- Step 2: Client application generates a JWT token (JWS) either using the secret received from the authorization server or it can use the private key it generated during the registration process. This will depend on the client authentication method agreed between the API provider and the client. Request is made to the authorization server with client_credentials grant type along with the JWS authentication token in order get JWS access token.
- Step 3: JWS access token is received by the client application if authorization server is able to successfully validate JWS token in step 2. The access token returned by authorization server is known as bearer access token which can also be generated as a JWT signed by the authorization server (JWS).
- Step 4: The client application can access protected resources by using the bearer access token in subsequent API calls.