RBAC
Concept of role-based access control in Nocto
Availability:
RBAC framework is available from the following versions:
- CLI (npx @rsc-labs/create-nocto-app) - >= 0.0.19
- @rsc-labs/nocto - >= 0.1.6
- @rsc-labs/nocto-plugin-system - >= 0.1.5
Introduction
Nocto starts providing a framework for implementing RBAC system, which lets you:
- hide sidebar items based on your conditions
- hide routes based on your conditions
- hide pages based on your conditions
- or even hide slots based on your conditions
RBAC in Nocto, as rest parts of Nocto, gives you a full flexibility how you would like to handle RBAC. It does not provide exact implementation, but gives you a framework to handle different ways because RBAC in your application can look differently than the others.
Important to know
Plugins and slots
Before going into RBAC, it is recommended to get familiar with Plugins, Slots and Routes, because RBAC is strongly connected to these concepts.
Frontend vs backend
To understand why Nocto gives such framework, it is needed firstly to understand the difference of RBAC on the Frontend
versus Backend
.
Nocto provides you administrator dashboard on top of Medusa Admin, so it gives you a frontend experience. It means that you can expect that you will be able to hide some UI elements based on different conditions. However, it does not prevent the user to execute some queries to your backend - in theory if user knows the API, he can anyway call your API without having any visualization on the frontend.
On the other hand - please do not be scary. Medusa backend provides you a good framework to defend from such queries, but again - this is separated from what user sees on the frontend - it won't be covered in Nocto itself, because it requires holistic view on the system.
Summary:
RBAC in Nocto gives you ability to hide UI elements based on different conditions, but what exactly user can do underneath needs to be implemented on the backend - this is the ultimate, secured solution.
Architecture
RBAC context
On top of Nocto context, there is provided RBAC context which holds the information about RBAC configuration. When using CLI, you won't see this, but it means that your RBAC configuration can be passed via the main App
.
There is one new parameter called rbac
which contains two parameters:
- fetchPermissions
- evaluateAccess
You can go to src/main.tsx
generated by the CLI and notice this possibility:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { loadMyNoctoPlugins } from './utils';
import { noctoConfig } from './../nocto-config'
import App from "@rsc-labs/nocto"
import "./index.css"
import "./themes/theme-oceanic.css"
async function bootstrap() {
await loadMyNoctoPlugins(noctoConfig);
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App noctoConfig={noctoConfig} rbac={/*RBAC configuration*/} />
</React.StrictMode>
);
}
bootstrap();
Permissions
The first parameter is the function which you passed to get the permissions for the user. Nocto uses userId
from Medusa (precisely - it uses hook useMe()
), so your function can take it as argument (or you can also use userId
from auth request - see Retrieve Admin User). The function which you will provide shall execute backend API to get the list of permission which are related to logged-in user.
Backend API:
We recommend calling the backend to get the list of permissions, but you can even hardcode them - the function can be async
or sync
.
The function shall return following type Map<string, string[]>
where:
key
is the id of the Nocto pluginvalue
- list of permissions for the logged-in user for this plugin
Permission itself is fully defined by you. Nocto does not limit this, so it is totally up to you how you will structure them. The only thing which connects RBAC with Nocto is the ID of the Nocto plugin.
Return type:
Above return type is a return type for the fetchPermissions
function. It does not mean that your backend shall return such type. You can also just use your existing backend and do internal mapping in a function. Examples will be provided in the next section.
Evaluate access
Above information about permissions can now be used to evaluate access to particular piece of UI. It is done via next function which is evaluateAccess
. This function is executed for every plugin in Nocto to decide if it shall be rendered for the logged-in user.
The function gets list of permissions and returns decision (boolean
) if the plugin shall be rendered. For instance, let's say that you returned following information from fetchPermissions
:
return new Map<string, string[]>([
[
"@products", ["view"]
"@orders", ["view"]
]
]);
Now, when Nocto renders @products
plugin, it executed evaluateAccess
function. You can implement evaluateAccess
in that way:
evaluateAccess(permissions?: string[]): boolean {
if (permissions.includes('view')) {
return true;
}
return false;
}
It means that user which has view
permission will see the plugin. Above permission will let you user to see Products
and Orders
on the sidebar. The rest options will be hidden.
More examples will be provided in the next section.