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:
- Authorization Request: The
requestAuthorizationfunction callsPOST /oauth/device/codewith theclient_idand optionalaudience/scopeparameters. - User Code Display: The CLI displays the
user_codeand verification URL, optionally opening the browser automatically. - Token Polling: The
exchangeDeviceCodeForTokenfunction pollsPOST /oauth/tokenwith thedevice_codeuntil the user completes authentication. - 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:
- Configuration: The
ClientCredentialsConfiginterface requiresauth0Domain,auth0ClientId, andauth0ClientSecret. - SDK Integration: The
requestClientCredentialsAuthorizationfunction instantiates anAuthenticationClientand callsoauth.clientCredentialsGrant. - Token Storage: The resulting access token is stored via
storeTokenInfoinsrc/auth/client-credentials-flow.ts(lines 71-90), though no refresh token is persisted. - Audience Defaulting: If unspecified, the
audiencedefaults tohttps://{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.tsandsrc/auth/client-credentials-flow.tsrespectively, with token persistence handled bysrc/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →