Using Client Credentials with Drupal Simple OAuth (the simple way)

By drupov , 5 April, 2026

Tags

Client Credentials in Drupal Simple OAuth is a simple way to let backend services access your API without user logins. It allows your app to act as a controlled Drupal user, keeping everything secure and predictable while staying within Drupal’s permission system.

When I first looked at OAuth in Drupal, it felt like unnecessary complexity. Drupal already has users, roles, and permissions—why add another layer?

The answer only really clicks once you deal with non-user access.

Imagine your Next.js app (server-side), a cron job, or a small script that needs to fetch data from Drupal. There is no user logging in, but you still don’t want your API completely open. That’s exactly what the Client Credentials flow solves.

Instead of a real login, you define a client that acts as a fixed Drupal user.

The basic idea

You create a special Drupal user, for example:

username: api_user
role: api_user (or just authenticated with limited permissions)

This user should have only the permissions needed (for example: read content via GraphQL).

Then you create a consumer in Drupal and enable Client Credentials, and assign that user to it.

From that point on, any token issued for this client will behave as if it were that user.

Getting a token

Your app (or script) requests a token like this:

curl -X POST "https://your-drupal-site.com/oauth/token" \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -d "grant_type=client_credentials" \
 -d "client_id=YOUR_CLIENT_ID" \
 -d "client_secret=YOUR_CLIENT_SECRET"

Drupal responds with something like:

{
 "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOi...",
 "token_type": "Bearer",
 "expires_in": 3600
}

Using the token

Now you use that token for API requests:

curl -X POST "https://your-drupal-site.com/graphql" \
 -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
 -H "Content-Type: application/json" \
 -d '{"query": "{ nodeQuery { entities { ... on NodeArticle { title } } } }"}'

Drupal will process this request as:

“This is the api_user making the request”

So all access is controlled by that user’s permissions.

What makes this useful

This approach gives you a clean separation:

  • No public API access
  • No user login required
  • Full control via Drupal roles

Your Next.js server or background job can safely talk to Drupal, and you still stay inside Drupal’s permission system.

One important rule

Never use an admin user here.

Whatever permissions that user has, the token will have too. Keep it minimal and purpose-specific.

Final thought

Client Credentials is not about users—it’s about trusted systems.

If something needs to talk to Drupal without a human involved, this is the simplest and cleanest way to do it.

Comments