azure-devopsdevopsazure-devops-rest-apiazure-devops-extensions

How to add users to a particular repository using API


I am struggling in going through the API documentation for Azure devops on how to add a user to a particular repo using Rest API with read and write access to a git repository. Please guide me on this.

For Example: There are 3 Repositories. I want to restrict access to other two repositories via API. I fetched the namespaceId and used access control entitlement APIs nothing helped


Solution

  • Based on the further discussions, the actual requirement is to allow users' access to one single repo in a project and prevent the access to other repos in this project. For this, you may try the sample PowerShell script below, which will Deny All repositories Contribute permission for [PrjectA]\Contributors group and Allow Repo1 Contribute permission for [PrjectA]\Contributors group.

    $organization = "YourADOOrgName"
    $project = "ProjectA"
    $groupName = "Contributors"
    $allowRepo = "Repo1"
    
    $MyPat = 'xxxxx'
    $B64Pat = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$MyPat"))
    $headers = @{
        'Authorization' = 'Basic ' + $B64Pat
        'Content-Type' = 'application/json'
    }
    
    # Get projects GET https://dev.azure.com/{organization}/_apis/projects?api-version=7.1-preview.4
    $projectsURL = "https://dev.azure.com/$organization/_apis/projects?api-version=7.1-preview.4"
    $projects = Invoke-RestMethod -Uri $projectsURL -Method Get -Headers $headers
    $projectA = $projects.value | Where-Object { $_.name -eq "$project" }
    $projectAId = $projectA.id
    Write-Host "The id of $project is $projectAId"
    
    # Get repos GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories?api-version=7.1-preview.1
    $reposURL = "https://dev.azure.com/$organization/$project/_apis/git/repositories?api-version=7.1-preview.1"
    $repos = Invoke-RestMethod -Uri $reposURL -Method Get -Headers $headers
    $repo = $repos.value | Where-Object { $_.name -eq "$allowRepo" }
    $repoId = $repo.id
    Write-Host "The id of $allowRepo is $repoId"
    
    # Get group identity GET https://vssps.dev.azure.com/{organization}/_apis/identities?searchFilter=General&filterValue=Project Collection Valid Users&queryMembership=None&api-version=7.2-preview.1
    $groupIdsURL = "https://vssps.dev.azure.com/$organization/_apis/identities?searchFilter=General&filterValue=[$project]\$groupName&queryMembership=None&api-version=7.2-preview.1"
    $groupIds = Invoke-RestMethod -Uri $groupIdsURL -Method Get -Headers $headers
    $groupId = $groupIds.value | Where-Object { $_.providerDisplayName -eq "[$project]\$groupName" }
    $groupDescriptor = $groupId.descriptor
    Write-Host "The descriptor for group [$project]\$groupName is $groupDescriptor"
    
    # All security namespaces GET https://dev.azure.com/{organization}/_apis/securitynamespaces?api-version=7.2-preview.1
    $namespacesURL = "https://dev.azure.com/$organization/_apis/securitynamespaces?api-version=7.2-preview.1"
    $namespaces = Invoke-RestMethod -Uri $namespacesURL -Method Get -Headers $headers
    $namespaces |  ConvertTo-Json -Depth 100 | Out-File "C:\Users\Alvin\Desktop\namespaces.json"
    $namespaceGitRepos = $namespaces.value | Where-Object { $_.displayName -eq "Git Repositories" }
    $namespaceIdGitReposContribute = $namespaceGitRepos.actions | Where-Object { $_.displayName -eq "Contribute" }
    $namespaceIdGitReposContributeBit = $namespaceIdGitReposContribute.bit
    $namespaceIdGitRepos = $namespaceGitRepos.namespaceId
    Write-Host "The id for namespace Git Repositories is $namespaceIdGitRepos"
    Write-Host "The bit for permission Contribute in namespace Git Repositories is $namespaceIdGitReposContributeBit"
    
    # Access Control Entries - Set Access Control Entries POST https://dev.azure.com/{organization}/_apis/accesscontrolentries/{securityNamespaceId}?api-version=7.2-preview.1
    $contributeACEURL = "https://dev.azure.com/$organization/_apis/accesscontrolentries/${namespaceIdGitRepos}?api-version=7.2-preview.1"
    
    # Deny All repositories Contribute permission for [PrjectA]\Contributors group
    $contributeDenyACEBody = @{
        "token" = "repoV2/$projectAId"
        "merge" = $true
        "accessControlEntries" = @(
            @{
                "descriptor" = "$groupDescriptor"
                "allow" = 0
                "deny" = $namespaceIdGitReposContributeBit
                "extendedInfo"= @{
                    "effectiveAllow" = 0
                    "effectiveDeny" = $namespaceIdGitReposContributeBit
                    "inheritedAllow" = 0
                    "inheritedDeny" = $namespaceIdGitReposContributeBit
                }
            }
        )
    } | ConvertTo-Json -Depth 100
    Invoke-RestMethod -Uri $contributeACEURL -Method Post -Headers $headers -Body $contributeDenyACEBody 
    
    # Allow Repo1 Contribute permission for [PrjectA]\Contributors group
    $contributeAllowACEBody = @{
        "token" = "repoV2/$projectAId/$repoId"
        "merge" = $true
        "accessControlEntries" = @(
            @{
                "descriptor" = "$groupDescriptor"
                "allow" = $namespaceIdGitReposContributeBit
                "deny" = 0
                "extendedInfo"= @{
                    "effectiveAllow" = $namespaceIdGitReposContributeBit
                    "effectiveDeny" = 0
                    "inheritedAllow" = $namespaceIdGitReposContributeBit
                    "inheritedDeny" = 0
                }
            }
        )
    } | ConvertTo-Json -Depth 100
    Invoke-RestMethod -Uri $contributeACEURL -Method Post -Headers $headers -Body $contributeAllowACEBody
    

    Image

    Once tested working, you may spread to other permissions like Read and set permissions for another group of users like Readers.