Migrating from Connect lifecycle to Forge events - how to preserve clientKey-based architecture?

Hey everyone,

I’m working on migrating our Jira Connect app to adopt Forge (ahead of the Q4 2026 deadline) and I’ve hit a pretty significant roadblock. Would love to hear if anyone else has dealt with this.

The situation:

  • We have customers running our Connect app in production
  • Our entire backend is an ACSB (Atlassian Connect Spring Boot) application, built around Connect’s clientKey as the primary identifier (database keys, API endpoints, logging, you name it)
  • I successfully migrated the webhooks (issue created/modified/deleted) to Forge triggers with @ForgeRemote(associateConnect = true) - those work great
  • Now I’m trying to migrate the /installed lifecycle event to Forge’s avi:forge:installed:app

The problem:
When the Forge installed event fires, I’m getting a null value in AtlassianHostUser.
I think this happens because @ForgeRemote(associateConnect = true) tries to look up an existing Connect installation, but at installation time, that record doesn’t exist yet.

The issue webhooks work fine because they fire after installation completes, so the Connect record already exists.

I know Forge Invocation Tokens (FIT) don’t contain a client key.
For existing installations it’s ok since @ForgeRemote(associateConnect=true) handles the mapping and retrieves the AtlassianHost successfully. But, new installations don’t have clientKeys.

My question:
Has anyone successfully migrated from Connect’s /installed lifecycle to Forge’s avi:forge:installed:app event while maintaining a clientId/AtlassianHost-based application?

Some options I’m considering:

  1. Extract the clientKey somehow from the Forge context (is this even possible?)
  2. Keep relying on Connect’s /installed event
  3. Go big and refactor the entire app to use installationId instead of clientKey, or at least a new flow for users without clientKeys. Even with ACSB’s easy mapping, all our Jira api usage uses AtlassianHost and will need to be replaced.

Option 3 seems like the “right” long-term answer, but it’s a massive undertaking with significant risk given our customer base.

Has anyone dealt with this? What’s the recommended migration path for ACSB apps that are heavily invested in clientKey as an identifier?

Thanks in advance for any insights!

1 Like

When we migrated we decided between the installationId and the cloudId and for us the cloudId fit us better (it exists across install/uninstalls)

We created a cloudIdMapping table where the clientKey and cloudId can be looked up. cloudId exists in the FIT token. Then we had the /installed hook populate the table for a while. When we switched to Forge remote proper - we just started to use that table to lookup what the clientKey was and if it wasn’t there - we use the cloudId.

Depending on your timeline - you might need to populate that type of mapping ahead of time – the installation payload that’s sent down has the cloudId nowadays and if I recall - there are some non-official api that can give you the cloudId as well.

Don’t know if it will work for you - but that’s what we did…

/Daniel

1 Like

Thanks Daniel. Did you also use ACSB? By "you might need to populate that type of mapping ahead of time" you mean publish the Forge successor and letting ACSB populate AtlassianHostMapping table?

And did you fully migrate from ACSB to plain Forge remote? Or is it possible to keep using ACSB with AtlassianHost connector to Jira Api even after migrating to cloudId/installationId instead of clientId?

We were using atlassian-connect-express. So we shipped a version that had the /install hook and populated the table whenever we got that. The easiest way to get that btw is to update the atlassian connect descriptor since that triggers a reinstallation.

I don’t have experience with ACSB - but with Forge and the FIT tokens you get the apiBaseUrl and such through the FIT token so you don’t really need to store anything for the rest api’s.

Thanks. I will try to create a separate path for Jira REST in the Forge flow, and see if I can rely solely on the installationId.
Then after the full migration the next step would be to discard the AtlassianHost flow once all the users already have installationIds.

If you have any other insights that might help please feel free to keep sharing, it help a lot. Or if anyone else of course, I would be happy to hear.

Thank you, Roy.