Download attachment in JIRA Cloud using REST API for issue update events


I have a requirement to download attachment on the issue updated event and upload that file back to other system automatically. I guess this can be possible with AddOn creation. I would like to have this written in Python or Ruby. Please redirect to start with sample programs on it and your feasible inputs and solutions to implement. I still have queries on how REST APIs to be called as they are authorized links (meaning it requires authentication) in the addon and how this add-on can be triggered only when issue is updated event (meaning how to handle events). As you might have already understood with my post, I am very newbie to this program. :slight_smile :slight_smile:

Needed your assistance here.

The right approach depends on your needs to distribute what you’re building. If what you plan to build is so general purpose that other Atlassian customers might want it, then, yes, build an Atlassian Connect add-on. However, Atlassian Connect introduces a lot of overhead for authentication. If you only plan to use this utility for your own purposes, then Webhooks and REST APIs with Basic Authentication will be sufficient. The following sequence diagram explains the main steps.

In plain English, an administrator uses the JIRA UI to register a webhook to the URL of your integration service. When your integration service receives webhooks, it should follow the URLs provided in those payloads to navigate to the attachments for that issue. Issues can have multiple issues; hence, the for loop to get each one. The issue has fields.attachment[].content as the content for each attachment. You have to download each attachment as bytes, which you can pipe to your other system.

As long as your integrations service is behind the same firewall as JIRA, you don’t need any authentication on the webhook. But, coming back in to make the REST API request, you will need to authenticate. I suggest simple Basic authentication.

Hope that helps.

1 Like

Thank you for your feedback and valuable solution. I have thought of going with Webhooks, but for security constraints we can’t use basic authentication as It will be in plain text and resides in webhook system. Enabling with OAuth in Webhooks again requires separate application to be hosted I guess (apart from integration service). So thought of moving to Add-ons. Your suggestions on it and directions towards on Add-on development will also greatly helps (like samples and queries that I have in my previous post).

Best Regards

Sorry, my original answer wasn’t well considered. Your security concerns make complete sense for JIRA Cloud. And Atlassian Connect is the right answer. You can secure both Webhooks and REST API requests with JWT.

I have a partially completed tutorial that builds up an add-on that creates an issue using the REST API. And I have sample code for accepting a webhook. Both are Node.js applications, but I think the structure is pretty easy to understand as a model for Python or Ruby. The hardest part is calculating the Atlassian custom claim called QSH, but there are libraries for both Python and Ruby.

1 Like

Thanks you for the update and given kick start materials.

Let me try out and come back if needed any support. Thank you again.

I am able to satrt with this. Can you also please help in getting samples on how to use rest api calls in AddOn program with jwt authenticaion? node example is fine for me.

Sure try-jira-ping should get you pointed in the right direction.

Hi Ian,

I am sorry, I couldn’t able to understand well with try-jira-ping add-on. Could you describe more with steps to get authorized for APIs invoking?

Basically, when I installed the first addon (try-jira-webhooks) and while running it, I observed that we are validating whether the event is having authorization header or not, and then generating some encoded token and validating it on every event request with signature, claims set. So my question is, whatever that encrypted token generated and validated during the event call, can that be used for invoking rest apis using request method by setting Authorization bearer token header value.

Something like as below -

                            .get('', {
                                    'Authorization': 'bearer ' + jwttoken
                            .on('response', function (response) {

Will that work? Is that token valid for accessing simple jira issue id details? is that the same token or is it something related only to addon? if that is case, how to generate a token and use that for accessing rest apis like for downloading secure attachments? by the way, when I tried with above script, I am getting unauthorized response. similarly I tried with below step to sendjwt token as param in url string. but no luck.

                            .get('' + jwttoken)
                            .on('response', function (response) {

appreciate if you could help on this regard.

One reason we went with JWT for authentication is that it could be used in both directions. That is, your add-on can use JWT to talk to JIRA, and JIRA can use it to talk to your add-on. But there are some slight differences depending on direction. In try-jira-webhooks, the direction is from JIRA to your add-on, where your add-on needs to verify the JWT token to avoid leaking sensitive data (or just improperly responding to false webhooks).

I don’t think that JWT token can be used to make subsequent REST requests from your add-on because the QSH claim would not match. But, even if you could, I would recommend against it. It’s better to calculate your own JWT tokens because the time window may cause your add-on to make an expired request. That’s way try-jira-ping generates it’s own JWT. However, thanks for prompting me about this because I notice the README is all wrong. So sorry!

Out of curiosity, have you abandoned using Python or Ruby, in favor of JavaScript? If so, I think most developers in this community would agree that it’s far easier to handle all of this JWT stuff using Atlassian Connect Express. My examples are meant to illustrate the JWT concepts that are hidden by that framework, like the lifecycle callbacks and JWT signing. They’re still the right thing if you’re trying to replicate this in Python or Ruby.