OAuth 2.0 Device Authorization Flow vs Client Credentials Flow in Auth0 MCP Server

The device authorization flow requires interactive user authentication via a browser and returns a refresh token for long-lived access, while the client credentials flow enables fully automated machine-to-machine authentication without user interaction or refresh tokens.

The auth0/auth0-mcp-server repository implements both OAuth 2.0 flows to accommodate different authentication scenarios. Understanding the distinction between OAuth 2.0 device authorization flow vs client credentials flow is essential for choosing the correct authentication method for your deployment environment.

Core Architectural Differences

The fundamental distinction lies in the authorization boundary: device flow creates user-bound sessions, while client credentials creates service-bound sessions.

Device Authorization Flow: Interactive User Authentication

The device flow, implemented in src/auth/device-auth-flow.ts, is designed for input-constrained devices like CLIs or smart TVs. It delegates user authentication to a secondary device with a full browser. According to the source code, this flow produces a user-bound session where the tenant context derives from the authenticated user's JWT.

The implementation stores a refresh token in the OS keychain via src/utils/keychain.ts, enabling the CLI to obtain new access tokens without requiring the user to re-authenticate. The entry point requestAuthorization initiates the flow, while exchangeDeviceCodeForToken handles the polling mechanism against Auth0's token endpoint.

Client Credentials Flow: Machine-to-Machine Authentication

The client credentials flow, located in src/auth/client-credentials-flow.ts, facilitates server-to-server authentication without any user interaction. This flow is implemented via the requestClientCredentialsAuthorization function, which invokes the Auth0 SDK's oauth.clientCredentialsGrant method.

Unlike the device flow, this implementation returns only an access token; no refresh token is issued. The client must use the stored auth0ClientSecret to request a new token upon expiration. This creates a service-bound session suitable for automated environments where user context is irrelevant.

Implementation Details in Auth0 MCP Server

Both flows follow distinct implementation patterns within the codebase, reflecting their operational requirements.

Device Flow Implementation

The device authorization implementation relies on a polling mechanism and secure token persistence:

  1. Authorization Request: The requestAuthorization function calls POST /oauth/device/code with the client_id and optional audience/scope parameters.
  2. User Code Display: The CLI displays the user_code and verification URL, optionally opening the browser automatically.
  3. Token Polling: The exchangeDeviceCodeForToken function polls POST /oauth/token with the device_code until the user completes authentication.
  4. Secure Storage: Upon success, the access token, refresh token, and expiration data are stored via src/utils/keychain.ts.

The flow includes polling back-off logic to respect Auth0 rate limits, and the refresh token can be revoked via revokeRefreshToken when sessions terminate.

Client Credentials Implementation

The client credentials implementation prioritizes automation and headless operation:

  1. Configuration: The ClientCredentialsConfig interface requires auth0Domain, auth0ClientId, and auth0ClientSecret.
  2. SDK Integration: The requestClientCredentialsAuthorization function instantiates an AuthenticationClient and calls oauth.clientCredentialsGrant.
  3. Token Storage: The resulting access token is stored via storeTokenInfo in src/auth/client-credentials-flow.ts (lines 71-90), though no refresh token is persisted.
  4. Audience Defaulting: If unspecified, the audience defaults to https://{domain}/api/v2/.

This flow is used by Private Cloud customers and CI/CD pipelines where browser interaction is impossible.

Key Differences Summary

Aspect Device Authorization Flow Client Credentials Flow
Authentication Type User-bound (interactive) Service-bound (automated)
User Interaction Required (browser sign-in) None (headless)
Token Types Access token + refresh token Access token only
Primary Use Case Local development, CLI tools CI/CD pipelines, Private Cloud
Credential Storage Refresh token in OS keychain Client secret in environment/config
Token Renewal Automatic via getValidAccessToken() Manual re-authentication required
Implementation File src/auth/device-auth-flow.ts src/auth/client-credentials-flow.ts

Code Examples

Device Authorization Flow (Interactive)

Use this flow when building CLI tools that require user-specific tenant access:

import { requestAuthorization } from './auth/device-auth-flow.js';

// Initiates device flow with custom scopes
await requestAuthorization(['read:clients', 'read:users']);

// Later, retrieve valid token (auto-refreshes if expired)
import { getValidAccessToken } from './auth/device-auth-flow.js';
const token = await getValidAccessToken();

Source: src/auth/device-auth-flow.ts – Entry point requestAuthorization (lines 30-62).

Client Credentials Flow (Automated)

Use this flow for server-to-server authentication without user interaction:

import { requestClientCredentialsAuthorization, ClientCredentialsConfig } from './auth/client-credentials-flow.js';

const config: ClientCredentialsConfig = {
  auth0Domain: 'my-tenant.auth0.com',
  auth0ClientId: process.env.AUTH0_CLIENT_ID!,
  auth0ClientSecret: process.env.AUTH0_CLIENT_SECRET!,
  audience: 'https://my-tenant.auth0.com/api/v2/',
  scopes: ['read:clients']
};

await requestClientCredentialsAuthorization(config);

Source: src/auth/client-credentials-flow.ts – Main function requestClientCredentialsAuthorization (lines 27-63).

Security and Token Management

The Auth0 MCP Server implements distinct security models for each flow.

Device Flow Security relies on the OS keychain via src/utils/keychain.ts to store the refresh token. This enables the refreshAccessToken functionality, allowing the CLI to maintain long-lived sessions without storing the user's password. The flow supports token revocation via revokeRefreshToken when sessions terminate.

Client Credentials Security does not issue refresh tokens. The implementation in src/auth/client-credentials-flow.ts stores only the short-lived access token. Security depends on protecting the auth0ClientSecret in environment variables or secure configuration stores. Token lifetime is controlled by the Auth0 API (default ≤ 24 hours), requiring the client to re-authenticate periodically.

Summary

  • Device Authorization Flow requires interactive user authentication via a browser, stores a refresh token in the OS keychain, and is ideal for local development environments.
  • Client Credentials Flow enables headless machine-to-machine authentication using a client secret, returns only short-lived access tokens, and is designed for CI/CD pipelines and Private Cloud deployments.
  • Both flows are implemented in src/auth/device-auth-flow.ts and src/auth/client-credentials-flow.ts respectively, with token persistence handled by src/utils/keychain.ts.

Frequently Asked Questions

When should I use device authorization flow versus client credentials flow?

Use the device authorization flow when a human user needs to authenticate through a CLI or input-constrained device, such as during local development or interactive scripting. Use the client credentials flow for automated server-to-server communication where no user interaction is possible, such as in CI/CD pipelines or Private Cloud environments.

Does the client credentials flow support refresh tokens?

No. According to the implementation in src/auth/client-credentials-flow.ts, the client credentials flow returns only an access token without a refresh token. The client must use the stored auth0ClientSecret to request a new access token when the current one expires.

How does the Auth0 MCP Server store authentication tokens?

The server uses the OS keychain via src/utils/keychain.ts to securely persist credentials. For the device flow, it stores the refresh token, access token, and expiration data. For the client credentials flow, it stores only the access token and expiration, as no refresh token is issued.

Which flow is better for CI/CD pipelines?

The client credentials flow is the correct choice for CI/CD pipelines because it requires no browser interaction or user presence. The pipeline can authenticate using environment variables containing the auth0ClientId and auth0ClientSecret, making it fully automated and suitable for headless environments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →