Permissions and security groups in Azure DevOps
Design and implement permissions and security groups in Azure DevOps
Groups, not people
Azure DevOps ships built-in groups — Readers, Contributors, Project Administrators, Build Administrators, Project Collection Administrators — and permissions should be assigned to groups, with people added to groups. Assigning directly to a user is how an organisation ends up unable to answer "who can deploy to production?"
Allow, Deny, and inheritance
Permissions are inherited down the hierarchy — organisation → project → object — and each is Allow, Deny or Not set.
Deny takes precedence over Allow. A user in two groups, one allowing and one denying, is denied.
That single rule explains most "why can't they do this?" incidents. The exception worth knowing: members of Project Collection Administrators are not restricted by a Deny in the same way, which is itself a reason to keep that group small.
Not set means inherit; it is not the same as Deny. Setting an explicit Deny where inheritance would already have denied makes later delegation harder, because the Deny wins even when someone is deliberately added to an allowing group.
Scope the sensitive things separately
Service connections, agent pools, variable groups and environments each carry their own permissions and their own checks. Repository and pipeline permissions do not govern them — which is the point: the owner of the production environment can be a different person from the owner of the code.
Primary sources