Documentation Index
Fetch the complete documentation index at: https://mintlify.com/grafana/grafana/llms.txt
Use this file to discover all available pages before exploring further.
Grafana uses a comprehensive role-based access control (RBAC) system to manage user permissions and access to resources. This guide covers the authorization architecture and configuration.
Overview
Grafana’s authorization system is implemented in pkg/services/accesscontrol/ and provides:
- Role-based access control (RBAC)
- Fine-grained permissions on resources
- Built-in roles (Viewer, Editor, Admin, Grafana Admin)
- Custom role creation
- Team-based permissions
- Resource-specific permissions
Core Concepts
Permissions
A permission consists of an action and a scope:
type Permission struct {
Action string // e.g., "dashboards:read"
Scope string // e.g., "dashboards:uid:abc123" or "dashboards:*"
}
Reference: pkg/services/accesscontrol/models.go:206-218
Actions define what operation can be performed:
dashboards:read - View dashboards
dashboards:write - Edit dashboards
dashboards:delete - Delete dashboards
users:read - View users
datasources:explore - Use Explore feature
Scopes define where the action applies:
dashboards:* - All dashboards
dashboards:uid:abc123 - Specific dashboard
folders:uid:xyz789 - Specific folder
datasources:id:1 - Specific datasource
Roles
Roles are collections of permissions:
type Role struct {
ID int64
OrgID int64 // 0 for global roles
UID string
Name string
DisplayName string
Description string
Group string
Hidden bool
Permissions []Permission
}
Reference: pkg/services/accesscontrol/models.go:36-49
Role Types
-
Built-in Roles: Predefined organization roles
-
Grafana Admin: Super admin with global permissions
-
Fixed Roles: System-defined roles (prefixed with
fixed:)
-
Custom Roles: User-defined roles for specific needs
-
Managed Roles: Auto-generated roles for resource permissions
Evaluators
Evaluators combine permissions with logical operators:
// Single permission
EvalPermission("dashboards:read", "dashboards:uid:abc123")
// Multiple permissions (AND)
EvalAll(
EvalPermission("dashboards:read"),
EvalPermission("dashboards:write"),
)
// Multiple permissions (OR)
EvalAny(
EvalPermission("dashboards:read"),
EvalPermission("folders:read"),
)
Reference: pkg/services/accesscontrol/evaluator.go
Built-in Roles
Organization Roles
Grafana has three built-in organization roles with different permission levels:
Viewer
- View dashboards and panels
- View datasources (not query)
- View playlists
- View annotations
Editor
- All Viewer permissions
- Create and edit dashboards
- Create and edit folders
- Create and edit playlists
- Create annotations
Admin
- All Editor permissions
- Add and edit datasources
- Add and edit users to organization
- Manage organization settings
- Configure teams
- Manage plugins
- View and edit API keys
Grafana Admin
Grafana Admins have super admin privileges across all organizations:
- All organization permissions in all orgs
- Create and manage organizations
- Create and manage users globally
- Access server admin pages
- Manage Grafana configuration
- View usage statistics
Constant: accesscontrol.RoleGrafanaAdmin (line 345)
Reference: pkg/services/accesscontrol/models.go:345
Access Control Service
The main access control interface provides permission evaluation and management.
Core Interface
type AccessControl interface {
// Evaluate evaluates access to resources
Evaluate(ctx context.Context, user identity.Requester, evaluator Evaluator) (bool, error)
// RegisterScopeAttributeResolver registers scope resolvers
RegisterScopeAttributeResolver(prefix string, resolver ScopeAttributeResolver)
// WithoutResolvers creates an AccessControl without resolvers
WithoutResolvers() AccessControl
// InvalidateResolverCache clears cached scope resolutions
InvalidateResolverCache(orgID int64, scope string)
}
Reference: pkg/services/accesscontrol/accesscontrol.go:22-34
Permission Evaluation
Evaluating permissions in middleware:
// Check if user has access
hasAccess := ac.HasAccess(accessControl, c)
if !hasAccess(EvalPermission("dashboards:read", "dashboards:uid:123")) {
accessForbidden(c)
return
}
Reference: pkg/services/accesscontrol/accesscontrol.go:200-210
User Permissions
Getting User Permissions
type Service interface {
// Get user permissions
GetUserPermissions(ctx context.Context, user identity.Requester,
options Options) ([]Permission, error)
// Search user permissions by action
SearchUserPermissions(ctx context.Context, orgID int64,
filterOptions SearchOptions) ([]Permission, error)
// Clear permission cache for user
ClearUserPermissionCache(user identity.Requester)
}
Reference: pkg/services/accesscontrol/accesscontrol.go:36-66
Permission Caching
Permissions are cached for performance:
[rbac]
# Enable permission caching
permission_cache = true
Reference: conf/defaults.ini:1126-1127
Resource Permissions
Resource-specific permissions control access to individual resources.
Permission Service
type PermissionsService interface {
// Get permissions for a resource
GetPermissions(ctx context.Context, user identity.Requester,
resourceID string) ([]ResourcePermission, error)
// Set user permission on resource
SetUserPermission(ctx context.Context, orgID int64, user User,
resourceID, permission string) (*ResourcePermission, error)
// Set team permission on resource
SetTeamPermission(ctx context.Context, orgID, teamID int64,
resourceID, permission string) (*ResourcePermission, error)
// Set built-in role permission
SetBuiltInRolePermission(ctx context.Context, orgID int64,
builtInRole string, resourceID, permission string) (*ResourcePermission, error)
// Delete all permissions for resource
DeleteResourcePermissions(ctx context.Context, orgID int64,
resourceID string) error
}
Reference: pkg/services/accesscontrol/accesscontrol.go:150-165
Resource Types with Permissions
- Dashboards:
DashboardPermissionsService
- Folders:
FolderPermissionsService
- Datasources:
DatasourcePermissionsService
- Teams:
TeamPermissionsService
- Service Accounts:
ServiceAccountPermissionsService
- Alerting Receivers:
ReceiverPermissionsService
Reference: pkg/services/accesscontrol/accesscontrol.go:128-148
Middleware
Access control middleware enforces permissions on routes.
Basic Middleware
// Require specific permission
ac.Middleware(accessControl)(
ac.EvalPermission("dashboards:read"),
)
// Require role
RoleAuth(org.RoleAdmin)
// Require signed in
Auth(&AuthOptions{ReqSignedIn: true})
// Require Grafana Admin
Auth(&AuthOptions{ReqGrafanaAdmin: true})
Reference: pkg/services/accesscontrol/middleware.go
Route Protection
Example from pkg/middleware/auth.go:
// Require authentication
func Auth(options *AuthOptions) web.Handler {
return func(c *contextmodel.ReqContext) {
if !c.IsSignedIn && options.ReqSignedIn {
notAuthorized(c)
return
}
if !c.IsGrafanaAdmin && options.ReqGrafanaAdmin {
accessForbidden(c)
return
}
}
}
Reference: pkg/middleware/auth.go:202-233
Actions and Scopes
Common Actions
User Actions
const (
ActionUsersRead = "users:read"
ActionUsersWrite = "users:write"
ActionUsersDelete = "users:delete"
ActionUsersCreate = "users:create"
ActionUsersEnable = "users:enable"
ActionUsersDisable = "users:disable"
ActionUsersPasswordUpdate = "users.password:write"
ActionUsersPermissionsUpdate = "users.permissions:write"
ActionUsersPermissionsRead = "users.permissions:read"
)
Reference: pkg/services/accesscontrol/models.go:347-368
Organization Actions
const (
ActionOrgsRead = "orgs:read"
ActionOrgsWrite = "orgs:write"
ActionOrgsDelete = "orgs:delete"
ActionOrgsCreate = "orgs:create"
ActionOrgUsersRead = "org.users:read"
ActionOrgUsersAdd = "org.users:add"
ActionOrgUsersRemove = "org.users:remove"
ActionOrgUsersWrite = "org.users:write"
)
Reference: pkg/services/accesscontrol/models.go:370-383
LDAP Actions
const (
ActionLDAPUsersRead = "ldap.user:read"
ActionLDAPUsersSync = "ldap.user:sync"
ActionLDAPStatusRead = "ldap.status:read"
ActionLDAPConfigReload = "ldap.config:reload"
)
Reference: pkg/services/accesscontrol/models.go:385-389
Team Actions
const (
ActionTeamsCreate = "teams:create"
ActionTeamsDelete = "teams:delete"
ActionTeamsRead = "teams:read"
ActionTeamsWrite = "teams:write"
ActionTeamsPermissionsRead = "teams.permissions:read"
ActionTeamsPermissionsWrite = "teams.permissions:write"
)
Reference: pkg/services/accesscontrol/models.go:413-419
Common Scopes
const (
// Global scopes
GlobalOrgID = 0
ScopeGlobalUsersAll = "global.users:*"
// User scopes
ScopeUsersAll = "users:*"
ScopeUsersPrefix = "users:id:"
// Team scopes
ScopeTeamsAll = "teams:*"
// Settings scopes
ScopeSettingsAll = "settings:*"
ScopeSettingsSAML = "settings:auth.saml:*"
ScopeSettingsSCIM = "settings:auth.scim:*"
)
Reference: pkg/services/accesscontrol/models.go:341-422
Scope Patterns
Scopes support wildcards for flexible permission matching:
dashboards:* - All dashboards
dashboards:uid:* - All dashboards by UID
folders:* - All folders
datasources:id:* - All datasources
Fixed Roles
Fixed roles are system-defined roles that map to built-in functionality.
Declaring Fixed Roles
type RoleRegistration struct {
Role RoleDTO // Role definition
Grants []string // Built-in roles to grant this role to
Exclude []string // Built-in roles to exclude
}
// Example: Register a custom fixed role
service.DeclareFixedRoles(
RoleRegistration{
Role: RoleDTO{
Name: "fixed:datasources:reader",
DisplayName: "Datasource Reader",
Description: "Read datasource configuration",
Permissions: []Permission{
{Action: "datasources:read", Scope: "datasources:*"},
},
},
Grants: []string{string(org.RoleEditor), string(org.RoleAdmin)},
},
)
Reference: pkg/services/accesscontrol/models.go:27-33
External Service Roles
External services can have custom roles assigned to their service accounts.
Creating External Service Roles
type SaveExternalServiceRoleCommand struct {
AssignmentOrgID int64
ExternalServiceID string
ServiceAccountID int64
Permissions []Permission
}
// Create role for external service
err := acService.SaveExternalServiceRole(ctx, SaveExternalServiceRoleCommand{
AssignmentOrgID: 1,
ExternalServiceID: "my-service",
ServiceAccountID: serviceAccountID,
Permissions: []Permission{
{Action: "dashboards:read", Scope: "dashboards:*"},
{Action: "datasources:query", Scope: "datasources:*"},
},
})
Reference: pkg/services/accesscontrol/models.go:299-338
Team Permissions
Teams allow grouping users and assigning permissions collectively.
Team-based Access
// Set team permission on dashboard
service.SetTeamPermission(ctx, orgID, teamID, dashboardUID, "View")
// Get team permissions
permissions, err := service.GetPermissions(ctx, user, dashboardUID)
Team Access Evaluator
Protects team configuration pages:
// Require team access (create OR read+write)
var TeamsAccessEvaluator = EvalAny(
EvalPermission(ActionTeamsCreate),
EvalAll(
EvalPermission(ActionTeamsRead),
EvalAny(
EvalPermission(ActionTeamsWrite),
EvalPermission(ActionTeamsPermissionsWrite),
),
),
)
Reference: pkg/services/accesscontrol/models.go:572-582
Configuration
RBAC Settings
[rbac]
# Enable permission caching
permission_cache = true
# Reset basic role permissions on startup (warning: resets on every boot)
reset_basic_roles = false
# Validate permissions when creating/updating roles
permission_validation_enabled = true
Reference: conf/defaults.ini:1124-1134
Best Practices
1. Use Built-in Roles
Leverage built-in roles (Viewer, Editor, Admin) for common access patterns before creating custom roles.
2. Principle of Least Privilege
Grant minimum necessary permissions:
// Good: Specific scope
Permission{Action: "dashboards:read", Scope: "dashboards:uid:abc123"}
// Avoid: Overly broad scope
Permission{Action: "dashboards:write", Scope: "dashboards:*"}
3. Use Teams for Group Management
Assign permissions to teams rather than individual users for easier management.
4. Cache Invalidation
Clear permission cache after role changes:
acService.ClearUserPermissionCache(user)
5. Scope Validation
Validate scope format:
// Valid scopes
ValidateScope("dashboards:uid:abc123") // true
ValidateScope("dashboards:*") // true
ValidateScope("dashboards:uid:*") // true
// Invalid scopes
ValidateScope("dashboards*") // false
ValidateScope("dashboards:*abc") // false
Reference: pkg/services/accesscontrol/accesscontrol.go:378-388
6. Check Global Permissions
For cross-organization access:
hasGlobalAccess := HasGlobalAccess(ac, authnService, c)
if !hasGlobalAccess(evaluator) {
accessForbidden(c)
}
Reference: pkg/services/accesscontrol/accesscontrol.go:173-198
Troubleshooting
Permission Denied Issues
-
Check User Roles: Verify user has correct organization role
# Via API
GET /api/user
GET /api/user/orgs
-
Check Permissions: View user’s effective permissions
GET /api/access-control/user/permissions
-
Clear Cache: Permissions may be cached
[rbac]
permission_cache = false
Debug Logging
Enable access control debugging:
[log]
filters = accesscontrol:debug
Permission Evaluation
Trace permission evaluation:
// The evaluator logs evaluation steps
hasAccess, err := ac.Evaluate(ctx, user, evaluator)
// Check logs for evaluation details