How to request a macro body as an anonymous user?

Here’s our use case: we have a Connect app that needs to make a server-side request for a macro body using the /wiki/rest/api/content/{id}/history/{version}/macro/id/{macroId} REST API. We use the ACT_AS_USER scope in this app. Because of the nature of this app, we can’t get the macro body on the client side in this use case, we must fetch it from the server side.

In normal Confluence usage scenario, everything works as is.

However, when the Connect macro is rendered inside a JSD portal, the act-as-user approach fails for JSD portal users, since their user account id cannot be found on the target Confluence instance. The error is disallowed to impersonate the user because 'no valid active user exists'.

We have customers who deliberately set up the access to this Confluence content to be anonymously accessible. When they cannot access it through our macro, they find it confusing, as they should.

There are two conceivable workarounds to this:

  1. Fall back to using the app user instead of impersonation when impersonation fails. This is a terrible idea, however because the app user could potentially have access to restricted content, which would turn this macro into a privilege escalation vector.

  2. Fall back to making the REST API request anonymously. Unfortunately, most of the Confluence REST APIs (including this one) cannot be accessed without appropriate authorization credentials, even when the associated content is itself anonymously accessible :frowning: Attempting to use this approach yields a different error message: Current user not permitted to use Confluence

It seems like what I want is to be able to make a request using a JWT signed by our app with a subject that would be interpreted not as the app’s own user but rather as no user – the net result being to verify that the REST call is being performed by an authorized app but not in the context of any specific user.

As far as I can tell there is no safe way for an authorized Connect app to make a request for only anonymously-accessible Confluence content (that is, without risking possible privilege escalation when acting on behalf of an anonymous user). Is there an approach that I am missing?