Hello @Federico Crovetto,
Thank you for posting your query on Microsoft Q&A.
Firstly please note that, Service Principal authentication is not supported to work with Azure DevOps PATs API. You can only use delegated flows that involves user interaction to make it work.
As your requirement is to avoid user interactions, the only way is to make use of ROPC flow. But if MFA is enabled for the user, you cannot use ROPC flow to generate the access token.
To resolve this, please make sure to disable the MFA for the user and generate access token using username password (ROPC) flow.
Important:
- The Microsoft identity platform only supports the ROPC grant within Microsoft Entra tenants, not personal accounts. This means that you must use a tenant-specific endpoint (
https://login.microsoftonline.com/{TenantId_or_Name}
) or theorganizations
endpoint. - Accounts that don't have passwords can't sign in with ROPC, which means features like SMS sign-in, FIDO, and the Authenticator app won't work with that flow. If your app or users require these features, use a grant type other than ROPC.
- If users need to use multi-factor authentication (MFA) to log in to the application, they will be blocked instead.
For additional details, please refer to the below document.
https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth-ropc
Please try to add the API permissions as mentioned in the below Screenshot.
I ran below code files and got the response successfully like this:
auth.js:
require("dotenv").config();
const { PublicClientApplication } = require("@azure/msal-node");
async function getAccessToken() {
const config = {
auth: {
clientId: process.env.AZURE_CLIENT_ID,
authority: https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}
,
}
};
const pca = new PublicClientApplication(config);
try {
const authResponse = await pca.acquireTokenByUsernamePassword({
scopes: ["499b84ac-1321-427f-aa17-267ca6975798/.default"],
username: process.env.AZURE_USERNAME, // Your username (email)
password: process.env.AZURE_PASSWORD, // Your password
});
console.log("Access Token:", authResponse.accessToken);
return authResponse.accessToken;
} catch (error) {
console.error("Error acquiring access token:", error);
}
}
if (require.main === module) {
getAccessToken();
}
module.exports = getAccessToken;
fetchPats.js:
require("dotenv").config();
const axios = require("axios");
const getAccessToken = require("./auth");
async function fetchPats() {
try {
const accessToken = await getAccessToken();
if (!accessToken) throw new Error("Failed to acquire access token");
const url = "https://vssps.dev.azure.com/sridevOps22/_apis/tokens/pats?api-version=7.1-preview.1";
const response = await axios.get(url, {
headers: {
"Authorization": Bearer ${accessToken}
,
"Content-Type": "application/json",
}
});
console.log("\nPAT Tokens Response:", JSON.stringify(response.data, null, 2));
} catch (error) {
console.error("Error fetching PAT tokens:", error.response?.data || error.message);
}
}
fetchPats();
Response:
I hope this above information provided is helpful. Please feel free to reach out if you have any further questions.
If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Thanks and Regards,
Sanoop Mohan