uandi / ui-permissions
Deployable TYPO3 backend user permissions via YAML configuration files
Installs: 206
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 1
Type:typo3-cms-extension
pkg:composer/uandi/ui-permissions
Requires
- typo3/cms-core: ^12.4.8 || ^13.4
Requires (Dev)
- a9f/typo3-fractor: ^0.5.7
- ergebnis/composer-normalize: ^2.48.2
- friendsofphp/php-cs-fixer: ^3.89.2
- helmich/typo3-typoscript-lint: ^3.3.0
- php-parallel-lint/php-parallel-lint: ^1.4.0
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan: ^2.1.32
- phpstan/phpstan-strict-rules: ^2.0.7
- seld/jsonlint: ^1.11.0
- spaze/phpstan-disallowed-calls: ^4.7.0
- squizlabs/php_codesniffer: ^4.0.1
- ssch/typo3-rector: ^3.8.0
- typo3/coding-standards: ^0.8.0
Replaces
- typo3-ter/ui-permissions: 1.0.0
This package is auto-updated.
Last update: 2025-12-21 13:06:28 UTC
README
Deployable TYPO3 Permissions
TYPO3 extension to declaratively manage backend user group permissions as code.
If you have a TYPO3 project with any level of permissions for backend users you probably ran into one of the following problems:
- Creating the permissions in the TYPO3 backend takes a lot of time and clicks
- If you have different environments like INT, PPE and PROD, you would have to create the permissions on each environment
- You deployed something to PROD and forgot about the permissions until the customer calls because he can't see the new feature
This extension introduces deployable YAML descriptions of permissions that are gathered from all active extensions, merged, and written into the database via a CLI command. This makes permission changes reviewable (VCS), testable, and reproducible across environments.
What it does
- Collects all files matching
*.permissions.yamlfrom every active TYPO3 extension (recursive scan)- These YAML files basically contain abstractions of
be_groupsandsys_filemountsrecords.
- These YAML files basically contain abstractions of
- Merges all found configurations deterministically
- Writes/updates corresponding records in:
sys_filemountsbe_groups
- Resolves relations (e.g.,
be_groups.subgroup,be_groups.file_mountpoints) by referencing other items by their logical keys
Goals
- Treat backend permissions as configuration-as-code
- Enable safe deployments without manual backend tweaking
- Keep environments (INT/PPE/PROD) in sync
- Provide a clear, readable schema that is easy to review in pull requests
- If you know how TYPO3 permissions work and how they are stored in the DB, you'll have no trouble writing the YAML abstractions
Installation
composer require uandi/ui-permissions
Extension configuration (Settings → Extension Configuration)
pidBeGroups(int): PID to store/updatebe_groupsrecordspidSysFilemounts(int): PID to store/updatesys_filemountsrecordscreateFilemountDirectories(bool): Create directories for filemounts if missing
These values are used by the repositories when inserting/updating records.
CLI usage
Run via TYPO3 CLI. This command is ideally executed during deployments.
# Apply the current YAML permissions to the database
vendor/bin/typo3 ui_permissions:update
Where to place YAML files
While the collector scans the whole extension path, the recommended location is:
EXT:your_ext/Configuration/Permissions/YourName.permissions.yamlfor general purposesEXT:your_ext/ContentBlocks/ContentElements/*/permissions/YourName.permissions.yamlfor ContentBlock elements.
Any filename ending with .permissions.yaml is picked up.
Naming conventions (permission files and keys)
Based on the “TYPO3 Backend User Management” concept (naming-for-purpose), use clear, prefixed keys. The map key of each item becomes its durable permission_key (and should also inform the filename):
- R_<Name>: Role groups that aggregate capabilities via
subgroup, e.g.R_Editors,R_EditorsInChief - ACL_<Name>: Access control scopes for single tables/features/CTypes, e.g.
ACL_tt_content_common,ACL_contentelement_gallery - FM_<Name>: Filemount definitions and helper groups that attach filemounts, e.g.
FM_ProjeectIcons - DB_<Name>: Database (page tree) mounts, e.g.
DB_Projeect - PG_<Name>: Page-related presets, e.g.
PG_Projeect - L_<Name>: Language-related presets for accessible languages, e.g.
L_Spanish
Further reading
- https://archive-2019.typo3worx.eu/2017/02/typo3-backend-user-management/
- https://punkt.de/de/blog/2017/typo3-backend-berechtigungen.html
Recommendations
- Keep keys unique and stable; they act as IDs across environments
- Name files accordingly, e.g.
R_Editors.permissions.yamlcontaining abe_groups: R_Editors: ...definition - Compose roles (R_) from ACL_ and FM_* using
subgroupandfileMountpoints
YAML schema
As was already noted, the YAML files are abstractions of the database records. So the top level keys describe which table we're dealing with:
sys_filemounts: map of filemounts by a unique key ("permission key")be_groups: map of backend groups by a unique key ("permission key")
Each item’s map key becomes its permission_key in the database and is used to reference between items.
sys_filemounts item fields
permission_key(string, optional - map key will be used if missing)title(string, optional - map key will be used if missing)description(string, optional)identifier(string, e.g.1:/assets)readOnly(bool, default: false)
Legacy support: If identifier is missing, the pair base + path will be converted to identifier (base:path).
be_groups item fields (selection)
permission_key(string, optional - map key will be used if missing)title(string, optional - map key will be used if missing)description(string, optional)tablesModify(array|string CSV)tablesSelect(array|string CSV)pagetypesSelect(array|int|string CSV)nonExcludeFields(maptable: [field, ...]or strings/CSV)explicitAllowdeny(map of tables → fields → [values])- Legacy support:
explicitAllowdeny: { allow: { table: { field: [values] } } }also accepted
- Legacy support:
dbMountpoints(array|int|string CSV of page IDs)fileMountpoints(array of filemount permission keys)filePermissions(array|string CSV)subgroup(array|string CSV of other be_group permission keys)groupMods(array|string CSV)TSconfig(string)allowedLanguages(array|string CSV of sys_language uids)customOptions(array|string CSV)mfaProviders(array)
Some fields are resolved after initial persistence (e.g., subgroup, fileMountpoints). See Classes/Domain/Repository/BackendUserGroupRepository.php for some insights.
Merge behavior
Merging is custom (see ConfigurationCollector::mergeConfiguration()):
- Associative arrays are merged recursively; later values override earlier scalars
- List arrays are concatenated and
array_unique()-ed
This enables layering configurations across multiple extensions.
Examples
Examples of permissions files
Example ACL for a content element (CType)
be_groups: ACL_contentelement_gallery: tables_select: tt_content tables_modify: tt_content explicit_allowdeny: tt_content: CType: - contentelement_gallery
Example role composed of many ACLs
be_groups: R_Editors: pagetypes_select: 1, 3, 4, 199, 254 subgroup: - ACL_form_formframework - ACL_pages_common - ACL_sys_file_metadata - ACL_sys_file_reference - ACL_tt_content_common - ACL_tt_content_shortcut # Content Elements - ACL_contentelement_gallery - ACL_contentelement_media - ACL_contentelement_quote - ACL_contentelement_stage - ACL_contentelement_teaser - ACL_contentelement_textmedia # Grids - ACL_contentelement_grid2columns50-50 - ACL_contentelement_grid3columns33-33-33 - ACL_contentelement_grid4columns25-25-25-25 groupMods: - web_layout - media_management - user_setup
Example filemounts (FM_*) and their respective be_groups
sys_filemounts: FM_ProjeectIcons: title: 'Assets' description: 'Base Fileadmin Folder for Icons' identifier: '1:/user_upload/Projeect/Icons/' FM_ProjeectIcons_ReadOnly: title: 'Icons' description: 'Base Fileadmin Folder for Icons (Read Only)' identifier: '1:/user_upload/Projeect/Icons/' read_only: 1 be_groups: FM_ProjeectIcons: file_mountpoints: - FM_ProjeectIcons FM_ProjeectIcons_ReadOnly: file_mountpoints: - FM_ProjeectIcons_ReadOnly
Example database mount (DB_*)
be_groups: DB_Projeect: db_mountpoints: 1
Tips
- Keep permission keys unique and stable; they become the durable identifier (
permission_key) across environments - Split large setups into multiple files; merging will combine them
- Prefer arrays over CSV for readability, but both are supported in many fields
What's next
- CLI Command to create YAML files from existing permissions in the database to make it easier to introduce this extension to existing projects
- Maybe try to introduce some level of plausibility/error checks to make it easier to find misconfigurations in the YAML abstraction files