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

> Compare OAuth 2.0 device authorization flow and client credentials flow in Auth0 MCP Server. Understand user vs machine authentication needs and token management.

- Repository: [Auth0/auth0-mcp-server](https://github.com/auth0/auth0-mcp-server)
- Tags: deep-dive
- Published: 2026-02-25

---

**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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/src/auth/device-auth-flow.ts) | [`src/auth/client-credentials-flow.ts`](https://github.com/auth0/auth0-mcp-server/blob/main/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:

```typescript
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`](https://github.com/auth0/auth0-mcp-server/blob/main/src/auth/device-auth-flow.ts) – Entry point `requestAuthorization` ([lines 30-62](https://github.com/auth0/auth0-mcp-server/blob/main/src/auth/device-auth-flow.ts#L30-L62)).

### Client Credentials Flow (Automated)

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

```typescript
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`](https://github.com/auth0/auth0-mcp-server/blob/main/src/auth/client-credentials-flow.ts) – Main function `requestClientCredentialsAuthorization` ([lines 27-63](https://github.com/auth0/auth0-mcp-server/blob/main/src/auth/client-credentials-flow.ts#L27-L63)).

## 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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/src/auth/device-auth-flow.ts) and [`src/auth/client-credentials-flow.ts`](https://github.com/auth0/auth0-mcp-server/blob/main/src/auth/client-credentials-flow.ts) respectively, with token persistence handled by [`src/utils/keychain.ts`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/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`](https://github.com/auth0/auth0-mcp-server/blob/main/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.