RBAC
Flow-level access control with roles and per-user permissions.
@invect/rbac adds role-based access control on top of @invect/user-auth. It lets you restrict which users can view, edit, or own individual flows — and contributes a Share button and Access Control page to the frontend.
The RBAC plugin requires @invect/user-auth to be configured first. It handles the authorization layer on top of the authentication that better-auth provides.
Installation
npm install @invect/rbacAdd the plugin to Invect
Register rbacPlugin after userAuth in your plugins array:
import { createInvectRouter } from '@invect/express';
import { userAuth } from '@invect/user-auth';
import { rbacPlugin } from '@invect/rbac';
import { auth } from './auth';
app.use('/invect', createInvectRouter({
baseDatabaseConfig: {
type: 'sqlite',
connectionString: process.env.DATABASE_URL || 'file:./dev.db',
id: 'main',
},
plugins: [
userAuth({ auth }),
rbacPlugin(),
],
}));InvectModule.forRoot({
baseDatabaseConfig: {
type: 'postgresql',
connectionString: process.env.DATABASE_URL || 'postgresql://localhost:5432/invect',
id: 'main',
},
plugins: [
userAuth({ auth }),
rbacPlugin(),
],
})createInvectHandler({
baseDatabaseConfig: {
type: 'sqlite',
connectionString: process.env.DATABASE_URL || 'file:./dev.db',
id: 'main',
},
plugins: [
userAuth({ auth }),
rbacPlugin(),
],
})Enable the flow access table
In your Invect config, opt in to per-flow access control:
createInvectRouter({
baseDatabaseConfig: {
type: 'sqlite',
connectionString: process.env.DATABASE_URL || 'file:./dev.db',
id: 'main',
},
auth: {
useFlowAccessTable: true,
},
plugins: [
userAuth({ auth }),
rbacPlugin(),
],
});Migrate the database
The RBAC plugin uses the core flow_access table (already included in the base schema). Run migrations if you haven't already:
npx invect-cli generate
npx invect-cli migrate --pushAdd the frontend plugin
In your React app, include the RBAC frontend plugin:
import { Invect } from '@invect/frontend';
import { rbacFrontendPlugin } from '@invect/rbac/ui';
import '@invect/frontend/styles';
export default function App() {
return (
<Invect
apiBaseUrl="/invect"
plugins={[rbacFrontendPlugin]}
/>
);
}This adds the Share button to the flow editor header, an Access tab in the node panel, and an Access Control admin page in the sidebar.
Access levels
Each flow access record grants one of three permission levels:
| Level | Can view | Can edit | Can delete | Can manage access |
|---|---|---|---|---|
viewer | ✓ | — | — | — |
editor | ✓ | ✓ | — | — |
owner | ✓ | ✓ | ✓ | ✓ |
When a user creates a flow, they are automatically granted owner access.
API Endpoints
All endpoints are mounted under /plugins/rbac/ (or the equivalent path for your framework).
| Method | Path | Description |
|---|---|---|
GET | /rbac/me | Current user identity, role, and resolved permissions |
GET | /rbac/roles | List available roles |
GET | /rbac/flows/:flowId/access | List access records for a flow |
POST | /rbac/flows/:flowId/access | Grant access to a user or team |
DELETE | /rbac/flows/:flowId/access/:accessId | Revoke an access record |
GET | /rbac/flows/accessible | List flow IDs the current user can access |
Granting access
// POST /rbac/flows/:flowId/access
{
"userId": "user_123",
"permission": "editor",
"expiresAt": "2026-12-31T00:00:00Z" // optional
}Configuration
rbacPlugin({
// Enable per-flow access table checks (default: true)
useFlowAccessTable: true,
// Permission required to view the Access Control admin page (default: 'admin:*')
adminPermission: 'admin:*',
})