What's new from Grafana Labsbreadcrumb arrow What's new: RBAC behavior changes with Grafana 13
What's new from Grafana Labs
What's new from Grafana Labs
Grafana Cloud Generally Available Enterprise Generally Available Breaking change
Release date: 2026-05-05

What's new: RBAC behavior changes with Grafana 13

Grafana 13 tightens RBAC enforcement for custom roles, Terraform-managed roles, and role provisioning. Most users aren’t affected. If you maintain custom RBAC roles, especially roles with data source permissions scoped to specific UIDs, or roles using legacy annotation scopes, review your role definitions now to prevent errors.

We recommend updating affected roles proactively. Stricter enforcement is being rolled out progressively, and roles that contain the deprecated permissions described below will begin failing. Taking action now prevents disruption.

If role create, update, delete, or assignment operations start failing, check whether the role contains one of the permissions described below.

Data source permissions in global roles

Grafana 13 changes how data source permissions work in custom RBAC roles as data source APIs move toward strongly typed API groups. If you manage Grafana roles with Terraform, check any role that combines global = true with data source UID-scoped permissions.

What changed

  • A global role should not grant access to one specific data source UID.
  • Specific data source permissions should be defined on non-global roles, or managed through data source permission resources.

What you should do

  • If a Terraform-managed grafana_role contains datasources:uid:<uid>, recreate it as a non-global role. Grafana cannot update the global scope of an existing role in place.
  • If you manage data source permissions through Terraform data source permission resources, set datasource_type when you know the data source type.
  • In Grafana Cloud, a compatibility layer is in place to reduce immediate impact. Self-managed Grafana users should update Terraform before upgrading to Grafana 13.

Before:

resource "grafana_role" "datasource_reader" {
  name   = "Datasource Reader"
  uid    = "datasource-reader"
  global = true

  permissions {
    action = "datasources:read"
    scope  = "datasources:uid:prometheus_uid"
  }
}

After:

resource "grafana_role" "datasource_reader_v2" {
  name   = "Datasource Reader"
  uid    = "datasource-reader-v2"
  global = false

  permissions {
    action = "datasources:read"
    scope  = "datasources:uid:prometheus_uid"
  }
}

Changing global = true to global = false on an existing role won’t work as it changes the scope of the role. Create the replacement role with a new UID, move assignments to it, then remove the old global role.

If you use data source permission resources directly, include the data source type:

resource "grafana_data_source_permission_item" "team_query" {
  datasource_uid  = grafana_data_source.prometheus.uid
  datasource_type = "prometheus"
  team            = grafana_team.observability.id
  permission      = "Query"
}

Dashboard annotation fixed roles were removed

The fixed roles fixed:annotations.dashboard:writer and fixed:annotations.dashboard:reader have been removed. These roles have been superseded by dashboard and folder permissions.

What changed

  • fixed:annotations.dashboard:writer no longer exists.
  • fixed:annotations.dashboard:reader no longer exists.
  • annotations:type:dashboard is a legacy scope and should not be used in new role definitions.

What you should do

  • Remove fixed:annotations.dashboard:writer and fixed:annotations.dashboard:reader from Terraform configurations and automation.
  • Remove permissions that use annotations:type:dashboard from custom roles.
  • Use dashboard or folder permissions (View, Edit, Admin) to grant access to dashboard annotations.
  • Use fixed:annotations:reader and fixed:annotations:writer for organization-level annotations.
  • To grant unrestricted access to all dashboard annotations, use fixed:annotations.all:reader and fixed:annotations.all:writer.
  • If you define custom roles for organization annotations, use the specific annotation actions, such as annotations:read or annotations:write, with annotations:type:organization.

Example replacement for organization annotations:

permissions {
  action = "annotations:read"
  scope  = "annotations:type:organization"
}

Dashboard annotation access now follows dashboard and folder access. If a user can view or edit the dashboard through dashboard/folder permissions, they get the matching access to that dashboard’s annotations.

Stop using annotations:* in custom roles

annotations:* is a legacy wildcard scope and is no longer granted by default. Do not use it in custom roles, Terraform, or provisioning.

What changed

  • Grafana no longer expects custom roles to grant annotation access through annotations:*.
  • Roles that still contain this scope may cause permission errors during role create, update, delete, or assignment operations.
  • Some existing roles may need updating to remove this deprecated scope.

What you should do

  • For organization-level annotations, use annotations:type:organization.
  • For dashboard annotations, use dashboard or folder permissions instead of annotation-specific dashboard scopes.
  • If your automation attempts to grant all annotation access, split the intent:
    • Organization annotations: annotations:type:organization
    • Dashboard annotations: dashboard or folder permissions, such as folder-level View, Edit, or Admin.
  • Do not recreate annotations:* in Terraform after it has been removed.
  • If your role is stuck because Grafana refuses to update or delete it, contact support. The role may contain a deprecated permission that must be removed before Terraform or API updates can succeed.

Troubleshooting

If you see errors like these, inspect the role permissions:

[POST /access-control/roles][403] createRoleForbidden {"message":"Forbidden"}
[PUT /access-control/roles/{roleUID}][403] updateRoleForbidden {"message":"Forbidden"}
[PUT /access-control/roles/{roleUID}/assignments][403] setRoleAssignmentsForbidden {"message":"Forbidden"}

Look for:

  • Data source permissions with a specific datasources:uid:<uid> scope on a global role
  • fixed:annotations.dashboard:writer
  • fixed:annotations.dashboard:reader
  • annotations:type:dashboard
  • annotations:*

After removing or replacing the deprecated permissions, re-run your Terraform apply or role provisioning.


Related What's new posts