Role-Based Access Control (RBAC)
Relevant source files
The following files were used as context for generating this wiki page:
Role-Based Access Control (RBAC), also referred to as Fine-grained Access Control in enterprise contexts, is the primary system for managing permissions and security within the project. It allows administrators to define granular sets of actions and scopes, group them into roles, and assign those roles to users, teams, or service accounts. This system replaces or augments simpler legacy permission models to provide precise control over resources such as dashboards, data sources, and organization settings.
Sources: public/api-enterprise-spec.json:1174, pkg/api/accesscontrol.go:42
Core Architecture and Data Structures
The RBAC system is built upon three primary pillars: Permissions, Roles, and Assignments.
Permissions and Scopes
A permission is the smallest unit of access control, consisting of an Action (the operation allowed) and a Scope (the specific resource or group of resources the action applies to).
- Actions: Strings like
users:read,dashboards:write, oralerting.rules:create. - Scopes: Define where the action is valid. Examples include
global.users:*(all users globally),datasources:uid:abc(a specific data source), orfolders:uid:general(the general folder).
Sources: pkg/api/accesscontrol.go:19-26, pkg/services/accesscontrol/roles.go:300, conf/provisioning/access-control/sample.yaml:20-25
Roles and Role Types
Roles are named containers for a collection of permissions. The system categorizes roles using specific prefixes:
| Prefix | Type | Description |
|---|---|---|
basic: | Basic Role | Built-in organizational roles: Viewer, Editor, Admin, and Grafana Admin. |
fixed: | Fixed Role | Pre-defined roles for specific features (e.g., fixed:reporting:admin). |
custom: | Custom Role | User-defined roles created via API or provisioning. |
managed: | Managed Role | Internal roles managed by the system for specific resource instances. |
plugins: | Plugin Role | Roles defined by installed plugins. |
Sources: pkg/services/accesscontrol/roles.go:15-30, pkg/api/accesscontrol.go:45-50
Logic Flow for Permission Evaluation
The following diagram illustrates how the system evaluates if a user has access to a resource based on their assigned roles.
Explanation: The system aggregates permissions from directly assigned roles, organizational roles, and roles inherited via teams to determine access.
Sources: public/api-enterprise-spec.json:52-55, pkg/api/accesscontrol.go:315-325
Role Management and Provisioning
Roles can be managed either through the HTTP API (Enterprise) or via YAML configuration files (Provisioning).
Provisioning Logic
Administrators can define custom roles and assignments in access-control provisioning files. The system supports creating roles, deleting roles (setting state: absent), and creating roles that inherit permissions from existing ones using the from attribute.
roles:
- name: 'custom:users:writer'
uid: customuserswriter1
permissions:
- action: 'users:read'
scope: 'global.users:*'
teams:
- name: 'DevOps Team'
roles:
- uid: 'customuserswriter1'
Sources: conf/provisioning/access-control/sample.yaml:8-75
API Endpoints for Access Control
The enterprise API provides endpoints for programmatic management of the RBAC system.
| Endpoint | Method | Summary |
|---|---|---|
/access-control/roles | GET | List all available roles. |
/access-control/roles | POST | Create a new custom role. |
/access-control/users/{userId}/roles | PUT | Bulk set role assignments for a user. |
/access-control/teams/{teamId}/roles | POST | Assign a role to a team. |
Sources: public/api-enterprise-spec.json:52-250
Implementation Details in Backend
Role Declaration
The backend uses a RoleRegistration structure to declare fixed roles and their default grants to basic organizational roles. For example, the fixed:organization:reader role is granted by default to Viewer and Grafana Admin.
orgReaderRole := ac.RoleRegistration{
Role: ac.RoleDTO{
Name: "fixed:organization:reader",
DisplayName: "Reader",
Description: "Read an organization's metadata.",
Group: "Organizations",
Permissions: []ac.Permission{
{Action: ac.ActionOrgsRead},
{Action: ac.ActionOrgsQuotasRead},
},
},
Grants: []string{string(org.RoleViewer), ac.RoleGrafanaAdmin},
}
Sources: pkg/api/accesscontrol.go:142-154
Resource Metadata
The system can attach accesscontrol metadata to resource responses (like folders or data sources). This metadata tells the frontend which actions (edit, delete, save) the current user is permitted to perform on that specific resource.
Sources: pkg/api/accesscontrol.go:315-328, public/api-enterprise-spec.json:1130
RBAC in Frontend Development
In the frontend, access control is primarily checked using the useAbilities hook or by inspecting the contextSrv.
Component Permission Checks
Developers check for specific actions before rendering UI elements. For example, a "Create Rule" button in the alerting feature should only appear if the user has the alerting.rule:create action.
const [_, { can }] = useAbilities();
const canCreate = can(AccessControlAction.AlertingRuleCreate);
return canCreate ? <CreateButton /> : null;
Sources: public/app/features/alerting/unified/AGENTS.md:310-318, public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx:50-55
Frontend Style and Testing
- Testing: MSW (Mock Service Worker) is used to mock API responses, including permission metadata.
- RBAC State: By default, tests assume RBAC is enabled to reflect common user scenarios.
Sources: public/app/features/alerting/unified/AGENTS.md:195-205
Summary
The Role-Based Access Control system provides a robust, granular framework for securing the project. By decoupling actions from specific identities and utilizing a structured hierarchy of roles and scopes, it allows for scalable permission management across global and organizational boundaries. The integration of provisioning, API-driven management, and frontend hooks ensures a consistent security posture throughout the application.
Sources: pkg/api/accesscontrol.go:42-50, pkg/services/accesscontrol/roles.go:300-320