RFC-69: Custom Forge app events

RFCs are a way for Atlassian to share what we’re working on with our valued developer community.

It’s a document for building shared understanding of a topic. It expresses a technical solution, but can also communicate how it should be built or even document standards. The most important aspect of an RFC is that a written specification facilitates feedback and drives consensus. It is not a tool for approving or committing to ideas, but more so a collaborative practice to shape an idea and to find serious flaws early.

Please respect our community guidelines: keep it welcoming and safe by commenting on the idea not the people (especially the author); keep it tidy by keeping on topic; empower the community by keeping comments constructive. Thanks!

Summary of Project:

We would like to gather interest in a new feature allowing Forge apps to emit events that can be received by other apps. It would integrate seamlessly with the existing trigger module.

  • Publish: Oct 15, 2024
  • Discuss: Nov 1, 2024
  • Resolve: Dec 6, 2024

Problem

Currently, Forge apps cannot communicate between themselves. This can make it harder to build integrations between apps developed by the same or different Marketplace vendors.

Today, Forge apps can already receive events from Atlassian products by using the trigger module.

The trigger Forge module can listen to a limited set of events, such as avi:jira:created:issue or avi:confluence:created:page, but apps cannot directly send events to other apps to inform them that something has happened.

Proposed Solution

We would like to introduce a new Forge module that apps can use to indicate their intent to send events. The module would look like this:

customAppEvent:
  - key: my-custom-event-module
    eventKey: my-custom-event-key
    name: My Custom Event Name

Apps declaring this module would be able to use it like so:

import { customAppEvents } from '@forge/customappevents';

customAppEvents.emit(my-custom-event-key);

Other apps would then be able to process this event by using the usual trigger module with a new event type avi:forge:custom:app:event:

trigger:
    - key: customEvent-trigger
      function: run
      events:
        - avi:forge:custom:app:event
      filter:
        eventKeys:
          - my-custom-event-key
export async function run(originatingApp, event, context) {
  // 'event' would be {eventKey: "my-custom-event-key"}
}

Asks

While we would appreciate any reactions you have to this RFC (even if it’s simply giving it a supportive “Agree, no serious flaws”), we’re especially interested in learning more about:

  • Would your apps benefit from such a feature? How would you use it?
  • Do you have any concerns about privacy or any other feedback?
15 Likes

Good idea. We’d use this to get rid of the communication between our apps over webtriggers and hence avoid being categorized as a Forge app with egress. An example for that is our app AutoPage.

A problem that I see with the suggested approach is, that it will be easy to get naming clashes. Imagine, two vendors come up with a name like ‘page-updated’ event. Does the subscriber then receive the events from both originating apps and has to check for the originatingApp?

Also it must be made clear that everyone can receive events (potentially containing sensitive data) when working with that API. I guess, for internal purposes, the Async Events API must be used, right?

7 Likes

Looking forward to having this feature, but like others have already mentioned, It would be good to have some guidelines on what event names should be or some sort of namespacing to avoid conflicts between vendors using the same event names.

5 Likes

For each event, an explicit allowlist of App IDs (maybe including a wildcard for indicating all apps) would make me (and potentially Jira admins) more comfortable as data could be egressed via these events. Edit: I guess it doesn’t count as egress because its all in Forge right? And any apps installed have already had their permissions approved by the Jira admins…

It also feels like event identifiers should be namespaced automatically within Forge using the App ID to avoid the inevitable conflicts, or even some kind of malicious event shadowing mechanism.

11 Likes

Since we have two apps in the Marketplace that work closely together, we see great value in using custom events to move toward a more integrated bundling solution.

This would involve triggering custom events regularly (e.g., if the other app has a valid license).

I also agree with others that the source app might have control over which potential receivers can handle these events.

1 Like

This is a good idea, and we would support this, we have multiple apps which could make use of this, and if we can use it across our portfolio of apps, even better.

2 Likes

I can see a lot of utility in having this feature. Would it be possible for the same app installed on different instances to talk to each other? This would be helpful in enterprise scenarios where multiple Atlassian sites sit underneath an organisation and each of those sites have installed our app.

1 Like

It would be great if you put more effort into improving already existing product forge product events to equalize them with atlassian connect product events

1 Like

This looks promising!
Could these APIs also be used to send events between two custom UI iframes belonging to different apps? Use case (simplified) is one app opening a UI of a second app, and sending some data along to pre-fill form fields.

Related to that: Can such a trigger module open a custom UI if if there is currently no UI displayed by the app owning the trigger?

1 Like

I think this would be a great addition. We already have a few ideas on how this could help bridge some gaps in inter-app communication.

As already stated in the thread, optionally limiting what app can trigger these events would be ideal.

1 Like

Thank you for the feedback @JulianWolf !

In order to avoid having to check (in most cases) for the originating app, I can think of two solutions.

The easiest way to avoid this issue would be to include app ARIs in the filter of the receiving app:

trigger:
    - key: customEvent-trigger
      function: run
      events:
        - avi:forge:custom:app:event
      filter:
        eventKeys:
          - ari:cloud:ecosystem::app/{app-id}/my-custom-event-key

This would probably eliminate the problem altogether.

Alternatively, we could possibly support an allowlist of apps that can receive the events, declared by the app that emits them:

customAppEvent:
  - key: my-custom-event-module
    eventKey: my-custom-event-key
    name: My Custom Event Name
    allowedRecipients:
      - ari:cloud:ecosystem::app/{allowed-app-id-1}
      - ari:cloud:ecosystem::app/{allowed-app-id-2}

There are possible cons with this approach though. Apps won’t be able to receive such events unless specifically allow-listed. And of course, if your app is allow-listed by different apps for events having the same key, it would still be necessary to check for the originating app.

On the other hand, having an allowlist would likely alleviate possible problems with sensitive data being shared.

3 Likes

Hi @jbevan , thank you for the feedback!
I agree that an allowlist could be a desired feature; see also my response to @JulianWolf here. I can think of allowing a wildcard there as well, such as ari:cloud:ecosystem::app/*

1 Like

I suggest offering allowedRecipients when needed. Starting with the first approach that just avoids naming clashes sounds fine to me. Things to consider:

  • Are these events considered egress or do they endanger the Forge Native status of an app? This should not be the case at least as long as all consumers are Forge Native, too.

  • From a partner perspective, I suggest that changes to the mentioned sections in the manifest.yml do not trigger a major update. From a security perspective, this might be necessary.

4 Likes

Hi @rcsr,
Currently we are not planning to allow cross-instance communication between apps in the context of this proposed feature.

Hi @Alexandr, what missing features or events are you referring to specifically?

Hi @jens ,
Currently we are not planning to allow communication between iframes in the context of this proposed feature, nor allowing data to be passed along due to privacy concerns, at least in the first iteration.

For example, the Delete issue event payload is more rich for the AC app than for the forge

1 Like

Hi @JulianWolf ,

Are these events considered egress or do they endanger the Forge Native status of an app? This should not be the case at least as long as all consumers are Forge Native, too.

As these events, at the moment, only contain keys, they don’t impact Runs on Atlassian/Forge Native. And if we go with the allowlist of consumers, then you are correct it shouldn’t impact Runs on Atlassian if all consumers are also RoA.

3 Likes

We have 3 apps in the marketplace and customers usually use atleast two of them in conjunction. Ability to interact with the other apps is going to be very beneficial for us. We currently use post functions or webhooks to achieve limited interactions. This feature will make it very clean.

1 Like

As this proposal is only considering event keys, will you be adding custom event data down the line? This would open up a lot more opportunities, especially for apps installed on different products. As far as I know it is not possible to access the product API from another product than the one the app is installed on. Ex. a confluence app can not access the Jira product API and vice versa. Letting us send parts of this data through events would be very appreciated.