Action Required - Atlassian Connect installation lifecycle security improvements

@HanjooSong , thank you. You are right, i was inspecting the body, not the header. Seems to work!

In regards to your statement that updating config.json does the same thing, is it compliant to not to update atlassian-connect.json but config.json instead with signed-install=true in order to prevent the app from being versioned up?

Are Jira Data Centre addons affected by this security vulnerability?

Hi @HanjooSong,
I’m using ACE 7.4.4 and have “signed-install”: true set in the atlassian-connect.json. Installation works fine in the old Confluence instances. Today a created a new Confluence instance and tried to install the app, but it fails with the following error:
Authentication verification error (401): JWT claim did not contain the correct audience (aud) claim
Looks like some our customers already failed to install the app because of this issue.
Also, could you update the post with the info about addon.authenticateInstall() for /installed and /uninstalled callbacks?

I’m currently implementing this change for our custom jwt auth. handling. Works good so far. I stumbled across that the Atlassian backend now sends a new sharedSecret for every subsequent installation. This is new isn’t it? Actually pretty cool because this allows to recover from lost sharedSecrets in dev-mode. Can you confirm that @HanjooSong ?

Hi @akhaneev ,
Do you have localBaseUrl configured in config.json of your ACE app like below and does it match the baseUrl from your atlassian-connect.json?

  "product": "jira",
  "production": {
    "localBaseUrl": "https://app.base.url",  # This is used to verify 'audience' claim

Or if your app supports multiple baseUrls, you can add your base Url to allowedBaseUrls field, please have a look at comment I linked below.

I would love to keep the main announcement post updated but unfortunately there are some limits on editing the main content. For the purpose of documentations and guidelines, we will try to find better place to accomodate this in future so that we can always have the updated main content.

Hi @JulianWolf
That is the case for dev-mode only. It is not a new feature, and when your app gets published on the marketplace, it will start getting a single shared secret for all installs(including subsequent install) as it was before.
Coincidently, we actually were planning to provide unique shared secret per installs in close future. Here is the announcement that I’ve made just a moment ago which summarises this plan.

FYI, there is no additional actions required as long as your app works fine in dev-mode for multiple installs in different tenants.

1 Like

Hi @karanjagdish , this is only for jira-cloud and confluence-cloud apps.

1 Like

The app will always create a new version, regardless of the config file you choose to opt-in to this feature. But having it in config.json AND defaulting the behaviour to opt-in caused confusions. As a result it ended up creating new versions in Marketplace which may have not been the intention of the app developers.

Hi @HanjooSong, please correct me if I am wrong but doesn’t Jira Server/Data Center Addon installation hooks work the same way as the Cloud Addon install prior to the security changes highlighted here?

Could you please let me know if the same vulnerabilities (DoS and MitM) affecting the Cloud affect Data Centre/Server addons with the technical reasons as to why yes or no?

Hi @HanjooSong,
Thank you for your help. URLs seem to be case-sensitive.

Hi @HanjooSong
For us, MPAC ended up creating new version of the app even after this setting.

What do you mean by “your app descriptor did not change by setting "signed-install" field under "apiMigrations" section.”

And also, subsequent installations are failing with 401. How do we fix the 401’s?

We use ACE and upgraded to 7.4.0 and updated the descriptor to use signed-install

I wish this could have been more straight forward.

Looking forward to your response.


Hi @HanjooSong!

I don’t get @palbecki’s error myself, but it seems that the symmetric auth is still enabled even if I set the property. Looking at JwtAuthenticationFilter, it looks like the property it’s checking AtlassianConnectProperties.isAllowSymmetricAuthInstallCallback(), which I think would convert to atlassian.connect.allow-symmetric-auth-install-callback in a .properties file.

Does that sound right? Is it going to be stable from now on?

Correct, that property is to force asymmetric install callbacks only. The fallback to symmetric install hook is in place to make sure the apps does not loose any installations if anything goes wrong with this feature from our end.
In the future, a new version of ACSB will remove allow-symmetric-auth-install-callback and default to use symmetric install callback, this will happen right before the enforcement of this feature.

Hi @lavakumar.dukanam ,
MPAC creates new version when it finds any difference in the descriptor file.
If you are referring to your announcer-jira addon, I’ve checked that the most recent version introduced a signed-install field, and this has created a new version in MPAC as expected.
I think the guideline that made you confusing was for apps upgrading from 7.1.5 which I assume it is not for your case.

Also, could you please elaborate a bit more about 401 error you are getting for more further investigation? Such as attempted time and the product url, error message from your server will be helpful. Thanks!

@HanjooSong You’re right, i’m referring to announcer-jira addon.

Attempted time:
Aug 18 13:49:06
Product url:
Are you looking for descriptor-url?

After the upgrade the app is unable to authenticate and resulted in throwing
{} Authentication verification error (401): Could not lookup stored client data for XXX

uninstalling and subsequent installations are failing with the below error.
{} Authentication verification error (500): Could not lookup stored client data for XXX


Hi @HanjooSong - Any update on this issue?

Hi @lavakumar.dukanam , May I ask what type of storage you are using? I see that the error message you posted indicates that it failed to query the app data from your storage.
You might also have more detail error stack trace from your server logs.

Hi @HanjooSong - we use postgres.
Nothing much on the logs. This is happening only after adding signed-install attribute to descriptor.
See the sample error log

Hi @lavakumar.dukanam
I can see from our end that, all installations(upgrades) were successful on 11th after the version up including However, on 18th, I see that there were many attempts to re-install, and these requests failed to receive a successful response from your app server.
Could you see what may have been changed from your app’s side between those time(Specially related to the db connection)?
Also, if the problem persists and need more help, please create a devhelp ticket with any information that may help with the investigation. Let me know the ticket number, so that I can follow up from there. Thanks!

Hi @HanjooSong

  1. Changes should only be made to the install hook? In this step, only the install hook is specified, but in the documentation above you also write about the unistall hook.
  1. expectedIssuer is the iss parameter from the jwt token?
  1. It turns out that all the required attributes listed below that are contained in the jwt token must be checked in the install hook?
  • iss (mandatory)
  • iat (mandatory)
  • exp (mandatory)
  • qsh (mandatory)