Backend module access gates 

New in version 14.2

Existing backend module registrations using the built-in access values continue to work without modification:

  • user
  • admin
  • systemMaintainer

The TYPO3 backend module system supports configurable access control through module access gates. Gates determine whether a backend user may access a specific backend module.

TYPO3 provides built-in gates for common access strategies and allows extension authors to register custom gates for project-specific requirements.

Built-in access gates 

TYPO3 ships the following built-in access gates:

  • \TYPO3\CMS\Backend\Module\AccessGate\UserGate ('access' => 'user')
  • \TYPO3\CMS\Backend\Module\AccessGate\AdminGate ('access' => 'admin')
  • \TYPO3\CMS\Backend\Module\AccessGate\SystemMaintainerGate ('access' => 'systemMaintainer')

These gates preserve the traditional backend module access behavior.

UserGate 

The UserGate grants access to:

  • Backend administrators
  • Backend users or groups with explicit module permissions configured in:

    • be_users.userMods
    • be_groups.groupMods

This corresponds to the module access value:

'access' => 'user',
Copied!

AdminGate 

The AdminGate grants access only to backend administrator users.

This corresponds to:

'access' => 'admin',
Copied!

SystemMaintainerGate 

The SystemMaintainerGate grants access only to system maintainers.

This corresponds to:

'access' => 'systemMaintainer',
Copied!

Register a custom access gate 

Extension authors can implement custom access strategies by creating a class that implements \TYPO3\CMS\Backend\Module\ModuleAccessGateInterface .

Custom gates are registered using the #[AsModuleAccessGate] PHP attribute.

The gate must return a \TYPO3\CMS\Backend\Module\ModuleAccessResult value.

Possible results are:

  • ModuleAccessResult::Granted
  • ModuleAccessResult::Denied
  • ModuleAccessResult::Abstain

Example: Custom editor gate 

EXT:examples/Classes/Module/AccessGate/ExampleGate.php
<?php

declare(strict_types=1);

namespace T3docs\Examples\Module\AccessGate;

use TYPO3\CMS\Backend\Module\ModuleAccessGateInterface;
use TYPO3\CMS\Backend\Module\ModuleAccessResult;
use TYPO3\CMS\Backend\Module\ModuleInterface;
use TYPO3\CMS\Core\Attribute\AsModuleAccessGate;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;

#[AsModuleAccessGate(identifier: 'exampleUser')]
class ExampleGate implements ModuleAccessGateInterface
{
    public function decide(
        ModuleInterface $module,
        BackendUserAuthentication $user,
    ): ModuleAccessResult {
        if ($module->getAccess() !== 'exampleUser') {
            return ModuleAccessResult::Abstain;
        }
        $userTsConfig = $user->getTSConfig();
        $exampleUserGroupId = (int)($userTsConfig['options.']['example.']['userGroup'] ?? 0);
        $permission = $user->isAdmin() || in_array($exampleUserGroupId, $user->userGroupsUID);
        return $permission
            ? ModuleAccessResult::Granted
            : ModuleAccessResult::Denied;
    }
}
Copied!

The example above defines a custom access type called exampleUser.

The gate only handles modules whose access option is set to exampleUser. For all other modules, it returns ModuleAccessResult::Abstain.

The gate accesses information about the currently authenticated backend user through the BackendUserAuthentication object passed to the decide() method.

This allows custom gates to implement project-specific permission logic based on user groups, user TSconfig settings, workspace access, user preferences, or other backend user properties.

After registering the gate, use its identifier in the module configuration.

EXT:my_extension/Configuration/Backend/Modules.php
return [
    'my_module' => [
        'access' => 'exampleUser',
        'labels' => 'examples.module.content_examples_clipboard',
        // ...
    ],
];
Copied!

Gate evaluation order 

Multiple gates can be registered simultaneously.

The before and after options of the #[AsModuleAccessGate] attribute define the evaluation order.

use TYPO3\CMS\Backend\Module\ModuleAccessGateInterface;
use TYPO3\CMS\Core\Attribute\AsModuleAccessGate;

#[AsModuleAccessGate(
    identifier: 'exampleUser',
    after: ['user'],
)]
final readonly class ExampleGate implements ModuleAccessGateInterface
{
    // ...
}
Copied!