I’ve create a new rule under Auth Pipeline → Rules which I call PostLoginCreateUserAccount. It essentially posts the details of my user to a backend API. The code is basically this:
Essentially I want to secure this API. I thought about Role Based Access Control (RBAC), however, I’m not sure that this applies here.
My understanding of RBAC is that a user is created and assigned a role in Auth0. The API access can be controlled in my backend appropriately. For example, if I have Java SpringBoot, I annotate the code with @PreAuthorize(“hasAuthority(‘read:project’)”)
which allows a read:project permission on the backend side for that user.
My question is whether I can apply the same approach for creating a user. This is because I need to assign a role to the Auth0 process that runs the rule.
My workaround is to create an API key or fixed bearer token on the backend side to control access, however, I’m sure there’s a better way.
It sounds like you are describing a transaction that is not happening on behalf of any user, which would make RBAC not the right solution here. (The user isn’t really creating themself, you wouldn’t want the user to have create:user permissions, right?)
The OAuth2 way of doing things for these types of transactions would be to use a Client Credentials Flow to obtain a token in the rule (or alternatively, an Action), and that token would be attached to the request and verified in your API. You could certainly take this approach.
The drawback is that your rule/action will have to request a token every time you want to create a new user (although there is some caching mechanism available in rules, it is limited). Make sure you are aware of the M2M token limits for your subscription.
The other option to is use an API key or some other form of basic auth, this is a reasonable option as well.
I’ll try to make my question clearer. In the context of a SPA with a backend and secured by Auth0, the backend is a resource server where the SPA is granted access using the token it receives from Auth0.
However, the post-registration to sync the Auth0 users with the backend system adds another dimension for authentication, i.e. the backend needs to only allow access to an Auth0 rule or action. This is what I did in my original question with the rule that has this call from the Auth0 rule to the backend.
I can add an API key in the backend that only Auth0 knows about. My question is whether there’s a better way?
The example you shared with the client credentials flow is where an M2M communicates with Auth0 and the API. I’m only interested in the communication between Auth0 and the API. I hope this makes sense.
Hi Dan,
Further to my email, see the example here Post User Registration Flow
under the sub-heading “Store the Auth0 user id in remote system”. Note how there is an axios.post() method to the remote API. See how there’s no authentication in this example. This is the problem I want to solve.
In the context of this transaction, the rule/action is an M2M app. You can think of it as a serverless function that needs to authenticate with your backend, that just so happens to be hosted by Auth0, and just so happens to be run during a user authentication request from your SPA. But it requires a separate auth transaction between two machines.
In this case, your Auth0 Tenant is the auth server that issues the token, the rule/action is the M2M app that is requesting the token, and your backend is the resource server that will validate the token.
The better way is to use M2M/Client credentials. The drawback; there is a cost associated with M2M tokens and Actions doesn’t have a caching mechanism at the moment, which means you will need one M2M token per call (rules does, but they will become a legacy feature).
Here is an FAQ I wrote about the topic of authenticating an API call from a rule (the same principles apply whether or not you are using an Action, Rule, or Hook etc.):
Hi @dan.woda, Thanks for the links. This is much clearer now in terms of the auth0 server, the M2M app and the backend server. I think this clears it up for me.