Client Credentials Grant
What is the Client Credentials grant?
Section titled “What is the Client Credentials grant?”The Client Credentials grant is designed for machine-to-machine calls where there is no user. Instead of a user authenticating, the client authenticates itself using its client_id and client_secret. Because there is no user in the flow, Keycloak returns only an access token — there is no ID token.
This grant is part of the OAuth2 specification and is the standard approach for service accounts, background jobs, and any automated process that needs to call a protected API.
When to use it
Section titled “When to use it”Use the Client Credentials grant for:
- Background jobs calling an internal API
- Microservices calling each other
- CI/CD pipelines provisioning infrastructure
Do not use it for anything where a real user is involved. If a user must authenticate and your app needs to act on their behalf, use Authorization Code + PKCE instead.
Setting up in Keycloak
Section titled “Setting up in Keycloak”- Create a confidential client (set Client authentication to On).
- Enable Service Accounts — on the Capability config tab, enable Service account roles.
- Copy the client secret from the Credentials tab.
- Assign realm roles or client roles to the service account user on the Service Accounts Roles tab if your API checks roles in the token.
Requesting a token
Section titled “Requesting a token”curl -X POST https://${KC_URL}/realms/${REALM}/protocol/openid-connect/token \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}"Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
| Client Credentials (M2M) | Simple to set up, no user login needed — good for background jobs and service-to-service calls | No user context at all — unusable if you need to track who performed the action |
| Authorization Code + PKCE (user-delegated) | Knows exactly which user an action was performed on behalf of; supports consent and per-user auditing | Always requires a user to log in through a browser first — cannot be used for an automated job |
Common mistakes
Section titled “Common mistakes”- Putting a client secret in a frontend or mobile app — the Client Credentials grant is designed for confidential clients only, such as a backend service running on a server you control. Embedding the secret in frontend or mobile app code means anyone who decompiles it or opens dev tools sees the secret immediately.
- Using Client Credentials when you actually need user context — if the flow needs to know “who requested this action” for an audit log or role-based authorization, never use Client Credentials, since no user is involved at all. Use Authorization Code + PKCE instead.
- Not rotating the client secret periodically — because a service account tends to run for a long time with nobody touching its code again, the same secret often stays in use indefinitely without rotation, letting risk accumulate over time.
Real-world example
A CI/CD pipeline that deploys infrastructure — such as GitHub Actions or GitLab CI calling an internal API to provision resources — uses the Client Credentials grant because no human is sitting at a screen while the pipeline runs.
A microservice calling another microservice internally — such as order-service calling inventory-service — authenticates with Client Credentials rather than forwarding the user’s token onward, which cleanly separates service identity from user identity.