doc/development/permissions/role_definitions.md
Default roles in GitLab are defined using YAML files in config/authz/roles/.
Each file defines a single role, its permissions, and its inheritance hierarchy.
The Authz::Role class loads these files at runtime, resolves inherited permissions,
and expands assignable permission groups into their constituent raw permissions.
Each role definition file follows this structure:
# config/authz/roles/<role_name>.yml
---
name: developer
description: Developer role
inherits_from:
- reporter
raw_permissions:
- push_code
- create_pipeline
permissions:
- read_work_item
| Field | Required | Type | Description |
|---|---|---|---|
name | yes | String | Unique, lowercase, underscored name matching the filename. |
description | yes | String | Human-readable description of the role. |
inherits_from | yes | Array | List of parent role names. Use [] for roles with no parent. |
raw_permissions | no | Array | Permissions granted directly by this role. These are individual permission atoms defined in config/authz/permissions/. |
permissions | no | Array | Assignable permission group names. Each name references a group defined in config/authz/permission_groups/assignable_permissions/ and is expanded into its constituent raw permissions at load time. |
When Authz::Role.get(:developer) is called:
config/authz/roles/developer.yml is loaded and cached.inherits_from list is resolved recursively. For each parent role,
the same loading and resolution process is applied.permissions are expanded via
Authz::PermissionGroups::Assignable. Each group maps to one or more raw permissions.raw_permissions from this rolepermissions (assignable groups) from this roleGiven these role definitions:
# guest.yml
name: guest
inherits_from: []
raw_permissions:
- read_issue
- create_issue
# reporter.yml
name: reporter
inherits_from:
- guest
raw_permissions:
- read_code
- download_code
# developer.yml
name: developer
inherits_from:
- reporter
raw_permissions:
- push_code
- create_pipeline
Calling Authz::Role.get(:developer).permissions returns:
[:read_issue, :create_issue, # inherited from guest
:read_code, :download_code, # inherited from reporter
:push_code, :create_pipeline] # direct from developer
Role YAML files are one layer of the GitLab permission architecture. Understanding how they relate to other components:
Defined in config/authz/permissions/<resource>/<action>.yml. These are the
atomic units of authorization — each represents a single action on a single
resource (for example, read_issue, create_pipeline). Raw permissions are referenced
directly in raw_permissions arrays in role YAML files and in policy enable/prevent calls.
For details on creating and naming raw permissions, see Permission conventions.
Defined in config/authz/permission_groups/assignable_permissions/<category>/<resource>/<action>.yml.
These bundle multiple raw permissions into user-facing capability sets that can be
assigned to roles or used for granular PAT scoping.
For example, the read_pipeline assignable permission group might expand to:
# config/authz/permission_groups/assignable_permissions/ci_cd/pipeline/read.yml
name: read_pipeline
description: Grants the ability to read pipelines
permissions:
- read_pipeline
- read_pipeline_bridge
- read_pipeline_job
boundaries:
- project
When a role YAML file lists read_pipeline under its permissions field, all three
raw permissions are granted to that role.
DeclarativePolicy classes (app/policies/) define the runtime
authorization rules that evaluate whether a user can perform an action. Policy rules
reference raw permissions via enable and prevent calls. Role YAML files
determine which permissions a user holds based on their role, and policies
determine the conditions under which those permissions are evaluated.
Defined in ee/config/custom_abilities/. These allow Ultimate customers to create
custom roles with specific abilities. Custom ability YAML files include
project_permissions and group_permissions fields that map to raw permissions,
similar to how role YAML files use raw_permissions. See Custom roles
for details.
When adding or removing permissions from a role:
raw_permission is acceptable.GITLAB_DEBUG_POLICIES=true (see Custom roles)
to trace where a permission is checked.