Bolt CMS (v5+) uses a Symfony-based permission system with roles defined in YAML configuration. Permissions are granted per content type and per admin section.
Built-in Roles
| Role | Dashboard | Create Content | Edit All Content | Manage Users | Manage Settings | File Manager |
|---|---|---|---|---|---|---|
| ROLE_ADMIN | Yes | Yes | Yes | Yes | Yes | Yes |
| ROLE_CHIEF_EDITOR | Yes | Yes | Yes | No | No | Yes |
| ROLE_EDITOR | Yes | Yes | Own only | No | No | Yes |
| ROLE_USER | Yes | No | No | No | No | No |
ROLE_ADMIN
Full access to everything including user management, configuration editing, system settings, and all content operations.
ROLE_CHIEF_EDITOR
Can manage all content across all content types. Can upload files and manage the media library. Cannot manage users or system settings.
ROLE_EDITOR
Can create content and edit their own content. Cannot edit other users' content or access system settings.
Permission Configuration
Permissions are configured in config/bolt/permissions.yaml:
# config/bolt/permissions.yaml
roles:
ROLE_ANALYTICS_MANAGER:
description: "Can manage analytics configuration"
permissions:
- edit_config # Access to edit config files
- view_files # Access to file manager
content-type-permissions:
pages:
view: [ROLE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
create: [ROLE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
edit: [ROLE_CHIEF_EDITOR, ROLE_ADMIN]
delete: [ROLE_ADMIN]
entries:
view: [ROLE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
create: [ROLE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
edit: [ROLE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
delete: [ROLE_CHIEF_EDITOR, ROLE_ADMIN]
Custom Roles
Add custom roles in permissions.yaml and assign specific content-type and global permissions.
Analytics-Relevant Permissions
Only ROLE_ADMIN (or roles with edit_config permission) can modify Twig templates where analytics scripts are placed:
{# templates/base.html.twig - Add analytics in <head> #}
<head>
{{ block('meta') }}
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
</head>
Best Practices
- Use
ROLE_CHIEF_EDITORfor content managers who do not need system access - Create a custom
ROLE_ANALYTICS_MANAGERwith only config-editing permissions - Keep
ROLE_ADMINaccounts to a minimum - Store permission changes in version control since they are YAML config files
- Test permission changes in a staging environment before deploying to production