Calling external API from forge app - CORS issue and is that "from URL" changing?

Hi guys,
I’m new at Forge apps and I’m creating this app that will call an endpoint to retrieve data.
I’m facing a CORS issue but I’m not sure what is the right URL to add in my server whitelist.
When I check the logs with the CORS issue I can see the following from URL https://[uuid].cdn.prod.atlassian.net

So, I have a few questions:

  1. What is this uuid? Is that changing? It will be a different value for every confluence instance that has the app installed?
  2. Is there a best practice to deal with those CORS issues? For example, should I do the request from the frontend resource or from the backend with the fetch from @forge/api?

I would like to avoid using wildcard for the uuid like that *.cdn.prod.atlassian.net, I wonder if there is another way to do it.

Best,
Joao

@JoaoVS,

The following addresses IP addresses and domains for allow listing like CORS:

Outgoing connections from forge apps dont come from those IP addresses, I have whitelisted everything there and still gets blocked.

Sorry to say this, but I’m not sure this is a sufficient answer.

If you were to allow CORS for e.g. *.cdn.prod.atlassian.net as in the original suggestion that means you’re opening your gates to every single app hosted at the Atlassian Forge, with no more granular control available. I don’t know if Atlassian reviews those (I’d assume not, because… well… scale) but if they aren’t reviewed then introducing malicious code is as easy as uploading an app to the forge.

Would it be possible to elaborate a bit on what Atlassian’s suggestion is here for their customers willing to implement CORS on their sites?

Addendum: I am aware that the linked article does not mention that specific entry; that’s because everything listed in your support page is even more permissive.

Welcome to the Atlassian developer community @GhostLyrics,

My post is the only resource I know where Atlassian addresses CORS. That said, I see from your response and that of @IanWorthington and @JoaoVS that something is missing when it comes to Forge. To get more published information (and/or a Forge feature), I’ll have to file a FRGE issue but I’m not entirely clear on how your Forge apps are interacting with CORS. Can you give me a little more information about the kinds of APIs you are trying to call from your Forge app? And if you had an ideal solution, what would that look like?

Hi Ian, I am trying to host a secure webservice endpoint that has IP whitelisting restrictions so that only my forge app can access it. This is a far more secure model than allowing any IP on the internet to access my endpoint.

To do this I would need to know what the IP address(es) of my forge app is coming from. I have tested and the list in that article does not seem to be accurate. So, whilst this is not strictly a CORS issue, my comment was relating to the outgoing IPs of forge apps being unknown and therefore not being able to IP block my webservice.

Hope that makes sense.

1 Like

CORS is one of the main blockers for us migrating a Connect app to Forge.

See here for details:

Unless the uu_id.cdn.prod.atlassian.net site specifically defines an iframe or something, (I am unclear how the uuids change or not) I think the straightforward answer would just be to define the CORS policy as

https://your_tenant.atlassian.net

In your instance, the CORS errors you are seeing are easy to misinterpret – the cdn urls come up because, the failure point is that the *.cdn.prod.atlassian.net (a lambda function) is not returning the required access headers to the client to indicate that the origin (the tenant url) is approved to execute cross-origin requests. But the lambda doesn’t actually have any input in this — it just propagated the missing header info from the resource endpoint.

AD 1.

What is this uuid? Is that changing?

In my experience the UUID doesn’t change between deployments. Once the app is installed, the ID stays the same and you can modify your CORS rules to allow traffic from Forge iframes (that’s how I’ve retrieved the UUID for my app).

The only exception to that is that if you’re using sandbox, and have a staging version of your app installed, then this one will have a different URL, so you need to account in your CORS for that too. But this is just different UUID per fresh installation, not new UUID every time.

The pain point is that this iframe URL/UUID isn’t known ahead of time, so if you need to bootstrap it without causing any disruptions (or shipping broken apps) you could probably install your app first with modules that return empty markup, note down iframe URL, modify your external backend CORS rules, then it should just work. Take this paragraph with some caution though, as our app is tailored just for our need, so I can’t guarantee the same will apply to “It will be a different value for every confluence instance that has the app installed?”.

AD 2.

Is there a best practice to deal with those CORS issues? For example, should I do the request from the frontend resource or from the backend with the fetch from @forge/api?

CORS should only apply to browser-sent requests. If you were to use fetch directly on the backend you should not face the CORS issues. You probably don’t need to use @forge/api if you intend to communicate with external APIs (since these packages are more directed towards usage with Atlassian APIs). In our case we use regular fetch to call our own external APIs just fine.