Skip to content

Azure pipeline System.AccessToken in shared pipeline#

Var $(System.AccessToken)#

System.AccessToken is a special variable that carries the security token used by the running build. If you check the doc of job authorization scope, you might think the var $(System.AccessToken) has by default the access to all the repositories in the same project where hosts the calling Azure pipeline. But unfortunately, it's only partially right.


Suppose following situation:

ProjectA.RepoOne.PipelineOne: The Azure DevOps repository RepoOne in the Azure DevOps project ProjectA has a pipeline PipelineOne, the PipelineOne just gets the repositoryId by repositoryName, behind the scenes, it calls the Azure DevOps API. We need to provide an access token to call this API, in our case, we use the built-in $(System.AccessToken).

After the test, if we give RepoOne as the repository name, the pipeline works well, and returns the repositoryId of the repository RepoOne. But if we give another repository name (for e.g. RepoTwo), which is in the same project ProjectA, you will get an error something like:

401 Client Error: Unauthorized for url:

Root cause#

This is because although the $(System.AccessToken) is designed to have access to all the repositories in the same project, there's still another level of security control which blocks the API call, which is the pipeline level permission.


To fix this, one of the solutions is to add the target repository as repositories resource in the PipelineOne yaml file:

    - repository: RepoTwo
      type: git
      name: ProjectA/RepoTwo

When we re-run PipelineOne, this time the pipeline will be in pending for asking for the permission to access to the RepoTwo repository, we need to manually click on the permit button to grant this access, and then the pipeline will succeed as expected.


The repositories resource does not accept variables in the repository and name values which makes the pipeline authoring a little bit sticky. We must write letter by letter the project name and repository name in string, so we need to declare as many repositories resources as the repositories in the same project on which we want to apply the PipelineOne.