Permissions & RBAC (Enterprise)
Relevant source files
The following files were used as context for generating this wiki page:- packages/@n8n/permissions/src/index.ts
- packages/cli/src/permissions.ee/check-access.ts
- packages/db/src/entities/role.ts
- packages/db/src/entities/scope.ts
- packages/cli/src/public-api/v1/shared/middlewares/global.middleware.ts
- packages/cli/test/integration/database/repositories/role.repository.test.ts
- packages/@n8n/permissions/src/tests/schemas.test.ts
- packages/cli/test/integration/services/role.service.test.ts
The n8n Enterprise Edition includes a comprehensive Role-Based Access Control (RBAC) system designed to provide granular control over user permissions. This system is built upon two core concepts: Roles and Scopes. A Role is a collection of Scopes, and a Scope represents a single, specific permission (e.g., workflow:create). Users are assigned roles, which in turn grant them the permissions defined by the associated scopes.
This system allows for both global (instance-wide) and project-specific permissions, enabling fine-grained access control for different resources like workflows and credentials. The feature is enabled via the feat:advancedPermissions license flag.
Core Data Models
The RBAC system is primarily defined by the Role and Scope database entities.
Sources: packages/db/src/entities/role.ts, packages/db/src/entities/scope.ts
Entity Relationship Diagram
The diagram below illustrates the many-to-many relationship between Roles and Scopes. A single role can have multiple scopes, and a single scope can be part of multiple roles.
Role Entity
A Role defines a set of permissions. Roles can be system-defined (e.g., global:admin) or custom-created. System roles cannot be modified or deleted.
Sources: packages/db/src/entities/role.ts, packages/cli/test/integration/database/repositories/role.repository.test.ts:210-222
| Field | Type | Description |
|---|---|---|
slug | string (Primary Key) | A unique identifier for the role (e.g., project:admin). |
displayName | string | A human-readable name for the role (e.g., "Project Admin"). |
description | string (nullable) | A description of the role's purpose. |
systemRole | boolean | If true, this is a built-in role that cannot be modified or deleted. |
roleType | 'global' | 'project' | 'credential' | 'workflow' | The category of the role, indicating its application context. |
scopes | Scope[] | A many-to-many relation to the Scope entities that this role contains. |
Scope Entity
A Scope represents a single, atomic permission within the system.
Sources: packages/db/src/entities/scope.ts
| Field | Type | Description |
|---|---|---|
slug | string (Primary Key) | A unique identifier for the permission (e.g., workflow:create). |
displayName | string | A human-readable name for the scope (e.g., "Create Workflows"). |
description | string | A description of what the permission allows. |
Role Schemas and Namespaces
Roles are categorized by namespaces, which are validated using Zod schemas. This ensures that role slugs follow a consistent and predictable format.
Sources: packages/@n8n/permissions/src/index.ts, packages/@n8n/permissions/src/tests/schemas.test.ts
| Namespace | Schema | Valid Examples | Description |
|---|---|---|---|
global | globalRoleSchema | global:owner, global:admin, global:member | Roles that apply instance-wide. |
project | systemProjectRoleSchema | project:owner, project:admin, project:editor, project:viewer | System-defined roles for project-level access. |
project (custom) | customProjectRoleSchema | custom:my-role | Custom-defined roles for project-level access. |
credential | credentialSharingRoleSchema | credential:owner, credential:user | Roles for sharing credentials. |
workflow | workflowSharingRoleSchema | workflow:owner, workflow:editor | Roles for sharing workflows. |
Access Checking
The core of the permission system is the userHasScopes function, which determines if a user has the required permissions to perform an action.
Sources: packages/cli/src/permissions.ee/check-access.ts
Access Check Flow
This function checks both the user's global role and their project-specific roles (if applicable) to see if they possess the required scopes.
The function signature is:
async function userHasScopes(
user: User,
requiredScopes: Scope[],
globalOnly = false,
params: {
workflowId?: string;
credentialId?: string;
} = {},
): Promise<boolean>
user: The user object whose permissions are being checked.requiredScopes: An array of scope slugs that are required for the action.globalOnly: Iftrue, only the user's global role is checked.params: Contains resource IDs (workflowId,credentialId) to check project-specific permissions.
Sources: packages/cli/src/permissions.ee/check-access.ts:101-110
API Middleware Integration
The RBAC system is integrated into the application's API layer through Express middleware, which protects endpoints by checking for required scopes before executing the controller logic.
Sources: packages/cli/src/public-api/v1/shared/middlewares/global.middleware.ts
Middleware Functions
globalScope(scopes): A middleware factory that checks for instance-wide permissions. It usesuserHasScopeswithglobalOnlyset totrue.projectScope(scopes, resource): A middleware factory for checking project-level permissions. It passes the resource type (workfloworcredential) and ID touserHasScopes.apiKeyHasScope(scope): A middleware for checking if an API key has a specific scope. This is enabled when thefeat:apiKeyScopeslicense feature is active.
API Request Sequence
The following diagram shows how a request to a protected API endpoint is handled.
Role Management
The RoleService provides the business logic for managing custom roles.
Sources: packages/cli/test/integration/services/role.service.test.ts
Key Service Methods
createCustomRole(dto): Creates a new custom role. It generates a slug from the display name and validates that all provided scopes exist.updateCustomRole(slug, dto): Updates an existing custom role's properties, such as itsdisplayName,description, orscopes. It prevents modification of system roles.removeCustomRole(slug): Deletes a custom role. This action is blocked if the role is a system role or if it is currently assigned to any users.
An important constraint is that system roles are immutable. Any attempt to update or delete a role where systemRole is true will result in an error.
Sources: packages/cli/test/integration/database/repositories/role.repository.test.ts:210-222, packages/cli/test/integration/services/role.service.test.ts:413-426
Summary
The n8n Permissions & RBAC system is a powerful, enterprise-focused feature that provides robust access control through a flexible model of Roles and Scopes. It secures the platform at multiple levels, from the database schema with Role and Scope entities to the API layer with dedicated middleware. The system's design, which separates global from project-level permissions and protects immutable system roles, ensures both security and maintainability for complex, multi-user environments.