Run the cloud code on behalf of ServerCodeUser

Hi Boris,

I just applied the changes. Here’s what I see:

An unauthenticated user cannot get restaurants by using the direct API:

A logged-in user with the Restaurant role cannot get restaurants by using the direct API:

An unauthenticated user cannot get data from the API service:

A logged-in user with the Restaurant role can invoke the API and get the data:

Hope this is what you wanted. Please let me know and I will provide a summary describing the changes.

Mark

@mark-piller,
I’m very sorry, but I’m confused. Could you please configure one more time?
Please notice, the direct API should be not available with any API key, including iOS, Android, etc. (except the Server Code key).
Perhaps, I made wrong changes because I’m still able to view the data


Thanks in advance!

Try now.

Boris Velvetech
The main idea is you have to add GRANT permission for Authenticated user for specific table or on a top level.

Hi, @oleg-vyalyh and @mark-piller!
Thank you for the reply and your help. At the first glance, the solution looks like what we need.
But the resolution is not obvious. In the article prepared by your team in 2019 you suggested to hack the SDK or do not sent the “user-token” in case of API requests. I think the article should be updated… Could you please explain how it works and why granted permission for the specific role and for the authenticated user allows to use direct calls within server-side code, but closes the same behaviour for other security keys?
I let you know if find any more troubles (I want to test the same behaviour with the “Files” module instead of DB queries).
Thank you!

Hi @oleg-vyalyh and @mark-piller!
I decided to start from scratch and stuck again. I created a new table and implemented a simple service, that returns the array with the data of that table.
I tried to configure permissions (Auth role has access to retrieve the data, the Customer role has access to retrieve the data).
The problem occurs when “Customer” role uses the direct DB API. The response contains the data


The cloud code returns the expected result:

The table has the following permission configuration:

If I deny access for the Customer role, the cloud code returns empty response, and Direct access continues working.
If I deny access for the particular user (test4@test.com in the current example), the response contains no data in any case.

What needs to be changed to close direct access to the database?
Please use test4@test.com/123123qwe user for testing purposes if need it.

Thank you!

Hello @Boris_Velvetech

Let’s start with which users or roles you want to keep access to the database?

By prioritizing permissions, the permission for a role will take precedence over the permission for an api key. Therefore, you can disable the Retrieve operation for the CloudCode role at the top level Manage> Security Roles.
At the same level you must allow the “Retrieve” operation for the Customer role. In this way, only authorized users with the Customer role will be able to access table.

Regards,
Inna

Hello, @Inna_Shkolnaya!

I want to keep direct access to the database for the CloudCode only.
I want to restrict direct access for all roles except the CloudCode. I.e. a frontend app (mobile) with the role “Customer” should be able to trigger a custom service and retrieve the result, but should not be able to use a direct API from the SDK to get data from the DB/file storage/etc.

Thanks.

Hello, @Inna_Shkolnaya !
Do you have any updates on this?
In other words, I want to allow executing all available API (e.g. DB queries) in CloudCode functions when a client (“Customer” role) triggers the implemented service methods.
And this is only the way the customer should has access to (using implemented REST API in the CloudCode).
Thanks!

@mark-piller, hello!
Could you take a look at this please?: Run the cloud code on behalf of ServerCodeUser - #18 by Boris_Velvetech
I believe, your set up was working because of the internal logic (there are no restaurants for some users based on the internal BL)
My last example is the simple service, querying the table from the DB. And I can’t configure the settings, where the result returns on behalf of the “Customer” role through the custom service API (CloudCode), but returns nothing via the direct DB access.
Thanks!

Hello @Boris_Velvetech

Try to deny permission for the custom roles




Hi, @vladimir-upirov,
I have already tried such configuration multiple times.
In that case, both: direct API and CloudeCode return empty response.





What is the user context on your third screenshot? Is it the same with the user you denied access on “User Permission” tab?
Thanks.

Hello @Boris_Velvetech,

Firstly, please restrict the CloudCode API key usage. It should be used only for the Business Logic calls, it’s not public and it’s not secured when users have access to it.

Secondly, please take a look at the permissions priority. The DENIED permission for the user is stronger than the ACCESS for the API key.

Maybe this article also could be useful.

Regards,
Olha

Hi @olhadanylova,
Your response doesn’t cover my question. I want to implement the Business Logic using ClodeCode only. Imagine, we have a “general” and simple web application with backend (node.js/.net core/spring/etc) and the frontend part (angular/vue/react). The server side has access to any resources like DB/Queue instance/File storage. I agree, that access can be restricted via additional validators/hosting configuration and so on. But the frontend part can’t query the DB directly, right? How to replicate the same logic?
I want to allow for my frontend executing of the API implemented in a custom service, and that API should be able to query the DB or the file storage under ther hood. But if I deny access for some role, my cloude code can’t retrieve a response from the DB because of the custom role context.


The article you provided is what I was starting from. Please review my first comment in the ticket: Run the cloud code on behalf of ServerCodeUser
And that article suggests to hack the SDK to not send the user token, that smells bad:

This said, depending on the SDK you use, you can hack it to not send the user-token from the specific call in Cloud Code and thus the flow will become the same as in the case described above. And if you use REST API to make calls from Cloud Code, it’s even simpler — just do not send the user-token header.

How to identify a user if the frontend doesn’t send a token? Why do I need to “hack” the SDK if I want to reach the most basic behaviour?
Thanks!

Hello, @olhadanylova!
Is my previous comment clear? Do you have any solutions except suggested in the article?
Thanks!

Hello Boris,

I will try to figure out the question and answer you tomorrow during the working day.
Thank you for your patience!

Regards,
Stanislaw

Thank you,
I will be waiting for your response!

Hello @Boris_Velvetech,

I have invited you to my app:
https://develop.backendless.com/app/PermissionsDemo

There I tried to configure what you are trying to achieve.
There are table Restaurants with a few objects in it.
There is one user (customer@test.com, password: secret).
There is a custom role Customer assigned to that user.
There is a second user (not-customer@test.com, password: secret), without any custom role.
There is an API Service that retrieves the records from the Restaurants table.

Please note that the permissions for the service itself have also been configured (in addition to the global and table permissions).

Please play around with it and let me know if this is what you are looking for, and if not - what is not working as you would expect in this app.
Thank you!

Regards,
Stanislaw

Thank you for the demo!
I will definitely review your example on Monday.
I briefly look at the settings on the table level.
Is that correct, that you denied permission at the role level:


but grant access for the particular user (i.e. we will need to grant access through the code for every created user):

Thanks!

Is that correct, that you denied permission at the role level, but grant access for the particular user (i.e. we will need to grant access through the code for every created user)

No, I didn’t change user permissions at all (and you will not need to).
The gray colors of X/V mean that permission is inherited (it’s not set explicitly, but inherits parent configuration).
In this case it shows Grant Inherited (gray checkmark) because I have set Explicit Grant (green checkmark) for the Authenticated Role (which all users obviously belong to):