The Client Credentials Flow is a foundational grant type in OAuth 2.0, designed for machine-to-machine (M2M) communication scenarios where no end-user is involved. This flow lets you securely backend services, daemons, or microservices to authenticate themselves and access protected APIs without user interaction.


Visual Overview:

sequenceDiagram
    participant User
    participant App as Client App
    participant AuthServer as Authorization Server
    participant Resource as Resource Server

    User->>App: 1. Click Login
    App->>AuthServer: 2. Authorization Request
    AuthServer->>User: 3. Login Page
    User->>AuthServer: 4. Authenticate
    AuthServer->>App: 5. Authorization Code
    App->>AuthServer: 6. Exchange Code for Token
    AuthServer->>App: 7. Access Token + Refresh Token
    App->>Resource: 8. API Request with Token
    Resource->>App: 9. Protected Resource

๐Ÿ” When Should You Use the Client Credentials Flow?

Use this flow when:

  • A backend service needs to call another internal API
  • A scheduled job or daemon interacts with protected endpoints
  • Microservices need to exchange data without involving users
  • You’re building automated scripts or monitoring tools that access APIs

๐Ÿ” How the Flow Works (Step-by-Step)

Hereโ€™s how the Client Credentials Flow operates:


+------------+                                      +------------------+
\|           | --(1) Authenticate & Request Token ->|                  |
\|  Client   |                                      | Authorization    |
\| (Backend) |<---------------- Access Token -------|    Server        |
+------------+                                      +------------------+
  1. The client authenticates using its client_id and client_secret.
  2. It makes a POST request to the token endpoint with grant_type=client_credentials.
  3. The authorization server returns an access token.
  4. The client uses this token to access protected resources.

๐Ÿงช Sample Token Request (cURL)

curl -X POST https://auth.example.com/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=abc123&client_secret=secret456"

Successful response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read write"
}

๐Ÿš€ Real-World Use Case Example (Java)

Using Spring Securityโ€™s OAuth2 client:

WebClient client = WebClient.builder()
  .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
  .build();

String token = client.post()
  .uri("https://auth.example.com/oauth2/token")
  .body(BodyInserters.fromFormData("grant_type", "client_credentials")
      .with("client_id", "abc123")
      .with("client_secret", "secret456"))
  .retrieve()
  .bodyToMono(TokenResponse.class)
  .block()
  .getAccessToken();

๐Ÿ› ๏ธ Common Errors and How to Fix Them

HTTP Code Meaning Fix Recommendation
401 Invalid client credentials Check client ID/secret or encoding
403 Insufficient scope or no consent Verify scopes assigned to the client
400 Invalid grant Ensure grant_type=client_credentials

๐Ÿงฑ Best Practices for Secure Use

  • ๐Ÿ” Use Client Assertions (JWT) instead of static secrets when possible

  • ๐Ÿ•‘ Rotate credentials regularly and avoid hardcoding secrets

  • ๐Ÿ“œ Limit scopes for each client to follow least privilege principle

  • ๐Ÿ“ก Use TLS (HTTPS) for all communication with the token endpoint



Need more real-world identity solutions? Explore the OAuth 2.0 & OpenID Connect Deep Cluster for more tutorials like this.