Fastest way to check whether the user is admin from app backend

Hi,
We are developing a Jira Cloud app and need to check whether the given user is admin for some of our REST endpoints. Currently, we are getting this information from GET /rest/api/2/mypermissions using AtlassianHostRestClients but it takes about 200-300 ms per request which is not acceptable for us. Is there a faster way to control user’s privileges?

Thanks in advance,
Berkay

2 Likes

If it’s just for deciding whether to display a page or not, you could use a condition “user_is_admin” in your atlassian-connect for that specific page.

Other than that, you could check out Jira expressions. I haven’t used the user one yet so I don’t know what properties are available, but it worked like a charm with issue properties, so it might be worthwile.

Cheers

2 Likes

The solution with Jira expression requires ACT_AS_USER scope on connect plugin, but I wonder if there is any alternative for simple READ scope plugins?

Unfortunatelly, permissions aren’t available in Jira expressions at the moment.

@Berkayztrk, you might try caching the permissions on your side?

Alternatively, if your endpoints are invoked from Jira’s UI callbacks, try inline conditions to make Jira send permissions that interest you in query parameters.

Thank you for the correction. Wasn’t sure about it, but now I know :slight_smile:

Thank you @kkercz and @ChupaCabra for your responses.

Our endpoints are indeed invoked from Jira’s UI and we have already defined user_is_admin condition in atlassian-connect.json file for the corresponding page. But we want to avoid non-admin users from accessing our endpoints via a third-party app like Postman. So we cannot trust any parameters that come from the client.

Should our endpoints be accessible only from Jira? If so, how can we achieve this?

Jira should be sending JWT tokens whenever your app is invoked from the UI. You just need to verify the token’s signature to know if the request comes from Jira. See Security for Connect apps

Hi @kkercz,

The problem here isn’t verifying if the request comes from the Jira instance.

Let’s say an app has an administration section that ables Jira Admins to save App Settings. Of course the page itself will be rendered upon atlassian connect conditions, using user_is_admin or what ever.
However, the endpoint that is used to save settings needs to verify user permissions before updating the settings.

Right now we are preventing this using the /rest/api/3/permissions/check but we would like to know if this is the best approach.

Thank you,
Paulo Alves.

2 Likes

I’m not sure I understand what the problem is. If you already have a condition on your page, it is guaranteed that it will be called only by users who satisfy the condition. You don’t need to recheck the conditions on your side.

I will try to give you the use case when validation of user permissions is required from an app API perspective.

  • The Jira Administrator goes to the Jira Apps Administration
  • The Jira Administrator navigates to the Settings page of an App
  • After the page is loaded (verified by the condition in the connect page), the user clicks on a button that requests the API of an App to save Administration Settings.

Any other Jira User (Non-Admin) can make a http request to that endpoint and save the App Settings - that’s why apps should verify user permissions on their API.

The problem here isn’t the endpoints used to load pages/modules, because those are secured by connect conditions.

Thank you,
Paulo Alves.

3 Likes

Got it, thanks.

I think something like generating a JWT token using the Javacsript API (AP.context.getToken()) on the Jira side page and then sending it to your API (that would have to verify it) could work.

Indeed, I just found this post that seems to perfectly describe the same use-case:

No, I think that isn’t the use case.

I believe @Berkayztrk is already sending the jwt while making the request, via the hbs rendered one or calling the AP.context.getToken().
Most of the apps are already using addon.checkValidToken() or similar to validate incoming requests. But there are some apps that need to make extra validations in order to perform some actions.

For example, if an app has configurations on Project Settings or Jira Apps Administration, only Jira Administrators or Project Administrators should be able to update them.
This is useful for preventing Broken Access Control vulnerabilities and I think it’s pretty common in most of Apps on the Atlassian Marketplace.

In our case, we’ve created a middleware that requests user permissions to Jira and only performs changes if the user is authorized to do it.
One solution would have some new middlewares on the atlassian-connect-express - addon.checkAdmin() where it would verify if the token is valid and the user is admin. I understand there are plenty of cases for it and making ace middlewares for this isn’t feasible.

I think a lot of apps should implement this and would be great if we could gather a general solution for this - like I said, we are using the /rest/api/3/permissions/check endpoint in almost every requests.

Cheers,
Paulo Alves.

@paulo.alves

Faster but less strict/safe solution would be to send encoded permissions to your hbs/page and send it back to the server with every AJAX request. Next, you could verify them on the server-side.

The advantage of that solution is that you can skip your middleware request to /rest/api/3/permissions/check.
The obvious downside is that the permissions you get with AJAX might not be up to date.

Cheers,
Jack

1 Like

Yes, we are sending and validating the JWT with every request but the problem here is that the JWT does not contain any information about the user’s authority. If we can add this information as a context parameter to the JWT - which is generated via AP.context.getToken() - then we can check that parameter on the server-side without sending an additional request to Jira. According to Context Parameters, it seems that this is not possible.

2 Likes

We had a similar problem. What we do is basically fetch the permissions asynchronously for known users and cache them. We have also implemented an active polling mechanism that refetches those known-user permissions on a given schedule. This way there is a very high chance the permissions are in cache and you do not sacrifice performance and you still do check them. The only problem is that those permissions can become stale. But you risk this either way with REST calls (by the time the response arrives to your server it can already be obsolete) so it’s really only a matter of how often you poll.

Cheers,
Bartek

Is someone at Atlassian able to raise this as a feature request? @kkercz, @dmorrow, @nmansilla

Specifically, the JWT token sent to app iframes should include an indication of admin access or not, corresponding to the permission required for a user to view an adminPage described in our descriptors.

That extra piece of information would remove the requirement for us to check each user’s permissions against Jira REST APIs before making requests to our services.

3 Likes

Hi @jbevan,

This seems like a sound idea. Thinking out loud, I guess we could add this to both the iframe URL token and the token returned by AP.context.getToken(). This way it is available to AJAX calls to app servers. Context tokens have a longer lifetime (15 minutes) than iframe tokens (3 minutes) so we’d need to think about that. Another concern relates to performance. I wonder if the information in the token could be determined by the module declaration so that only the required information is evaluated for each app iframe?

I can follow up with the Connect team.

Regards,
Dugald

2 Likes

Hi @jbevan,

I’ve created [AC-2529] - Ecosystem Jira for this.

Regards,
Dugald

1 Like

It looks like [AC-2529] - Ecosystem Jira won’t get implemented any time soon. Is that right @dmorrow?

Hi @jack,

It appears the development teams have other priorities so unfortunately there’s no estimate of when this may be implemented.

Regards,
Dugald

1 Like