How to decode the Access control Entries in Azure DevOps REST API for checking the Security groups permissions.

Yash Tiwari 60 Reputation points
2025-06-09T13:31:02.3566667+00:00

I am trying to understand Azure DevOps Security Group permissions through the REST API. The data available in the Access Control Entries (ACEs) REST API probably reflects the Allow/Deny permission details shown in the UI. I was able to retrieve this data, but I am having trouble understanding it.

Here’s an example response I received:

{

"count": 1,

"value": [

{

  "inheritPermissions": true,

  "token": "$PROJECT:vstfs:///Classification/TeamProject/6482a941-9c18-4e55-84ca-1778fe129a43",

  "acesDictionary": {

    "Microsoft.IdentityModel.Claims.ClaimsIdentity;vssgp.Uy0xLTktMTU1MTM3NDI0NS0xMTAxNjI4MDA0LTQxMjg5ODYzOC0yMjI3ODM2NzkyLTQyNjI2MzIwMDMtMS0zNjA1Nzk4MTcyLTI4OTY1OTcyNi0yMjgwMzMxMDIwLTIyMzY3Mjg3NQ": {

      "descriptor": "Microsoft.IdentityModel.Claims.ClaimsIdentity;vssgp.Uy0xLTktMTU1MTM3NDI0NS0xMTAxNjI4MDA0LTQxMjg5ODYzOC0yMjI3ODM2NzkyLTQyNjI2MzIwMDMtMS0zNjA1Nzk4MTcyLTI4OTY1OTcyNi0yMjgwMzMxMDIwLTIyMzY3Mjg3NQ",

      "allow": 0,

      "deny": 0,

      "extendedInfo": {}

    }

  },

  "includeExtendedInfo": true

}

]

}

I was able to generate this response, but I am unsure how to link it to specific projects and groups.

I also found the security namespace ID, and I can see the bit values, but I don’t understand how they produce the results I see.

Here’s an example from the Security Namespaces API:

{

"namespaceId": "52d39943-cb85-4d7f-8fa8-c6baac873819",

"name": "Project",

"displayName": "Project",

"separatorValue": ":",

"elementLength": -1,

"writePermission": 2,

"readPermission": 1,

"dataspaceCategory": "Default",

"actions": [

{

  "bit": 1,

  "name": "GENERIC_READ",

  "displayName": "View project-level information",

  "namespaceId": "00000000-0000-0000-0000-000000000000"

},

{

  "bit": 2,

  "name": "GENERIC_WRITE",

  "displayName": "Edit project-level information",

  "namespaceId": "00000000-0000-0000-0000-000000000000"

}

]

}

I assigned the value to "View project-level information", and I'm using the namespace ID 52d39943-cb85-4d7f-8fa8-c6baac873819.

Please guide me on how I can interpret these bit values and the allow/deny permissions using the REST API.

azure devops

Azure DevOps
0 comments No comments
{count} votes

Accepted answer
  1. Durga Reshma Malthi 4,530 Reputation points Microsoft External Staff Moderator
    2025-06-09T13:44:47.7133333+00:00

    Hi Yash Tiwari

    The namespace ID 52d39943-cb85-4d7f-8fa8-c6baac873819 corresponds to Project-level permissions.

    1. Each namespace contains actions with specific bit values
    2. Each permission has a bit value that represents a specific action. Example: GENERIC_READ (View project-level information) -> Bit value: 1 GENERIC_WRITE (Edit project-level information) -> Bit value: 2 If a user has both permissions, the allow value would be 1 + 2 = 3.
    3. The allow and deny fields in the ACEs response define which permissions are granted or restricted. Example:
      • "allow": 1 -> User can view project-level information.
      • "allow": 2 -> User can edit project-level information.
      • "allow": 3 -> User can view and edit.
      • "deny": 1 -> User cannot view project-level information.
    4. The UI dropdowns (Allow/Deny/Not Set) correspond to these bit values.
    5. If "View project-level information" is set to Deny, the API response should reflect "deny": 1.
    6. The token field ($PROJECT:vstfs:///Classification/TeamProject/...) represents the project where the permissions apply.
    7. The descriptor field (Microsoft.IdentityModel.Claims.ClaimsIdentity;vssgp...) represents the user or group.
    8. The acesDictionary contains the actual permissions for that user/group.

    Hope this helps!

    Please Let me know if you have any queries. If you found the information helpful, please click "Upvote" on the post to let us know and consider accepting the answer as the token of appreciation. Thank You.

    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Durga Reshma Malthi 4,530 Reputation points Microsoft External Staff Moderator
    2025-06-11T10:12:31.9+00:00

    Hi

    As we discussed in Private message, you are facing the below error,

    User's image

    User's image

    The GET /graph/descriptors/{descriptor} endpoint expects a storageKey or SID (like S-1-...), not the vssgp... descriptor. That's why you're getting: "Message": "The request is invalid."

    Try to use

    GET https://vssps.dev.azure.com/{organization}/_apis/graph/groups/{groupDescriptor}?api-version=7.1-preview.1
    

    or

    GET https://{{baseUrl}}/{{organization}}/_apis/identities?subjectDescriptors={{subjectdescriptor}}&api-version={{api-version}}
    

    Alternatively, you can try this

    GET https://vssps.dev.azure.com/{organization}/_apis/graph/identities/{descriptor}?api-version=7.1-preview.1
    

    or Try this URL format:

    GET https://vssps.dev.azure.com/yashtiwari0970/_apis/graph/identities/vssgp.Uy0xL...==?api-version=7.1-preview.1
    

    you will get response like

    {
      "descriptor": "vssgp.Uy0xL...",
      "originId": "GUID",
      "subjectKind": "Group",
      "displayName": "My Group",
      "url": "...",
      "domain": "vsts",
      "principalName": "",
      "origin": "vsts",
      "mailAddress": null,
      "links": {...},
      "id": "GUID",
      "storageKey": "S-1-9-1551374245-..."  ← This is what you match in ACL!
    }
    

    You now use:

    "descriptor": "Microsoft.TeamFoundation.Identity;{storageKey}"
    

    and match this against your ACL API results.

    Hope this helps!

    Please Let me know if you have any queries.

    If you found the information helpful, please click "Upvote" on the post to let us know and consider accepting the answer as the token of appreciation. Thank You.

    1 person found this answer helpful.
    0 comments No comments

  2. Durga Reshma Malthi 4,530 Reputation points Microsoft External Staff Moderator
    2025-06-10T08:14:32.8766667+00:00

    Hi Yash Tiwari

    Could you please follow the below steps:

    1. Your response shows "inheritPermissions": true, meaning permissions might be inherited from a higher-level group. Check if the Contributors group is inheriting permissions from another group that overrides your changes. Go to Azure DevOps -> Project Settings -> Contributors -> Check if any permissions show "Inherited" next to them -> Change the permission to Allow or Deny, overriding the inherited value.
    2. Azure DevOps may take a few minutes to apply security changes. Try waiting a bit and then re-querying the API.
    3. Some API responses might be cached. Try adding a query parameter like ?forceRefresh=true when making the request.
         curl -X GET "https://dev.azure.com/{organization}/_apis/securitynamespaces/{namespaceId}/permissions?forceRefresh=true&api-version=7.1"
      
    4. Alternatively, Set recurse=true to see inherited entries: Example:
         GET https://dev.azure.com/{organization}/_apis/securitynamespaces/{namespaceId}/accesscontrolentries?tokens=$PROJECT:vstfs:///Classification/TeamProject/{projectId}&descriptors={groupDescriptor}&includeExtendedInfo=true&recurse=true
      
      This allows the ACEs API to return inherited permissions, not just those explicitly set at the $PROJECT level.
    5. If you want to evaluate effective permissions, then use the following API:
         POST https://dev.azure.com/{org}/_apis/security/permissionevaluations?api-version=7.1-preview.1
      
      This will return "effectivePermission": "Deny"

    Hope this helps!

    Please Let me know if you have any queries.

    If you found the information helpful, please click "Upvote" on the post to let us know and consider accepting the answer as the token of appreciation. Thank You.


  3. Yash Tiwari 60 Reputation points
    2025-06-11T10:28:04.0133333+00:00

    Thanks @Durga Reshma Malthi
    GET https://{{baseUrl}}/{{organization}}/_apis/identities?subjectDescriptors={{subjectdescriptor}}&api-version={{api-version}}

    The above API has solved my query and i'm getting the descriptor for my group id that can be used to filter the Access control List APIs.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.