Comparing Data Access Strategies for Public APIs (Sign-up, Forgot Password)

Hello,
I am developing public-facing features such as user sign-up and password reset functionalities. To achieve this, I need to allow anonymous users to interact with the backend to create or modify data. I have identified several possible approaches for data access, and I would like to seek clarity on which method is considered the most secure and appropriate according to Jmix best practices.

  1. SystemAuthenticator + DataManager + SpecificPolicy
    My understanding is that this is a layered approach. First, a SpecificPolicy (e.g., resources = "public.sign-up") is assigned to the AnonymousRole to grant entry-point access to the specific REST controller method. Second, within the controller method, the entire business logic (involving DataManager calls) is wrapped in a systemAuthenticator.runWithSystem(...) block to execute it with system-level privileges.
  2. Using DataManager.unconstrained()
    This approach involves injecting the standard DataManager and then calling the .unconstrained() method to bypass security constraints for a specific operation. However, it seems this still requires an authenticated user context to begin with, which is absent in a public API call.
  3. Using the UnconstrainedDataManager bean
    This involves directly injecting the UnconstrainedDataManager. I understand this is a legacy approach and is generally discouraged, but I would like to confirm its security implications compared to the other methods.

My Questions Is:

  • Security Comparison: Which of these approaches provides the highest level of security for public APIs? What are the specific risks associated with each method?
  • Role of SpecificPolicy: When using SystemAuthenticator, is the primary role of SpecificPolicy simply to allow the HTTP request to reach the controller method, while the actual data operations are secured by the system-level execution context?
  • Recommended Practice: For features like user sign-up and password reset, what is the officially recommended Jmix pattern?

Thank you in advance for your guidance.

Hi Thinh,

When users open a view annotated with @AnonymousAllowed or access a public endpoint, the code is executed on behalf of the anonymous user. This doesn’t require any permissions per se, but by default the anonymous user cannot access data through the DataManager.

You are right, there are several ways to allow access to data for the anonymous user.

The simplest one is to use UnconstrainedDataManager by injecting it or by obtaining it through DataManager.unconstrained() - your items 2 and 3. They are absolutely the same, use whatever is more convenient.

The next approach is to wrap the DataManager invocation with system authentication using the SystemAuthenticator bean or @Authenticated annotation. This way you can execute code on behalf of the built-in system user (who has admin rights by default), or any other application user.

And the third approach is to assign a role with some permissions to the anonymous user. You can do it in the DatabaseUserRepository class of your project, similarly to how the system-full-access role is assigned to the system user. Your role should grant minimal permissions to the entities managed in your registration process.

As for SpecificPolicy, it is usually used to limit access to functionality regardless of existing data access permissions. For example, a user may have full access rights to some entity, but without the rest.enabled specific policy he cannot access the entity through the Generic REST API.

I don’t see the point of using a specific policy in your case, because there is nothing to limit here. You rather need to give permissions to access data to a user in a certain situation.

I recommend using the UnconstrainedDataManager, as you have complete control over the logic and a clear understanding of what data is accessed in your case. Assigning entity/attribute policies to the user would make sense if the process involved some framework mechanisms and UI, e.g. for automatic disabling or hiding actions and input fields.

Regards,
Konstantin

1 Like