---
title: "Important: #94246 - Generic sudo mode configuration"
manual: "TYPO3 Core Changelog"
version: "main"
permalink: "https://docs.typo3.org/permalink/changelog:important-94246-1681366863"
source: "Changelog/12.4/Important-94246-GenericSudoModeConfiguration.rst"
typo3-version: "12.4"
typo3-major: 12
type: "important"
issue: 94246
forge: "https://forge.typo3.org/issues/94246"
tags: ["Backend", "ext:backend"]
rendered: "2026-09-20T18:31:11+00:00"
---

# Important: #94246 - Generic sudo mode configuration {#important-94246-1681366863}

See [forge#94246](https://forge.typo3.org/issues/94246)

## Description {#description}

[Sudo mode](https://docs.typo3.org/permalink/changelog:important-92836)
has been integrated since TYPO3 v9.5.x to protect only Install Tool components. With TYPO3 v12
it has been changed to a generic configuration for backend routes (and implicitly modules).

Besides that, access to the Extension Manager now needs to pass the sudo mode verification as well.

### Process in a nutshell {#process-in-a-nutshell}

All simplified classnames below are located in the namespace `\TYPO3\CMS\Backend\Security\SudoMode\Access`).
The low-level request orchestration happens in the middleware `\TYPO3\CMS\Backend\Middleware\SudoModeInterceptor`,
markup rendering and payload processing in controller `\TYPO3\CMS\Backend\Controller\Security\SudoModeController`.

1.  A backend route is processed, that requires sudo mode for route URI `/my/route`
    in `\TYPO3\CMS\Backend\Http\RouteDispatcher`.
1.  Using `AccessFactory` and `AccessStorage`, the `RouteDispatcher`
    tries to find a valid and not expired `AccessGrant` item for the specific
    `RouteAccessSubject('/my/route')` aspect in the current backend user session data.
1.  In case no `AccessGrant` can be determined, a new `AccessClaim` is created
    for the specific `RouteAccessSubject` instance and temporarily persisted in the
    current user session data - the claim also contains the originally requested route
    as `ServerRequestInstruction` (a simplified representation of a `ServerRequestInterface`).
1.  Next, the user is redirected to the user interface for providing either their own password, or
    the global install tool password as alternative.
1.  Given, the password was correct, the `AccessClaim` is "converted" to an
    `AccessGrant`, which is only valid for the specific subject (URI `/my/route`)
    and for a limited lifetime.

### Configuration {#configuration}

In general, the configuration for a particular route or module looks like this:

```php
<?php
// ...
'sudoMode' => [
    'group' => 'individual-group-name',
    'lifetime' => AccessLifetime::veryShort,
],
```

-   `group` (optional): if given, grants access to other objects of the same `group`
    without having to verify sudo mode again for a the given lifetime. Example:
    Admin Tool modules **Maintainance** and **Settings** are configured with the same
    `systemMaintainer` group - having access to one (after sudo mode verification)
    grants access to the other automatically.
-   `lifetime`: enum value of `\TYPO3\CMS\Backend\Security\SudoMode\Access\AccessLifetime`,
    defining the lifetime of a sudo mode verification, afterwards users have to go through
    the process again - cases are `veryShort` (5 minutes), `short` (10 minutes),
    `medium` (15 minutes), `long` (30 minutes), `veryLong` (60 minutes)

For backend routes declared via `Configuration/Backend/Routes.php`, the
relevant configuration would look like this:

```php
<?php
return [
    'my-route' => [
        'path' => '/my/route',
        'target' => MyHandler::class . '::process',
        'sudoMode' => [
            'group' => 'mySudoModeGroup',
            'lifetime' => AccessLifetime::short,
        ],
    ],
];
```

For backend modules declared via `Configuration/Backend/Modules.php`, the
relevant configuration would look like this:

```php
<?php
return [
    'tools_ExtensionmanagerExtensionmanager' => [
        // ...
        'routeOptions' => [
            'sudoMode' => [
                'group' => 'systemMaintainer',
                'lifetime' => AccessLifetime::medium,
            ],
        ],
    ],
];
```
