> ## Content Index
> Fetch the complete content index at: https://blog.fabrixly.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to Use Client Credentials Flow (Machine-to-Machine, M2M) with Fabrixly-IDS
- URL: https://blog.fabrixly.com/how-to-use-client-credentials-flow-m2m-3/
- Published: 2026-07-07T14:10:45.000Z
- Updated: 2026-07-07T14:38:41.000Z
- Author: Fabrixly
- Tags: Documentation

## Overview

The Client Credentials Flow is for server-to-server (machine-to-machine, M2M) communication—no user involved! Your server authenticates with Fabrixly-IDS using client ID and secret to get an access token for APIs!

## Step 1: Configure M2M Client

First, set up a client for client credentials flow!

### Admin Console Setup

1. Go to **Fabrixly-IDS Admin Console** → **Clients**
2. Click **Create Client** → fill in details:
  - **Client Name**: "My M2M Client"
  - **Response Types**: Leave empty or add "token" (optional)
  - **Grant Types**: add `client_credentials`
  - **Token Endpoint Auth Method**: choose `client_secret_basic` or `client_secret_post`
3. Save! Note your client ID and secret!

### API Setup

### Authenticating API Requests

Management API endpoints (like `/api/clients`, `/api/users`, etc.) require administrative authentication. To call them:

1. **Include the Token in the Authorization Header**: Add `-H "Authorization: Bearer <your-admin-jwt-token>"` to your API calls.

**Obtain an Admin JWT Token**:

```bash
curl -X POST https://ids.fabrixly.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "your-admin-password"
  }'

```

*Note: This returns a JSON response containing a `token`.*

```bash
curl -X POST https://ids.fabrixly.com/api/clients \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-admin-jwt-token>" \
  -d '{
    "client_name": "M2M Client",
    "grant_types": ["client_credentials"],
    "response_types": [],
    "token_endpoint_auth_method": "client_secret_basic",
    "scope": "api:read api:write"
  }'

```

## Step 2: Get Access Token via Client Credentials

To get an access token, send a POST request to the token endpoint:

### Example 1: Using curl

```bash
curl -X POST https://ids.fabrixly.com/oidc/token \
  -u "your-client-id:your-client-secret" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&scope=api:read"

```

Response:

```json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "api:read"
}

```

### Example 2: Using Node.js

Create `m2m-app.js`:

```javascript
const fetch = require('node-fetch');
const { URLSearchParams } = require('url');

const TOKEN_URL = 'https://ids.fabrixly.com/oidc/token';
const CLIENT_ID = 'your-client-id';
const CLIENT_SECRET = 'your-client-secret';
const SCOPE = 'api:read api:write';

async function getAccessToken() {
  const params = new URLSearchParams();
  params.append('grant_type', 'client_credentials');
  params.append('scope', SCOPE);
  
  const credentials = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64');
  
  const response = await fetch(TOKEN_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Authorization': `Basic ${credentials}`
    },
    body: params
  });
  
  const tokenData = await response.json();
  return tokenData;
}

async function callApi(accessToken) {
  // Call your API with the access token
  const apiResponse = await fetch('https://ids.fabrixly.com/api/some-endpoint', {
    headers: { 'Authorization': `Bearer ${accessToken}` }
  });
  return apiResponse.json();
}

// Use it
getAccessToken().then(async (tokenData) => {
  console.log('Access Token:', tokenData.access_token);
  const apiResult = await callApi(tokenData.access_token);
  console.log('API Result:', apiResult);
}).catch(err => console.error('Error:', err));

```

### Example 3: Using openid-client

```javascript
const { Issuer } = require('openid-client');

async function main() {
  const issuer = await Issuer.discover('https://ids.fabrixly.com/oidc');
  const client = new issuer.Client({
    client_id: 'your-client-id',
    client_secret: 'your-client-secret'
  });
  
  const tokenSet = await client.grant({
    grant_type: 'client_credentials',
    scope: 'api:read api:write'
  });
  
  console.log('Access token:', tokenSet.access_token);
  console.log('Expires in:', tokenSet.expires_in);
}

main();

```

## Step 3: Use Access Token to Call APIs

Once you have an access token, use it in the `Authorization` header for API calls:

```http
GET https://ids.fabrixly.com/api/some-endpoint
Host: ids.fabrixly.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

```

## Scopes for M2M

Define scopes to control what your M2M client can do:

```env
# Example scopes
SCOPE_READ=api:read
SCOPE_WRITE=api:write
SCOPE_ADMIN=api:admin

```

## Token Expiry & Refresh

Client credentials flow tokens expire after some time (default: 3600 seconds, 1 hour). When a token expires, just request a new one!

## Security Best Practices

1. **Keep Client Secret Secure**: Never expose client secret in frontend code!
2. **Rotate Secrets**: Regularly rotate client secrets!
3. **Limit Scopes**: Only grant the scopes your M2M client actually needs!
4. **Use Short-Lived Tokens**: Prefer short expiry for access tokens!
5. **Use HTTPS Always**: Never send credentials over unencrypted connections!

## Troubleshooting

- **"Invalid client" error**: Check client ID and secret are correct!
- **"Unauthorized client"**: Ensure client has `client_credentials` grant type enabled!
- **"Invalid scope"**: Make sure requested scopes are allowed for your client!

## Use Cases for M2M Flow

- Cron jobs that call APIs
- Backend services talking to each other
- IoT devices authenticating to cloud APIs
- Scripts that need API access

## Next Steps

- Define custom scopes for your APIs
- Implement token caching for M2M tokens