We are setting up a CI/CD pipeline for our custom agent desktop app and need a way to authenticate without storing static tokens in the repo. The goal is to generate a long-lived session that the pipeline can use for the duration of the build.
I have been trying to use the OAuth2 client credentials flow. The initial token request works fine, but the access token expires in 3600 seconds. I am trying to use the refresh_token returned in the response to get a new access token, but it fails with a 401 Unauthorized.
Here is the code I am using in our Node.js script:
const axios = require('axios');
async function getAccessToken(clientId, clientSecret) {
const tokenUrl = 'https://api.mypurecloud.com/oauth/token';
const params = new URLSearchParams();
params.append('grant_type', 'client_credentials');
params.append('client_id', clientId);
params.append('client_secret', clientSecret);
try {
const response = await axios.post(tokenUrl, params, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
return response.data;
} catch (error) {
console.error('Token fetch failed:', error.response.data);
throw error;
}
}
async function refreshToken(refreshToken) {
const tokenUrl = 'https://api.mypurecloud.com/oauth/token';
const params = new URLSearchParams();
params.append('grant_type', 'refresh_token');
params.append('refresh_token', refreshToken);
try {
const response = await axios.post(tokenUrl, params, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
return response.data;
} catch (error) {
console.error('Refresh failed:', error.response.data);
throw error;
}
}
The error message from the refresh attempt is:
{
"errors": [
{
"description": "Invalid refresh token",
"code": "invalid_grant"
}
]
}
I read somewhere that client credentials flow does not support refresh tokens in the same way as authorization code flow. Is there a different endpoint or grant type I should be using for a machine-to-machine scenario in a pipeline? Or do I just need to re-fetch the token every time the pipeline runs? We want to avoid rate limiting issues if the pipeline runs frequently.