diagram.mmd — sequence
OAuth2 Client Credentials Flow sequence diagram

The OAuth2 Client Credentials Flow is the grant type designed for machine-to-machine (M2M) communication — situations where there is no human user involved and a service must authenticate as itself to call another service's API.

Unlike the OAuth2 Authorization Code Flow, there is no browser redirect, no user login screen, and no consent prompt. The flow is entirely back-channel: the client service holds a client_id and client_secret (or a signed JWT assertion) and exchanges them directly for an access token.

The requesting service sends a POST to the authorization server's /token endpoint with grant_type=client_credentials, its credentials, and the scope of access required. The authorization server validates the credentials against its client registry, checks that the requested scopes are permitted for this client, and returns an access token — typically a short-lived JWT (15 minutes to 1 hour is common).

The service then attaches this access token as a Bearer header on outbound API calls to the resource server. The resource server validates the token's signature, expiry, and scope claims before processing the request. When the token expires, the service requests a new one; there is no refresh token in this flow because the client can always re-authenticate immediately using its credentials.

Token caching is critical for performance at scale: fetching a new token for every API call adds latency and load to the authorization server. A well-implemented client caches the token and proactively renews it shortly before expiry (typically at 80–90% of its lifetime).

The Client Credentials Flow is the backbone of microservice-to-microservice auth in platforms like Auth0, Okta, and Azure AD. For APIs that use simpler long-lived secrets rather than short-lived tokens, compare API Key Authentication. Token structure and validation are covered in JWT Authentication Flow.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

The OAuth2 Client Credentials Flow is a grant type designed for machine-to-machine communication. A service authenticates as itself — using a `client_id` and `client_secret` — and receives a short-lived access token to call another service's API. There is no user, no browser redirect, and no consent screen.
The service sends a POST to the authorization server's `/token` endpoint with `grant_type=client_credentials`, its credentials, and the requested `scope`. The server validates the credentials, checks the permitted scopes, and returns an access token. The service attaches this token as a `Bearer` header on outbound API calls and fetches a new one when it expires.
The Authorization Code Flow involves a human user who must authenticate and consent via a browser. The Client Credentials Flow has no user — a service authenticates on its own behalf. Because of this, Client Credentials issues no refresh token; the service simply re-authenticates when the access token expires.
Use Client Credentials when you need short-lived, automatically rotated tokens with scope-limited access — for example in zero-trust microservice architectures. API keys are simpler but long-lived and must be rotated manually. Client Credentials is the better choice for systems where token expiry and scoping are important security controls.
Fetch a new token once and cache it in memory until shortly before its `exp` timestamp — typically at 80–90% of its lifetime. Fetching a fresh token on every API call adds unnecessary latency and load to the authorization server. Include retry logic so the service can re-authenticate if a cached token is rejected unexpectedly.
mermaid
sequenceDiagram participant ServiceA as Client Service participant AuthServer as Authorization Server participant ServiceB as Resource Server ServiceA->>AuthServer: POST /token with client_id + client_secret + scope AuthServer-->>AuthServer: Validate credentials and scope alt Credentials valid AuthServer-->>ServiceA: Access token (JWT, short-lived) else Credentials invalid AuthServer-->>ServiceA: 401 Unauthorized end ServiceA->>ServiceB: GET /api/data with Bearer token ServiceB-->>ServiceB: Validate token signature and scope alt Token valid ServiceB-->>ServiceA: 200 OK with resource data else Token expired or invalid ServiceB-->>ServiceA: 401 Unauthorized ServiceA->>AuthServer: POST /token (re-authenticate) AuthServer-->>ServiceA: New access token ServiceA->>ServiceB: Retry request with new token ServiceB-->>ServiceA: 200 OK with resource data end
Copied to clipboard