SudoSOS Back-end API / rbac
Rbac ​
A Role is a named permission set. A user picks up a role through one of three paths: their user type maps to it via RoleUserType, an admin assigns it explicitly via AssignedRole, or they inherit it from an organ they belong to via OrganMembership. RoleManager resolves the union of all three on every request.
The permission tuple ​
A Permission row is keyed on (role, entity, action, relation) with a JSON attributes list. To read a user's own email the check is can(roles, "get", "own", "User", ["email"]). The user passes if at least one of their roles has a permission row matching that tuple whose attributes contain "email" or the wildcard "*".
Relations express ownership scope. The common ones are "own" (the user themselves), "organ" (anyone in an organ the user belongs to), "created" (records the user created), and "all" (the global escape hatch). RoleManager.can() always adds "all" to the requested relations before querying, so a permission with relation "all" covers any narrower one.
Production roles ​
Production has a fixed set of system roles, defined in src/rbac/default-roles.ts and idempotently seeded by DefaultRoles.synchronize():
User-- base read role attached to most authenticated users.Local User-- additional permissions for users with a local password.Buyer-- can create transactions.AuthorizedBuyer-- can create transactions on behalf of others.Invoice-- attached to invoice-type accounts.Point of Sale-- attached to POS-type accounts.Seller-- granted to container owners through organ membership.Super admin-- wildcard everything for system administrators.
The UserType -> role mapping is seeded into RoleUserType rows by the same code path. Role.systemDefault: true marks these as protected: the cleanup pass at the end of synchronize() only deletes systemDefault roles whose name is missing from default-roles.ts, so admin-created roles are never touched.
Dev-mode bypass ​
RoleManager.can() returns true unconditionally when Config.app.isDevelopment is set. Tests that exercise RBAC need a non-development NODE_ENV, or the fixtures that seed the production roles and sign real tokens (ensureProductionRoles() + signTokenFor()).
Controller ​
RbacController exposes role CRUD plus per-role permission editing: list roles, get a role with its permissions, list users linked to a role, create / update / delete roles, and add / remove permissions on a role. It does not assign roles to users -- that happens through AssignedRole writes, or more commonly falls out of the UserType -> RoleUserType mapping.
Classes ​
| Class | Description |
|---|---|
| AssignedRole | The AssignedRole entity represents the many-to-many relationship between users and roles in the Role-Based Access Control (RBAC) system. This entity allows individual users to be assigned specific roles, granting them the permissions associated with those roles. |
| DefaultRoles | Static class defining all default roles present in SudoSOS. These roles are hardcoded and cannot be changed by the user. They should only contain basic functionality that is bound to one or more types of users. |
| Permission | - |
| RbacController | Controller for the rbac module. Read/write surface for Role records and their Permission rows; assigning a role to a specific user happens through AssignedRole writes elsewhere or falls out of the UserType -> RoleUserType mapping. See the module page for the permission tuple, dev-mode bypass, and the list of production roles. |
| RBACService | - |
| Role | - |
| RoleManager | The role manager is responsible for the management of registered roles in the system, and performing access checks based on user roles and user access. |
| RoleUserType | The RoleUserType entity represents the many-to-many relationship between user types and roles in the Role-Based Access Control (RBAC) system. This entity enables automatic role assignment based on a user's type. |
Interfaces ​
| Interface | Description |
|---|---|
| ActionDefinition | The action definition interface defines a mapping from ownership relation of the subject entity to the allowed attributes. Typical ownership relations are 'own', 'created', and 'all'. |
| ActionResponse | - |
| CreatePermissionParams | - |
| EntityDefinition | The entity definition interface defines a mapping from actions to the action definitions belonging to these actions. Action names typically are the CRUD values 'create', 'read', 'update', and 'delete'. |
| PermissionDefinition | The permission definition interface defines a mapping from entity subject names to entity definitions. The name of the entity describes the object for which CRUD permissions are checked. |
| PermissionResponse | - |
| PermissionRule | - |
| RelationResponse | - |
| RoleDefinition | A role definition contains a unique name, permission definitions, and an assignment predicate which determines if a supplied user has the role. |
| RoleDefinitions | The role definitions interface defines a mapping from role names to role definitions. In this mapping, all role definition objects should have the same name as the key used in this mapping. |
| RoleResponse | - |
| UpdateRoleRequest | - |
Type Aliases ​
| Type Alias | Description |
|---|---|
| AllowedAttribute | The allowed attribute is a string defining what attributes/properties of the entity are allowed to be accessed. |
| AssignmentCheck | The assignment check is a predicate performed on a user to determine whether or not the user has the given role. This predicate could perform database queries or other API calls, but should resolve swiftly as it delays login requests et cetera. |
Variables ​
| Variable | Description |
|---|---|
| SELLER_ROLE | - |