Roles and permissions
By default, Launchway comes with a flexible roles and permissions system. One role is assigned many permissions and each user within an organization must be assigned one of these roles. Users have a different role assignment per organization, allowing them to be, for example, an admin in one organization and a regular non-admin in another.
Roles and permissions are totally optional. Validating a users access to a certain feature or endpoint is a separate process to actually fetching data or performing mutations. It is entirely up to you where or how often you wish to validate a users access, if at all. It is set up by default because if you start without and then decided to retrofit it to your database schema down the line, it will be considerably more hassle.
Permissions
Permissions are modeled on the role-based access control (RBAC) model. You may be familiar with this system from apps like Stripe, GitHub or AWS.
Permissions comprise the following properties
- The action defines what operations can be performed. Currently the actions
read
andwrite
, wherewrite
implies that the permission can alsoread
. - The entity defines the objects or resources the action can be performed on (e.g.
issues
,members
,settings
) - The access defines the scope or level of access. Right now this is
any
for all pre-defined permissions but could be extended to be more restrictive. e.g. you could introduceteam
access to write a permission likewrite any team issue
Roles
There are two roles in the initial Launchway setup.
admin
- Has
write
permissions for all entities
user
- Has
write
permission forissues
- Has
read
permissions formembers
andsettings
This is configured in the app/drizzle/scripts/seed.ts
script and can be changed easily.
Validating roles
There is a helper method that is used at various parts of the app called validateUserRoleHasPermission()
. You call it like this
const canManageUsers = await validateUserRoleHasPermission(
userId,
['write'],
'members',
)
if (!canManageUsers) {
return redirect('/dashboard/members')
}
This will check that the current users role within the organization has write
permission for settings
. Both write
and settings
here are type-safe enums which make it easy to extend the system.
Extending the system
As you add more entities to your app, you may wish to add more role and permissions around them. There's a helper script you can run with npm setup:permissions
to guide you through the process of adding new roles and permissions.
Organization-specific roles
The default roles and permissions are global and not tied to any specific organizationId
. If you wanted to allow organizations to create their own roles or permissions, you could replicate the RolesTable
and PermissionsTable
with the addition of a new organizationId
column and query this alongside, or instead of, the existing roles and permissions tables.