Below is my 2 stage script in Azure DevOps release pipeline for authenticating/generating access token, and calling main API, I have a EntraID/Service Principal which is assigned to workspace with Admin access and also used to generate the token. Error is below
Script-Authenticating
# Define Variables
$tokenUrl = "/**/oauth2/v2.0/token"
$scope= "/.default"
# Prompt for user credentials
$authParams = @{
"client_id" = $env:clientId
"scope" = $scope
"grant_type" = "client_credentials"
"client_secret" = $env:client_secret
}
# Get Access Token
$response = Invoke-RestMethod -Method Post -Uri $tokenUrl -ContentType "application/x-www-form-urlencoded" -Body $authParams
# Extract and Output the Token
$accessToken = $response.access_token
Write-Output "Full Response: $($response | ConvertTo-Json -Depth 10)"
# Ensure access token is retrieved
if (-not $response.access_token) {
Write-Error "Access token is empty."
exit 1
}
# Store Access Token as a Pipeline Variable (for next task)
Write-Output "##vso[task.setvariable variable=accessToken;isSecret=true]$accessToken"
Write-Output "Stored Access Token Length: $($accessToken.Length)"
Main API call
# Retrieve the Access Token from Azure DevOps Pipeline Variable
$accessToken = "$(accessToken)" # Ensure this is set in the pipeline
Write-Output "Access token Length: $($accessToken.Length)"
# Ensure the token is not empty
if (-not $accessToken) {
Write-Error "Access token is empty. Ensure it is being passed correctly from the authentication task."
exit 1
}
# Set headers for API request
$headers = @{
"Authorization" = "Bearer $accessToken"
"Content-Type" = "application/json"
}
# Define API URL
$workspaceId = "**"
$apiUrl = "/$workspaceId/git/updateFromGit"
# Retrieve the latest commit hash from GitHub via Azure DevOps Pipeline variable
$commitId = "$(Build.SourceVersion)" # Ensure this is available in the pipeline
# Ensure commitId is not empty
if (-not $commitId) {
Write-Error "Commit ID is empty. Ensure the pipeline is triggered from a Git commit."
exit 1
}
# Define request body
$body = @{
"remoteCommitHash" = "**"
} | ConvertTo-Json -Depth 10
# Call Microsoft Fabric API
try {
$response = Invoke-RestMethod -Uri $apiUrl -Method Post -Headers $headers -Body $body -UseBasicParsing
Write-Output "Fabric API Response: $response"
} catch {
Write-Error "Error calling Fabric API: $_"
exit 1
}
Error:
Access token Length: 1292 2025-03-06T07:43:51.9969024Z D:\a_temp\7**6.ps1 : Error calling Fabric API: 2025-03-06T07:43:51.9969588Z {"requestId":"2dc3605d-9891-4f60-b54d-72ba4da52809","errorCode":"Unauthorized","message":"The caller is not 2025-03-06T07:43:51.9970305Z authenticated to access this resource"} 2025-03-06T07:43:51.9970968Z At line:1 char:1
Below is my 2 stage script in Azure DevOps release pipeline for authenticating/generating access token, and calling main API, I have a EntraID/Service Principal which is assigned to workspace with Admin access and also used to generate the token. Error is below
Script-Authenticating
# Define Variables
$tokenUrl = "https://login.microsoftonline/**/oauth2/v2.0/token"
$scope= "https://api.fabric.microsoft/.default"
# Prompt for user credentials
$authParams = @{
"client_id" = $env:clientId
"scope" = $scope
"grant_type" = "client_credentials"
"client_secret" = $env:client_secret
}
# Get Access Token
$response = Invoke-RestMethod -Method Post -Uri $tokenUrl -ContentType "application/x-www-form-urlencoded" -Body $authParams
# Extract and Output the Token
$accessToken = $response.access_token
Write-Output "Full Response: $($response | ConvertTo-Json -Depth 10)"
# Ensure access token is retrieved
if (-not $response.access_token) {
Write-Error "Access token is empty."
exit 1
}
# Store Access Token as a Pipeline Variable (for next task)
Write-Output "##vso[task.setvariable variable=accessToken;isSecret=true]$accessToken"
Write-Output "Stored Access Token Length: $($accessToken.Length)"
Main API call
# Retrieve the Access Token from Azure DevOps Pipeline Variable
$accessToken = "$(accessToken)" # Ensure this is set in the pipeline
Write-Output "Access token Length: $($accessToken.Length)"
# Ensure the token is not empty
if (-not $accessToken) {
Write-Error "Access token is empty. Ensure it is being passed correctly from the authentication task."
exit 1
}
# Set headers for API request
$headers = @{
"Authorization" = "Bearer $accessToken"
"Content-Type" = "application/json"
}
# Define API URL
$workspaceId = "**"
$apiUrl = "https://api.fabric.microsoft/v1/workspaces/$workspaceId/git/updateFromGit"
# Retrieve the latest commit hash from GitHub via Azure DevOps Pipeline variable
$commitId = "$(Build.SourceVersion)" # Ensure this is available in the pipeline
# Ensure commitId is not empty
if (-not $commitId) {
Write-Error "Commit ID is empty. Ensure the pipeline is triggered from a Git commit."
exit 1
}
# Define request body
$body = @{
"remoteCommitHash" = "**"
} | ConvertTo-Json -Depth 10
# Call Microsoft Fabric API
try {
$response = Invoke-RestMethod -Uri $apiUrl -Method Post -Headers $headers -Body $body -UseBasicParsing
Write-Output "Fabric API Response: $response"
} catch {
Write-Error "Error calling Fabric API: $_"
exit 1
}
Error:
Share Improve this question edited Mar 6 at 15:18 VLAZ 29.2k9 gold badges63 silver badges84 bronze badges asked Mar 6 at 8:46 SalmanSalman 1,9576 gold badges15 silver badges28 bronze badges 3Access token Length: 1292 2025-03-06T07:43:51.9969024Z D:\a_temp\7**6.ps1 : Error calling Fabric API: 2025-03-06T07:43:51.9969588Z {"requestId":"2dc3605d-9891-4f60-b54d-72ba4da52809","errorCode":"Unauthorized","message":"The caller is not 2025-03-06T07:43:51.9970305Z authenticated to access this resource"} 2025-03-06T07:43:51.9970968Z At line:1 char:1
- 1 Hi @Salman, Good day. Do you mean you generated the token in one PowerShell task in one stage of a release pipeline stage and then use that token directly in the downstream stage? – Alvin Zhao Commented Mar 7 at 5:28
- Hi @Salman, Hope you had relaxing weekends. Have you got a chance to check my workaround below to use a Key Vault resource instead of an output variable across stages of a release pipeline? The option to use a YAML pipeline can also work for you. Hope the information helps resolve your concerns in this ticket. Look forward to your response. Thx. – Alvin Zhao Commented Mar 10 at 9:43
- Hi @Salman. Good day. Have you got tired to the workaround to use Azure Key Vaults? Or would you use a YAML pipeline instead? Hope to be of help to resolve your query in this post. Look forward to you update and wish you a lovely weekend. – Alvin Zhao Commented Mar 14 at 9:14
1 Answer
Reset to default 0From your current description, it seemed that you would like to use the output variable accessToken
across the stages in a release pipeline.
Please note that the release pipelines don't support using outputs in different jobs/stages, as outlined in this document.
The workaround in this post doesn't seem to work any longer, as far as I have tested. Except for the option to transition to YAML pipelines, you may refer to the steps below in a release pipeline, if you are open to use an Azure Key Vault resource to manage secrets.
In Stage 1, add an Azure CLI task and run the
az keyvault secret set --name accessToken --vault-name $(myKeyVault) --value $(accessToken)
in it to create a secret (if one doesn't exist) or update a secret in your target Key Vault. It will use the value of variableaccessToken
output by your PowerShell task in the same job;In Stage 2, add the
AzureKeyVault@2
task before your script to call an API; it will retrieve the value of the secretaccessToken
in your Key Vault and populate a pipeline variable$(accessToken)
for your tasks in downstream jobs/stages to use.
Ensure the underlying service principal of the ARM service connection referenced by both AzureCLI@2
and AzureKeyVault@2
tasks is granted with sufficient permissions to read and write secrets in your Key Vault.
Be mindful of potential token exposure risks, such as unauthorized access to Key Vault.