Grafana · Arazzo Workflow

Grafana Assign a Custom RBAC Role to a Team

Version 1.0.0

Create a custom role with explicit permissions, resolve a team by name, and assign the role to it.

1 workflow 5 source APIs 1 provider
View Spec View on GitHub AlertingAnalyticsDashboardsLogsMetricsMonitoringObservabilityTracesVisualizationArazzoWorkflows

Provider

grafana

Workflows

assign-custom-role-to-team
Create a custom RBAC role and bind it to a team.
Creates the role with its permission list, verifies it, resolves the target team by name, sets the team's roles, and reads the assignment back.
5 steps inputs: description, displayName, global, group, includeHidden, permissions, roleName, teamName, uid, version outputs: roleUid, teamId, teamRoles
1
createRole
Create the custom role with an explicit list of actions and scopes. Keep the permission list narrow; this is the whole reason for not handing out Admin.
2
verifyRole
Read the role back by UID to confirm the permissions Grafana actually stored, which is not always the list you sent if an action name was wrong.
3
findTeam
Resolve the team by name, since role assignment addresses teams by a numeric id that differs between instances.
4
assignRoleToTeam
Set the team's roles. This replaces the team's custom role assignments with the supplied list rather than appending to them, so send the full set you want the team to end up with.
5
verifyAssignment
List the team's roles to prove the binding exists. Everyone on the team now holds these permissions, and anyone who leaves the team loses them.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Grafana Assign a Custom RBAC Role to a Team
  summary: Create a custom role with explicit permissions, resolve a team by name, and assign the role to it.
  description: >-
    Grafana's built-in Viewer/Editor/Admin roles run out of road quickly, and the
    usual next move is to make everyone an Admin. Custom RBAC roles are the
    alternative: name a set of actions and scopes, then bind it to a team rather
    than to people, so access follows team membership and leaving the team
    removes it. This workflow creates the role, reads it back, resolves the team
    by name, assigns the role, and lists the team's roles to prove the grant.
    Custom roles are a Grafana Enterprise and Grafana Cloud capability. Every
    step spells out its request inline so the flow can be read and executed
    without opening the underlying OpenAPI description.
  version: 1.0.0
  x-realizes-capability-ids:
  - BC-620.20
  x-capability-derivation:
    method: 'deterministic join: sourceDescriptions -> per-tag OpenAPI -> tag/capability edge. No classification at this step.'
    min_confidence: 0.7
    sources:
    - capability_id: BC-620.20
      capability_name: Identity & Access Management
      spec: grafana-roles-api-openapi.yml
      confidence: 0.85
    model: Turbo EA Capabilities by Vincent Verdet — Turbo EA, https://github.com/vincentmakes/turbo-ea-capabilities, CC BY 4.0
sourceDescriptions:
- name: createApi
  url: ../openapi/grafana-create-api-openapi.yml
  type: openapi
- name: getApi
  url: ../openapi/grafana-get-api-openapi.yml
  type: openapi
- name: listsApi
  url: ../openapi/grafana-lists-api-openapi.yml
  type: openapi
- name: rolesApi
  url: ../openapi/grafana-roles-api-openapi.yml
  type: openapi
- name: searchApi
  url: ../openapi/grafana-search-api-openapi.yml
  type: openapi
workflows:
- workflowId: assign-custom-role-to-team
  summary: Create a custom RBAC role and bind it to a team.
  description: >-
    Creates the role with its permission list, verifies it, resolves the target
    team by name, sets the team's roles, and reads the assignment back.
  inputs:
    type: object
    required:
    - roleName
    - permissions
    - teamName
    properties:
      roleName:
        type: string
        description: >-
          Role name. Custom roles are conventionally prefixed with "custom:"
          (e.g. "custom:dashboards.reader").
      displayName:
        type: string
        description: Human-friendly name shown in the UI.
      description:
        type: string
        description: What the role is for, which future-you will want.
      group:
        type: string
        description: Group the role is listed under in the UI (e.g. "Dashboards").
      permissions:
        type: array
        description: >-
          The actions and scopes the role grants, each an object with an "action"
          and an optional "scope" (e.g. {"action": "dashboards:read", "scope":
          "dashboards:*"}).
        items:
          type: object
      uid:
        type: string
        description: Optional stable UID for the role.
      global:
        type: boolean
        description: >-
          Create the role across all organizations rather than only the current
          one.
        default: false
      version:
        type: integer
        description: Version number for the role definition.
        default: 1
      teamName:
        type: string
        description: Name of the team to assign the role to.
      includeHidden:
        type: boolean
        description: Include hidden roles when replacing the team's role set.
        default: false
  steps:
  - stepId: createRole
    description: >-
      Create the custom role with an explicit list of actions and scopes. Keep
      the permission list narrow; this is the whole reason for not handing out
      Admin.
    operationId: createRole
    requestBody:
      contentType: application/json
      payload:
        name: $inputs.roleName
        displayName: $inputs.displayName
        description: $inputs.description
        group: $inputs.group
        permissions: $inputs.permissions
        uid: $inputs.uid
        global: $inputs.global
        version: $inputs.version
    successCriteria:
    - condition: $statusCode == 201
    outputs:
      roleUid: $response.body#/uid
      roleName: $response.body#/name
      roleVersion: $response.body#/version
  - stepId: verifyRole
    description: >-
      Read the role back by UID to confirm the permissions Grafana actually
      stored, which is not always the list you sent if an action name was wrong.
    operationId: getRole
    parameters:
    - name: roleUID
      in: path
      value: $steps.createRole.outputs.roleUid
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      storedPermissions: $response.body#/permissions
      storedName: $response.body#/name
      delegatable: $response.body#/delegatable
  - stepId: findTeam
    description: >-
      Resolve the team by name, since role assignment addresses teams by a
      numeric id that differs between instances.
    operationId: searchTeams
    parameters:
    - name: name
      in: query
      value: $inputs.teamName
    - name: perpage
      in: query
      value: 1
    successCriteria:
    - condition: $statusCode == 200
    - context: $response.body
      condition: $.teams.length > 0
      type: jsonpath
    outputs:
      teamId: $response.body#/teams/0/id
      teamName: $response.body#/teams/0/name
  - stepId: assignRoleToTeam
    description: >-
      Set the team's roles. This replaces the team's custom role assignments with
      the supplied list rather than appending to them, so send the full set you
      want the team to end up with.
    operationId: setTeamRoles
    parameters:
    - name: teamId
      in: path
      value: $steps.findTeam.outputs.teamId
    requestBody:
      contentType: application/json
      payload:
        roleUids:
        - $steps.createRole.outputs.roleUid
        includeHidden: $inputs.includeHidden
    successCriteria:
    - condition: $statusCode == 200
  - stepId: verifyAssignment
    description: >-
      List the team's roles to prove the binding exists. Everyone on the team now
      holds these permissions, and anyone who leaves the team loses them.
    operationId: listTeamRoles
    parameters:
    - name: teamId
      in: path
      value: $steps.findTeam.outputs.teamId
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      teamRoles: $response.body
  outputs:
    roleUid: $steps.createRole.outputs.roleUid
    teamId: $steps.findTeam.outputs.teamId
    teamRoles: $steps.verifyAssignment.outputs.teamRoles

Work with this as data

Every workflow here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for arazzo workflows

4 MCP tools reach this
  • find_arazzoBrowse and filter every workflow in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This workflow
curl "https://apis.io/api/v1/arazzo/grafana-team-rbac-role-workflow"
All arazzo workflows
curl "https://apis.io/api/v1/arazzo?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.