Limit the job authorization scope to the current project at the organization level, trim the permissions of the project build service identity, enable repository protection for YAML pipelines, and avoid secrets where a service connection or managed identity will do. Together these keep one compromised pipeline from reaching every repository.
What is a job access token?
Every pipeline job gets a token that Azure Pipelines generates at run time. The agent uses it to check out code, add tags, read Azure Artifacts feeds, upload logs and test results, and update work items.
Microsoft's documentation says the token's permissions come from two things: the job authorization scope, and the permissions on the build service account. Control both and you control the token.
Why does scope matter so much?
Scope is either collection or project. Collection means the job can reach all repositories in the organization. Project restricts it to repositories in the pipeline's own project.
The docs are blunt about the failure case. If scope is not restricted at the organization or project level, every YAML job gets a collection-scoped token. An adversary who gets into one pipeline in one project can reach any repository in the organization. Microsoft recommends setting the restriction at the highest level, in organization settings, so one project's problem stays in that project.
A constructed example: a small internal tools project has loose review rules, and a contributor can edit its pipeline. With collection scope, that pipeline can clone the payments repository. With project scope, it cannot.
Which settings do you change?
Under Organization settings, then Pipelines, then Settings, turn on these:
- Limit job authorization scope to current project for non-release pipelines (covers YAML and classic build pipelines).
- Limit job authorization scope to current project for release pipelines (classic release only).
If scope is set to project at the organization level, individual projects cannot change it back.
Also check Protect access to repositories in YAML pipelines. With it on, pipelines can reach only the Azure DevOps repositories named in a checkout step or a uses statement. The docs say it is on by default for organizations and projects created after May 2020, so older ones are worth checking.
What about the build service identity?
Two built-in identities run pipelines. One is collection-scoped, named Project Collection Build Service followed by your organization name. The other is project-scoped, named after the project followed by Build Service.
After you restrict scope, the project identity may lack access to something the collection identity had, such as a feed in another project. Grant that access explicitly and narrowly. The docs also describe cases for taking permissions away, for example stopping a pipeline from changing code in a repository or creating work items. The project-scoped account only appears after the pipeline has run once.
How should secrets be handled?
Microsoft's secrets guidance starts with avoiding them. Prefer service connections, managed identities, or the Azure CLI task with the addSpnToEnvironment option. Where you must keep a secret, use Azure Key Vault so Azure role-based access control limits who can read it.
Other points from the page: never echo secrets or pass them on the command line, map them into environment variables instead; log scrubbing is not foolproof; do not wrap secrets in JSON, XML or YAML blobs, because redaction gets less accurate; keep personal access token lifetimes short with minimal permissions; and rotate regularly.
What to do
- Open Organization settings, Pipelines, Settings, and enable both scope limits.
- Confirm Protect access to repositories in YAML pipelines is on.
- List cross-project access your pipelines really need and grant it to the project build identity only.
- Remove write access to repositories and work items from the build identity where pipelines do not need it.
- Replace stored credentials with service connections or managed identities.
- Move remaining secrets to Key Vault and review the run logs for leaks after testing with bad input.
- Set PAT expiry to the shortest practical time and review them quarterly.
Safeguard's policies and gates can add a check at pull request and build time, which helps when pipeline definitions change often.
Quick check
Is the project build service identity created automatically?
It appears only after the pipeline has run once, so run it before trying to edit its permissions.
Does a public project need the scope setting?
No. Microsoft's page says jobs in a public project are automatically restricted to project scope.
Sources
- Understand job access tokens, Azure Pipelines (fetched 18 October 2026)
- Secrets in pipelines, Azure Pipelines (fetched 18 October 2026)
Last reviewed: 18 October 2026.