Forge requires CORS headers on API requests served from a Connect-ish backend.
Most cases are covered by the wildcard origins: *.atlassian.com, *.atlassian.net, *.jira.com, *.atlassian-us-gov-mod.com, and *.atlassian-us-gov-mod.net.
However, some instances live at custom domains.
It is neither safe nor sustainable to have a policy which:
- Makes it impossible for any custom domain trial to work turnkey UNLESS unsafe CORS headers are adopted
- Given a reactive policy of adding origins as demanded, leaks the existence of users to each other through the CORS header
Until I confirmed by inspecting Origin headers, I suspected that forge bridge was issuing requests from a reasonable origin like *.paas.atlassian.com - but is actually issuing them from the instance subdomain.
We just ran into this issue with our Forge app as well.
In our case the solution was to get the displayUrl property from https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/serverInfo during the app installation lifecycle callback, and store that value in our backend database. Then in our API when we encounter an “outside of Atlassian” origin in a request that would otherwise fail our validation, we check it against the set of displayUrls from our installed clients. If matched, provide the necessary CORS custom response headers, else reject.
Fairly straightforward and no ongoing maintenance required.
This is the solution we’ve considered too. It’s not great to have to make an extra database call on every REST request. (Though it’s stable enough that a cache is a good candidate)
Yep. We have matches and failures kept in Redis to minimize impact. Right now we don’t have a lot of Forge clients with custom domains, so caching the failures is more important for us, but it could change in the future.