RFC-116: New link egress type for Forge apps

Project Summary

Introducing a new link egress type in the app manifest to allow static, user-initiated navigation to external URLs without triggering egress warnings or violating RoA status.

Publish: 27 October 2025

Discuss: 7 November 2025

Resolve: 18 November 2025

Problem

Currently, app developers are unable to provide users with direct links to external resources (such as documentation, tutorials, or videos) from within their apps without triggering egress warnings or losing RoA (Runs on Atlassian) status. This limitation impacts both developers and users as developers cannot easily guide users to helpful resources, and users may encounter unnecessary friction or warnings when navigating to legitimate external content. The inability to statically declare safe, non-data-egressing links also complicates compliance with regulatory and trust requirements, and may force developers to use less secure or less user-friendly workarounds. Addressing this now is important to support developer migration from Connect to Forge and end-user experience.

Proposed Solution

Forge proposes introducing a new link egress type in the app manifest. This would allow developers to declare a list of static, exact-match URLs that users can navigate to via explicit user actions (e.g., clicking a button that calls router.open()). Only URLs beginning with https (and potentially custom protocols, pending further investigation) would be permitted. No wildcards would be allowed; the manifest must specify the full URL, including protocol, domain, path, query parameters, and anchors.

The solution would involve:

  • Adding a links section under permissions in the manifest (e.g.permissions: links:).

  • Validating that URLs listed do not overlap with existing egress sections and are exact matches for those used in router.open.

  • Ensuring that only static links are permitted, with no dynamic generation or wildcards.

  • Updating developer documentation to clarify that these links should only be opened as a direct result of user interaction, and not via background scripts or unexpected navigation.

Users will be able to click on clearly defined links within apps to access external resources without encountering unnecessary warnings, provided the link matches exactly what is declared in the manifest.

Developers can statically declare safe external links in their manifest, improving productivity and reducing the need for workarounds. The manifest format is clear and avoids confusion with data egress permissions.

By restricting links to static, exact-match URLs and not treating them as data egress, Atlassian and apps will maintain user trust and RoA status. Risks such as phishing, domain impersonation, and redirection are mitigated by transparency and manifest validation.

This change enables more flexible app experiences while maintaining security and compliance. It avoids unnecessary friction for both developers and users, and supports the broader goal of configurable egress. The approach is designed to minimize dependencies on other teams and avoid major architectural changes.

Asks

While we would appreciate any feedback you have to this RFC, we’re especially interested in learning more about the scenarios where you would use our current solution, and what scenarios this solution would not meet your needs.

If you would like to provide feedback in a 1:1 conversation, please contact me here via DM!
Thank you and I’m looking forward to hearing back,
Vicky
Product Manager, Forge UI

10 Likes

Hi

These requirements will only allow non-public in-house developed apps to use the feature. If someone makes a 3rd party app that’s used by thousands of customers they can’t possibly be asked to add the ten thousands of unique exact links to the manifest that goes out to all of the customers using that app.

What about simply fixing the issue at its root?
If the platform (e.g Atlassian) is what decides what’s safe or not safe to visit why not add a “Settings”-functionality for that in the Atlassian platform itself.
That would allow Administrator users to put in their own list of whitelisted URLs used within their organization?

9 Likes

There was an older RFC about this: RFC-94: Configurable Egress and Remotes

3 Likes

We are maintaining > 100 links to our support docs in our product, from onboarding to detailed error message guides. So the proposed way would be unusable for us.

Neither can we have a manifest that large nor want any customer to review this - ever.Without patterns we won’t be able to use it. Like “https://support.yasoon.com/*”

Additionally question what I did not see in the RFC:
Would adding a new link trigger a major update?

16 Likes

Hi, can I ask what critical security hazard we are trying to prevent with an exact match white list of links. To me a browser opening a hyperlink (in a new tab) is Not data egress.
It is unclear why UX navigation to hyperlinks is being restricted at all?

As users can put any hyperlink they want into a Jira field or confluence document and navigate without restriction what is the point of preventing an app from doing the same thing?

But… if Atlassian is committed to blocking hyperlinks, then a few questions about how this proposal with static/exact match links would work?

As a vendor we have apps with context sensitive help navigation links. Let’s assume we have 30 well defined links to help desk/support articles or anchors for one app (all in the format https://support.myapp.com/articles/[ARTICLEID]/#anchor.)

What is the point of locking these 30 links into the manifest? Is the plan to show all 30 links to the Jira administrator who is installing the app and ask them to vet every single link? How could they possibly have the information to do that?
And assuming they do say yes, those 30 random links I know nothing about look okay, what happens when we need to add another help article link (#31) to the app?
Does adding that create another MAJOR version that requires every administrator in every customer site to personally assess the new link and install the new version before users can access that link.

Appreciate some background as to why all this link policing is even necessary.
If it is absolutely necessary, then at least put in wildcards so the admins can say yes, navigating to https://support.mysite.com/* is something I am willing to allow my users to go to from an app link. If I was building an app with dynamic links (e.g. links to youtube videos), I would want customers to be able to white list youtube.com/*.

Thank you for hearing our feedback
Chris

15 Likes

I think this is fundamentally the wrong approach (besides the fact that it is not workable in practice, as others have explained). It appears symptomatic of the fact that the “Runs on Atlassian” definition is constantly changing.

5 Likes

Hi Vicky.

I have a few questions:

  • Would there be a limit for the number of such links declared in the manifest? To give an example, we have about 35 unique documentation links in our app, not counting anchor tags.
  • Would the query parameters ordering impact the exact match detection ?
  • How would links count toward the total limit of modules in the manifest?
  • How does app versioning interact with this ? Would adding a link trigger a new major version ?
1 Like

Hi Vicky,

Thank you for publishing this RFC. Introducing a static links permission will streamline the user experience within our apps, making the customer journey easier and more intuitive.

A question regarding scope extension: Could this be extended to cover iframes (specifically, the frame-src Content Security Policy directive)?

We have a use case where we would like to display our comprehensive product documentation directly within the app using an iframe to ensure a seamless, inline experience. If the URLs declared under this new links egress type could also be allowed as valid frame sources, it would be very helpful for embedding trusted, static content without triggering warnings or policy issues related to frame-src.

We appreciate your work on this and look forward to seeing it implemented!

Best regards,
Ivan

2 Likes

The links we use for our customers depend on the instance where they are used. These links point to our Forge remote, and even while the remote is declared as egress, it seems the links trigger the annoying popup.

Would this proposal help?

1 Like

Hello,

This proposal will work for us, as we have around 10 links to our documentation or support portal in our apps.

But obviously, like the others commented, if changing any of these links trigger a major update, that is going to be very painful for everybody.

And what about the first time we add these link egress ? I currently have these links in the manifest in external.fetch.client. Does switching them into link will trigger a major update ?

1 Like

Agree with Chris, this seems over the top/heavy handed considering links can be added to Jira issues at will by users. Exact match URLs will simply not work, needs to use wildcards. Also please for the love of god don’t make modifications of this be a major version update.

6 Likes

We agree with most of what has been said in the previous responses.

Especially considering the fact that any user can add any links. Links can also be contained in attachments, e.g. PDFs, that even apps can upload.

Also, even if links are static, the content behind that link is not static. So I don’t see how this adds to security. Even if an admin reviews all links, possibly hundreds, this does not prevent redirects or changes to the content behind links. :man_shrugging:

4 Likes

We also have 70+ distinct help links in some apps, number growing. Would such a number be supported?

I also agree that it seems excessive if shipping a link fix requires admin approval to update the app to the newest version.

3 Likes

Based on the feedback from previous contributors, it seems that there is a disconnect between Atlassian’ desire to control data egress and the way vendors are using static links.

In essence, there are two ways in which data egress can happen with static links:

  • URL path (i.e. /some/path/with/sensitive/data)
  • Query string (i.e. /?variable=sensitiveData)

The query string problem can be fixed by Atlassian, simply by not allowing query strings. In the current RFC proposal, query string is allowed but it has to be declared in the manifest. I doubt that many vendors require the use of a fixed query string, and if they do, they can resolve this by using redirects in which the query string is appended.

My proposal would be for Atlassian to remove support of query string data in static links, and simply strip query strings when passed to router.open() or open the approval modal when a query string is added to the URL (regardless of whether the URL is listed in the manifest).

With regard to the path-based data egress: this is the reason why Atlassian requires fixed urls and will not support wildcards, regular expressions or domain-based links.

I doubt that this can be resolved by the original proposal of this RFC. Which means that for many vendors, they are stuck between a rock and a hard place:

  • do not declare the links and keep the annoying modal
  • declare the links and risk a major version requiring manual approval

I would like to propose an alternative solution, one which I doubt Atlassian will support, but one which might solve this issue:

  • Vendors must still declare static URLs in the manifest (that can only be used in router.open())
  • Administrator approval to static links only applies to the domain

This way, all links for domain A will need to be declared in the manifest, removing the ability to inject dynamic content and thus prevent data egress. This can be a PITA for vendors to maintain, but the reward is tangible: no more annoying modal and a shiny RoA badge!

In addition, it also removes the danger of triggering a manual approval step as the administrator has already agreed to allowing navigation to the domain. Adding a new domain will still trigger the manual approval.

Obviously, this implementation is more tricky for Atlassian as it will require updates to the automatic upgrade process and add some additional logic which is less binary than just “major version === manual approval”.

Another option would be to fix this on the manifest level:

link:
  - baseUrl: https://mydomain.com
    paths:
      - address: /path/to/resource/1
      - address: /path/to/resource/2
      - address: /some/different/path

Only adding additional top-level links (with different baseUrl) will trigger a major release. Adding new items to paths will constitute a minor release. This way, Atlassian does not need to change the manual approval logic.

Although I doubt Atlassian will consider this because of the additional engineering effort on her part, I think this would be a solution that works for all parties involved.

7 Likes

I assume that adding links to the allowlist requires a major update. (If not, why even bother to do all of this in the first place, because any vendor could then just list https://dangerous.evilsite.com at any time?)

I would say firmly that forcing yet more major updates on customers will be unhelpful to both the customers and vendors. This is because, in essence, customers never update, leading to customers getting left behind and broken app experiences.

Nobody wants to take on that additional cost just to add a hyperlink, so I imagine that most vendors will simply never update the list. As also mentioned by @PaulLunkenheimer , since vendors can easily update the content behind links anyway with HTTP redirects to anywhere, I do not understand what additional problems this allowlist is intended to solve.

Since links are not generally considered data egress, the main security reason I can see to exclude links from RoA is to prevent quasi-tabnapping attacks where (say) users click on a link and are taken to a Jira-like page that is not actually Jira.

In terms of the presumed security issues being addressed, what about scrapping the allowlist idea entirely and simply force all rendered links to open in a new browser tab/window? If there is a concern about exfiltration, perhaps also stripping off query parameters and/or enforcing a URL length limitation would be acceptable.

Forcing links to load in a different window makes it clearer to the user that they are going to a different site. You can even include an interstitial page, managed by Atlassian, that says “you are being redirected to https://whatever in (5…4…3…2…1…) seconds”. I suggest that any such interstitial page be informational and not “scary”, unlike the existing modal. (I think an interstitial page would be far more acceptable than the existing modal, but maybe other vendors can chime in.)

If this does not work for whatever reason, maybe Atlassian can also describe more precisely the problems it is trying to solve. It seems like the above would mostly cover the angles of “phishing, domain impersonation and redirection”.

3 Likes
  • As far as I remember, there is some limit to manifest size. If you have a lot of links that’s not going to help the problem.
  • Also interested in whether it’ll trigger an update. Even if it isn’t a major update it’s still way more work than just patching a broken link internally.
  • Why not just whitelist confluence-based documentation sites?
  • Updating the manifest every time you need to fix the link is a process nightmare.
  • Also interested why opening a link classifies as data egress.
  • Static links don’t allow for any sort of analytics like upgrades etc. RoA even allows for several analytics services so what’s the point of disabling them here?

I guess for our particular use case we have two types of links:

  • Links to the apps our apps integrate with, which we don’t know ahead of time but which are usually under one domain.
    • Of course these are not RoA anyway, but having the ability to define a wildcard would be helpful
    • Would be neat to get rid of the warning dialog, but that’s also not a huge deal.
  • Static Documentation links. These change between releases, but otherwise do not contain dynamic data
    • Would be great if these were not major updates requiring admin approval.
    • Our documentation is also not hosted in Confluence, so just allowlisting Confluence would be no good to us.

Our manifest is already generated via script, so collecting all links into one file and using that in both frontend generation and manifest generation should be easy enough for us. Annoying, of course, but doable.

But just to confirm, the current behavior with the warning dialog for undeclared links would continue working, right? Or is the idea to phase this out?

1 Like

Hi @VickyHu

We have few types of links:

  • support docs and portals
  • calendly to schedule support calls
  • tenants ask to setup guide links in their portals
  • we build integrations, so links to external objects like PRs, branches, pipelines etc. Which are dynamic.
  • links to self-hosted tenant systems and objects

I think you should not have so many limitations and permit the following:

  • an app can have a list of URLs (host names, subdomains etc) that tenant can or must provide
  • a tenant provide those
  • an app can get the value for a tenant and use it

We should be able to clear tell to the tenant what app needs and in which format, what are the defaults if any.

IMHO: Your proposed solution is not helpful.

Cheers,
Leo

2 Likes