Role-based Access Control
Relevant source files
The following files were used as context for generating this wiki page:
Role-based Access Control (RBAC) in PMM provides a structured mechanism for managing user permissions through the definition and assignment of roles. Each role is characterized by a title, a description, and a filter, which is utilized to determine the specific scope of access granted to a user. This system allows administrators to centralize permission management, ensuring that users have the appropriate level of access to database monitoring data based on their organizational responsibilities.
The RBAC implementation is primarily managed by the AccessControlService, which exposes a gRPC and RESTful API for role lifecycle management. This includes creating, updating, retrieving, listing, and deleting roles, as well as assigning roles to specific users and configuring a default role for the system. Sources: api/accesscontrol/v1beta1/accesscontrol.proto:104-162, managed/services/management/accesscontrol.go:37-43
Architecture and Components
The RBAC system follows a standard PMM service architecture where a protobuf-defined service is implemented in the managed backend and exposed via gRPC and a JSON reverse proxy.
Service Structure
The AccessControlService is the central component responsible for handling all role-related operations. It interacts with the underlying database using the reform ORM to persist role data and user assignments. Sources: managed/services/management/accesscontrol.go:37-43
The diagram above shows the request flow from an API client through the gateway to the implementation service and the persistence layer. Sources: api/accesscontrol/v1beta1/accesscontrol.pb.gw.go, managed/services/management/accesscontrol.go:48-55
Role Data Model
A role is defined by several key attributes that dictate its behavior and visibility:
| Field | Type | Description |
|---|---|---|
role_id | uint32 | Unique identifier for the role. |
title | string | The display name of the role (required, min length 1). |
filter | string | A string-based filter defining access scope (e.g., label-based filters). |
description | string | A textual explanation of the role's purpose. |
Sources: api/accesscontrol/v1beta1/accesscontrol.proto:9-13, api/accesscontrol/v1beta1/accesscontrol.pb.go:31-37
API Operations
The AccessControlService provides several RPC methods for role management.
Role Lifecycle Management
The service supports standard CRUD operations. When a role is deleted, a replacement_role_id can be provided to reassign associations, though additional logic applies to this process. Sources: api/accesscontrol/v1beta1/accesscontrol.proto:26-30, managed/services/management/accesscontrol.go:88-106
The sequence above illustrates the basic creation and update flow for roles within the system. Sources: managed/services/management/accesscontrol.go:58-84
User-Role Assignment
Roles are assigned to users via the AssignRoles method. This operation is destructive for existing assignments, as it replaces all currently assigned roles for a specified user with the new list of role IDs provided in the request. Sources: api/accesscontrol/v1beta1/accesscontrol.proto:144-152, managed/services/management/accesscontrol.go:160-176
API Endpoints (REST)
The following table summarizes the RESTful endpoints provided by the gRPC gateway for RBAC management:
| Method | Path | Description |
|---|---|---|
| POST | /v1/accesscontrol/roles | Create a new role. |
| GET | /v1/accesscontrol/roles | List all existing roles. |
| GET | /v1/accesscontrol/roles/{role_id} | Retrieve details of a specific role. |
| PUT | /v1/accesscontrol/roles/{role_id} | Update an existing role. |
| DELETE | /v1/accesscontrol/roles/{role_id} | Delete a role. |
| POST | /v1/accesscontrol/roles:assign | Assign roles to a user. |
| POST | /v1/accesscontrol/roles:setDefault | Configure the default role. |
Sources: api/accesscontrol/v1beta1/accesscontrol.proto:105-161, api/accesscontrol/v1beta1/accesscontrol.swagger.json
Implementation Details
Service Activation
The service includes an Enabled() check that verifies if access control is globally active in the PMM settings before proceeding with operations. If settings cannot be retrieved, it defaults to disabled. Sources: managed/services/management/accesscontrol.go:48-55
Database Interaction
Operations that modify multiple records or critical settings, such as AssignRoles, DeleteRole, and SetDefaultRole, are wrapped in database transactions to ensure atomicity. Sources: managed/services/management/accesscontrol.go:89-100, managed/services/management/accesscontrol.go:161-175
// AssignRoles assigns a Role to a user within a transaction.
func (acs *AccessControlService) AssignRoles(ctx context.Context, req *rolev1beta1.AssignRolesRequest) (*rolev1beta1.AssignRolesResponse, error) {
err := acs.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
roleIDs := make([]int, 0, len(req.RoleIds))
for _, id := range req.RoleIds {
roleIDs = append(roleIDs, int(id))
}
return models.AssignRoles(tx, int(req.UserId), roleIDs)
})
// ... error handling
}
Sources: managed/services/management/accesscontrol.go:160-176
Error Handling
The service uses standard gRPC status codes for error reporting:
codes.NotFound: Returned when a specifiedrole_iddoes not exist during Get, Update, Delete, or Assignment operations.codes.InvalidArgument: Triggered by validation rules defined in the.protofile (e.g., empty titles or non-positive role IDs).
Sources: managed/services/management/accesscontrol.go:72-74, api/accesscontrol/v1beta1/accesscontrol.proto:16-18
Conclusion
The Role-based Access Control system in PMM provides a robust API for defining granular access scopes through roles and assigning them to users. By utilizing a transaction-heavy implementation in the backend and a clear gRPC/REST interface, it ensures data integrity and ease of integration for administrative interfaces. Sources: managed/services/management/accesscontrol.go, api/accesscontrol/v1beta1/accesscontrol.proto