azureazure-devopsmicrosoft-graph-apiazure-devops-rest-api

Azure DevOps - load provided Graph avatars via OAuth 2.0


I'm using Projects - List REST API to retrieve the list of DevOps projects, with their avatar

[GET] https://dev.azure.com/MY_ORGANIZATION/_apis/projects?getDefaultTeamImageUrl=true

Each returned project has this structure:

{
      "id": "abcdxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "name": "PROJ",
      "url": "https://dev.azure.com/MY_ORGANIZATION/_apis/projects/abcdxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "state": "wellFormed",
      "revision": 21,
      "visibility": "public",
      "defaultTeamImageUrl": "https://dev.azure.com/MY_ORGANIZATION/_apis/GraphProfile/MemberAvatars/efghxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx?overrideDisplayName=PROJ&size=2",
      "lastUpdateTime": "2025-03-12T10:21:29.513Z"
    }

I tried to load /_apis/GraphProfile/MemberAvatars avatar image as is, by signing the request with the same valid OAuth 2.0 access token used for the REST API.
In Microsoft Entra Admin Center, I made sure to include vso.graph API permission for my app registration, but it didn't do the trick.

I know there's the dedicated Avatars - Get REST API (/_apis/graph/Subjects/{subjectDescriptor}/avatars) to get base64 avatars, but it needs the subject descriptor as input, and it's not included in /_apis/projects REST API response (and I'd like to avoid additional API calls to retrieve them).

Fun fact: I tried adding all 76 vso API permissions to my app registration, also with admin consent, and the avatar did load as intended. But now I'm having a hard time in identifying which is the involved API permission.

Any suggestions? Thanks in advance


Solution

  • Based on my test, to run REST API https://dev.azure.com/{OrgName}/_apis/GraphProfile/MemberAvatars/{AvatarId}?api-version=7.1, your API needs user_impersonation permission.

    enter image description here

    user_impersonation allows the application full access to the REST APIs provided by Visual Studio Team Services on behalf of the signed-in user. If the sign-in user has permissions to get project avatar, then the app has permissions.

    I tried assigning all API permissions except `user_impersonation` to my app registration, but my app still does not have enough permissions. Therefore, I guess that additional permissions are required to run the current API, and the permissions come from the user's membership in the organization. For example, PCA has more permissions than shown in the UI and PAT scope.