Attachment on JSM request cannot be downloaded by customer (403 Forbidden)

Hi,

we encountered the following issue via our nightly run Jira/JSM REST API tests.
From the 20/21th January 2022 on, a JSM customer (a user with customer role) cannot download a particular attachment (i.e. get the attachment content) of a JSM request anymore, a “403 Forbidden” status is returned.
The JSM request and the respective attachment is created programmatically - by setting a valid request type, too - using the following API calls:

When the content URL (returned by the previous “create attachment” operation) is called on behalf of the very same customer (same user context), it gets rejected by a “403 Forbidden” response.

More interestingly, the list of the attachments can be retrieved by the same user via the get attachments for request call.

In addition, it’s worth to note that the content URL got back from the JSM somewhat differs from the pattern stated in the examples on the documentation page:
Instead of “https://your-domain.atlassian.net/servicedesk/customershim/secure/attachment/10001/log.txt”, we get “https://your-domain.atlassian.net/rest/servicedeskapi/request/59059/attachment/29948”.

What can be the reason for this? Has something changed in the API usage or the permissions required to access the attachment?

Thanks,
Marton

Hi

Not sure if this is the same, but…
We have started to see 403 when using the https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-customer/

(the requests are done as an app though (atlassianHostRestClients.authenticatedAsAddon())… not as a user)

Functionality was working fine for years…

UPDATE: Our problem was because of the missing ADMIN scope. And yes, this has been recently removed after the code review… what a fail

Alex

Hi @marton.kelemen,

Just letting you know that we are looking into this.

I have one question for you: when you say the following, can you tell us more about which request is performed here? If you have a code snippet for us to try to reproduce it, that would be very helpful.

When the content URL (returned by the previous “create attachment” operation) is called on behalf of the very same customer (same user context), it gets rejected by a “403 Forbidden” response.

Thanks,
Caterina

Hi @marton.kelemen. My name is Leonardo (feel free to call me Leo). I’m a developer at Atlassian.
We’ve made some changes to this endpoint to improve security and enforce new OAuth scopes.
Can you confirm if your requests is using the scopes read:servicedesk-request, read:request.attachment:jira-service-management and read:user:jira, please?

As for the customer account, is the customer account the same account used for creating and attaching the issue? If the issue is on a comment, can you confirm if the user has access to read that comment?

Thanks

Hi Leo @LeonardoDiniz ,

first of all, thank you for the prompt feedback (@ccurti and @sash011 , for you, too).

I’ve just revised the situation and figured out the real workflow in our app and therefore I need to amend my original description. Sorry for the initial inaccuracies.

  1. The first two steps and the respective REST requests (create customer request, add attachments to it) are executed on behalf of the user, i.e. the JSM customer.
  2. The 3rd reuest - that is, the one that tries to download one of the attachments and fails - is executed in name of the add-on.

Some general info:

  • our app uses JWT tokens for authentication (exceptionally), so OAuth2 scopes should not play a role here
  • our app has the following app scopes specified in its atlassian-connect.json descriptor: "READ", "WRITE", "ADMIN", "ACT_AS_USER", "ACCESS_EMAIL_ADDRESSES"
  • request type applied in the failing unit test: “Ask a question”

atlassian-connect-json-excerpt

In regard to the information above, I think, the app should be able to download practically any attachment of any issue/customer request, regardless, who and how created/uploaded it. And this approach worked for us till 20th January. [One reason to do so - i.e. to act on behalf of the app - is to ensure that the attachment will be downloaded in any use case, regardless which user initiated the action.]
However, after a minor change in the source code I also made an attempt with the other option, namely when we execute the download request on behalf of the user that uploaded it. And it resulted in a response with status code 401 and with a message "Client must be authenticated to access this resource.", which sounds pretty weird knowing that the same user created the customer request and the attachments in the same session.

When executing the request as addon-user (the full response can be inspected in the JSM-API_failing_test_log.txt attached):

[warn] c.m.c.j.j.s.JIRAServiceImpl - Could not download attachment, status: 403, url: https://metainf-stage.atlassian.net/rest/servicedeskapi/request/59321/attachment/30044, body:

When executing the request on behalf of a real user:

[warn] c.m.c.j.j.s.JIRAServiceImpl - Could not download attachment, status: 401, url: https://metainf-stage.atlassian.net/rest/servicedeskapi/request/59323/attachment/30048, body: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>401Client must be authenticated to access this resource.

To summarize my findings, we use JWT tokens and we do execute REST API request either directly on behalf of the app or on behalf of a user (for thre latter one, we retrieve the JWT token via the JwtBearerAccessTokenProvider.getAccessToken(AcHost acHost, String accountId) method provided by the Play framework). So, is it possible at all to download any attachment on behalf of the app after these security changes?

Unfortunately, there is no public API endpoint defined for retrieving an attachment content (at least not indicated in the official JSM Cloud API documentation), so we cannot extrapolate, which app/user scopes may be required to do this now, or what have changed.

I hope, this info will help you.

Thanks for your further support and I’m looking forward to hearing from you,
Marton

JSM-API_failing_test_log.txt (68.2 KB)

Thanks @marton.kelemen
It does help. I’ll investigate it further and get back to you ASAP.

Meanwhile, I’ll revert the changes for metainf-stage.atlassian.net so your tests stop failing.

Sorry for any inconvenience.

Hi @LeonardoDiniz,

thank you for the quick reply again.
I think, it’s better not to change the settings on metainf-stage.atlassian.net, since it is our staging environment only. It’ better to see the actual situation there and be able to experiment with/adapt to changes. Btw, we could disable the failing test case individually on the stage server, so it does not re-appear every day in our CI/CD test reports. :wink:
What would be more useful and more welcome is to ensure the correct operation at our clients (on production sites), though. But I assume, it would require to revert these settings on each site, where our addon using this feature is installed, which is not possible of course…

Thanks,
Marton

I could find an error on our end and a fix will be deployed soon @marton.kelemen. It won’t require any changes on your end. As long as you follow the link returned in the API it should be fine.

Once I get it deployed in production I’ll reach out to you here to see if you’re having any problems.

Thanks for your help

1 Like

Hi @LeonardoDiniz,

sounds great, thank you for your help and mediation.
Keep me informed about any updates.

Best,
Marton

@marton.kelemen the bug fix was deployed in production and the URL’s /rest/servicedeskapi/request/{requestId}/attachment/{attachmentId}” should be working normally for you. Could you please run your tests on metainf-stage.atlassian.net and let me know how it goes? Thanks

Hi @LeonardoDiniz,

yes, it seems to be fixed, our test case now passes again.
Thank you for your help again.

Best regards,
Marton

Glad to hear it’s working now.
THANK YOU for reporting it and helping us get it right.
Once again, sorry for any trouble it might’ve caused.
Kind regards,
Leo

1 Like