Why does accessing Jira custom project avatars return 403?

We have an app that fetches a list of Jira projects via OAuth 2 (3LO) from REST API v2 ( via GET /rest/api/2/project/search) and renders them in a third-party application.

We use project.avatarUrls["24x24"] from the result to render the project avatars. Strangely, for Jira built-in avatars this works without any issues, however, for projects with custom avatars (image uploaded by us) the URLs return 403.

URLs look like this:

This does not work:
https://api.atlassian.com/ex/jira/63790a21-b73c-46b8-ba3c-e34cbbb97cd8/secure/projectavatar?size=small&s=small&pid=10005&avatarId=10524

Here it works:
https://api.atlassian.com/ex/jira/63790a21-b73c-46b8-ba3c-e34cbbb97cd8/secure/projectavatar?size=small&s=small&pid=10009&avatarId=10499

Does anyone have an idea how to fix this? It seems custom avatars are not made publicly accessible.

Ping: Does anyone at Atlassian have an idea on how to fix this? @nmansilla

Hi @tbinna,

I’ll see if I can help. I hope that either myself or someone from the Jira team will get back to you soon.

Regards,
Dugald

1 Like

Hi @tbinna, this is Cristian from Jira Platform :wave:t2:

Custom avatars are user-generated content and as such require authentication. If I understand correctly, avatars are being rendered (i.e. fetched) in a third-party application – so please make sure those requests are authenticated and with the right permissions to see the avatar.

Hope you have a great weekend!

Hey @ccasais, that’s right and makes absolute sense, however, the avatars are rendered in a third-party application, i.e. I just hand them the URL but I am not in control of how the avatars are rendered or how they are fetched.

I think the only way to work around this is to proxy the avatar request from the third-party system through our server where we can add authentication and return the image. Unfortunately, I assume we have to proxy all requests as there is no easy way to know if an avatar URL points to user-generated content or not.

@ccasais just had another look at this and did some more testing with some interesting results.

It seems project avatars in the REST API point to /secure/projectavatar?... and issue type avatars point to /secure/viewavatar?....

An interesting insight of this is that resolving custom issue type avatars via api.atlassian.com/ex/jira/[my-site-id]/secure/viewavatar?size=medium&avatarId=10929&avatarType=issuetype works without authentication.

If I use that same endpoint to try to load project avatars, it seems to default to the default project avatar but does not fail with a 403 as described above.

I am wondering what’s Atlassian’s view on this, considering that this behavior is inconsistent? Should custom avatars generally be public or should they be private? Having custom project avatars private and custom issue type avatars public does not really make sense to me.

1 Like

@ccasais just wanted to check back what you think about the above findings? Any chance that this could be fixed on Atlassian’s end?

1 Like

Hey @tbinna, so sorry for the delayed response, just wanted to give you an update on this:

Both project and issue type avatars should be private and we will be rolling out a patch to ensure that’s the case within the next few weeks. Please assume those URLs will require authentication and any requests coming from third-party apps will need to be proxied.

Hope this makes sense, and please let us know if you have any further questions! :slight_smile:

1 Like

Hey!

I added a suggestion for avatars to be public. I my case, an integrations such as Hubspot need to retrieve project icons, but currently we receive 403 Forbidden on all projects icon (because we use custom icon)

Go vote for the idea to be retained:
https://jira.atlassian.com/browse/JRACLOUD-78948Pouvez

Regards,

Hello. In my case, using forge app, when loading an avatar (custom image) like the following: “https://api.atlassian.com/ex/jira/c366c481-1c6e-43f4-bdb3-646803b6rot8/rest/api/2/universal_avatar/view/type/issuetype/avatar/10551?size=medium”.
And the following error occurs: Failed to load resource: the server responded with a status of 403 ()
{“errorMessages”:[“You do not have permission to view the avatar.”],“errors”:{}}
My scope in manifest.yml are:

app:
  id: ari:cloud:ecosystem::app/b25ec481-1c6e-43f4-bdb3-646803b6cao9
permissions:
  scopes:
    - read:avatar:jira
    - read:project.avatar:jira
    - read:jira-work

I don’t know how to solve it.
The problem is the same?
Any ideas?

1 Like

Have the same issue here.

Did you find a solution?

Same problem here, please ping me if a solution is found

Hi, this solved the problem for me:

permissions:
  external:
    images:
      - 'api.atlassian.com'

How do we authenticate such a request when using img src in a forge custom ui app?

still getting a 403 when using:

permissions:
external:
images:
- ‘api.atlassian.com

and - read:project.avatar:jira

What is meant by proxied? How does one do this with a forge custom ui app?

Here is what I know.

The docs found here https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-projects/#api-rest-api-3-project-search-get suggest that the response contains:

“avatarUrls”: {
“16x16”: “https://your-domain.atlassian.net/secure/projectavatar?size=xsmall&pid=10000”,
“24x24”: “https://your-domain.atlassian.net/secure/projectavatar?size=small&pid=10000”,
“32x32”: “https://your-domain.atlassian.net/secure/projectavatar?size=medium&pid=10000”,
“48x48”: “https://your-domain.atlassian.net/secure/projectavatar?size=large&pid=10000
},

What is actually being returned are urls like this:

https://api.atlassian.com/ex/jira/c1ade39a-8dca-4680-9286-86599120402c/rest/api/3/universal_avatar/view/type/project/avatar/10678?size=xsmall

These urls work for the built-in icons you can select in the project settings. But they do not work for custom icons you upload from your desktop. Instead a 403 is returned.

If you examine the image src attribute in the Jira Projects menu items, you will see something completely different to what is given in the docs. Instead the url’s look like this:

https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/project/avatar/10678?size=medium

My solution was to map the urls using the platform context’s siteUrl property, the rest api used in the Jira Projects menu, and the number extracted from the urls delivered in the response to https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-projects/#api-rest-api-3-project-search-get

This works, but I believe the response from https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-projects/#api-rest-api-3-project-search-get is incorrect url.

@robertbrower If you use the avatar icon URL in an image tag (<img src='...'>), the browser will add authentication if available for the domain. However, typically, there will not be any authentication for api.atlassian.com.
To proxy the request here means that you must somehow add authentication to it. For example, you could create a proxy that, when receiving a request for a certain icon on a certain URL (not api.atlassian.com), will fetch that icon from api.atlassian.com with authentication and return it. You can see an example of this in Gabriel’s post (which comes with its own challenges).

There are some posts suggesting replacing the api.atlassian.com domain of the avatar icon URL with the Jira site domain ([my-site].atlassian.net). This works if the user has permission to view the avatar icon (the browser will attach the authentication based on the current user session for [my-site].atlassian.net).

Please watch and vote on this issue: FRGE-680

@tbinna Thanks. I chose to use the 2nd approach which works well enough.