doc/development/permissions/granular_access/permission_definitions.md
Each permission should have a corresponding definition file (also called a "raw permission"). These files are used to build documentation and enable a permissions-first architecture around authorization logic.
Generate the permission definition and resource metadata files using the bin/permission command.
Interactive mode — pass just the permission name and the command walks you through each field, using the name to suggest defaults:
bin/permission <permission_name>
Non-interactive mode — pass -a (action) and -r (resource) as flags to skip prompts. The description auto-defaults to "Grants the ability to <action> <resource>". Add -c to also skip the feature category prompt:
bin/permission <permission_name> -a <action> -r <resource> -c <feature_category>
Overriding the action or resource is helpful when the action is more than one word. For example, consider the permission force_delete_ai_catalog_item. By default the command splits the name at the first underscore, suggesting force as the action and delete_ai_catalog_item as the resource. This would result in the definition file being written to config/authz/permissions/delete_ai_catalog_item/force.yml, which is incorrect.
The following command generates a definition file with the correct action and resource, writing it to config/authz/permissions/ai_catalog_item/force_delete.yml:
bin/permission force_delete_ai_catalog_item -a force_delete -r ai_catalog_item -c ai_catalog
Any field can be overridden with a flag (for example -d for a custom description). Run bin/permission --help for all available options.
This creates two files:
A permission definition at config/authz/permissions/<resource>/<action>.yml:
---
name: read_job
description: Grants the ability to read CI/CD jobs
A resource metadata file at config/authz/permissions/<resource>/.metadata.yml (if one does not already exist):
---
feature_category: continuous_integration
| Field | Description |
|---|---|
name | Permission name (auto-populated from the action and resource) |
description | Human-readable description of what the permission allows |
The resource metadata file is created once per resource directory. When you add a second permission for the same resource, the command detects the existing metadata and skips all metadata prompts (feature category, display name, and description).
Required Fields:
feature_category (required) - Must be a valid entry from config/feature_categories.yml. Look at existing endpoints in the API file for that resource to find the correct feature category. For example, CI/CD endpoints typically use continuous_integration, while package-related endpoints use package_registry.Optional Fields:
name - Overrides the titleized resource name for displaydescription - Provides context about what permissions in this resource group grantThe validation task (bundle exec rake gitlab:permissions:validate) enforces several constraints:
Permission Name Format:
For guidance on how to name permissions, see Naming Permissions.
Action Words:
For a list of disallowed actions, see Disallowed Actions.
File Structure:
config/authz/permissions/<resource>/<action>.ymlAll violations are caught automatically by Lefthook's pre-push hook when running git push. You can also run the validation manually with bundle exec rake gitlab:permissions:validate.