b13/restricted-domains

Restrict single domains of a TYPO3 site to logged-in backend users.

Maintainers

Package info

github.com/b13/restricted-domains

Homepage

Type:typo3-cms-extension

pkg:composer/b13/restricted-domains

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-08-15 07:56 UTC

This package is auto-updated.

Last update: 2026-08-15 07:56:15 UTC


README

CI

EXT:restricted_domains - Close single domains of a TYPO3 site for the public

A site is often reachable under more than one domain: the public one, plus a CMS/editing domain editors work on, plus whatever the staging setup adds. Those extra domains serve the very same page tree, so everything reachable there is duplicate content for crawlers and an unintended second entry point for visitors.

This extension closes such a domain for everybody but logged-in backend users.

Features

  • Marks a whole site or a single base variant as "backend users only" - right in the site configuration
  • Lets whole networks in without a login: office, VPN or monitoring addresses as an IP list, wildcard or CIDR range
  • Works with a checkbox in the Sites backend module, no TypoScript and no template changes needed
  • Answers denied requests with a 403 Forbidden (or 404, if you prefer) and an X-Robots-Tag: noindex, nofollow header
  • Ships a small, self-contained "access denied" page that links to the backend, and lets you rebrand it with your own Fluid template
  • Leaves the TYPO3 backend itself untouched, so editors can always log in
  • Supports TYPO3 v12.4, v13, v14 and v15 from a single extension version

Why did we create this extension?

Editing domains are a fact of life in bigger projects: cms.example.com next to www.example.com, a staging domain next to both. Technically they are the same site, and TYPO3 happily delivers the complete page tree under every one of them.

The usual workarounds all have a catch. Blocking the domain in the web server means editors cannot preview anything. robots.txt and noindex are advisory and do nothing against a visitor who has the URL. Basic authentication needs a second set of credentials that nobody wants to maintain, and it breaks preview links.

EXT:restricted_domains uses the credentials that are already there - the backend login. If a backend user is logged in, the domain behaves exactly as before, previews included. Everybody else gets a 403.

Installation

Install this extension via composer req b13/restricted-domains or download it from the TYPO3 Extension Repository and activate it in the Extension Manager of your TYPO3 installation.

Configuration

Mark a domain as restricted in the site configuration - either in the Sites backend module or directly in config/sites/<identifier>/config.yaml.

Restrict a single base variant:

base: 'https://www.example.com'
baseVariants:
  -
    base: 'https://cms.example.com'
    condition: 'applicationContext == "Production/Editing"'
    requireBackendUserLogin: true

Base variant conditions are evaluated without a request - the variables at hand are applicationContext, getenv() and the other ones TYPO3 offers for site configuration, but not the host of the current request. A variant therefore describes the domain of an environment (the editing instance, staging, local development), not a second domain served by the same instance. To close a domain that the very same instance serves next to the public one, restrict the site as a whole on that instance, or give the editing instance its own application context.

Restrict the site as a whole, no matter which domain it is served under:

base: 'https://staging.example.com'
requireBackendUserLogin: true

The flag of the base variant that is active for the current request wins. Only if that variant does not carry the flag at all - or if no variant matches and the plain base is in use - the site-level flag applies. This way a single domain can opt in or out independently of the site.

Letting IP addresses in without a login

A restricted domain is not only open to logged-in backend users: requests coming from an address in allowedIpAddresses are answered as well. That covers the office network, a VPN, an uptime monitor or a screenshot service - anything that cannot log in but should still see the site.

base: 'https://staging.example.com'
requireBackendUserLogin: true
allowedIpAddresses: '192.168.0.0/24, 203.0.113.*, 2001:db8::/32'

The list uses the same notation as everywhere else in TYPO3: comma-separated, IPv4 and IPv6, wildcards (192.168.*.*), CIDR ranges (192.168.0.0/24) and * for any address. A YAML list of addresses works as well. Base variants carry the setting too, and a list on the active variant takes precedence over the one of the site - an empty one, however, falls back to the site instead of denying everybody:

baseVariants:
  -
    base: 'https://cms.example.com'
    condition: 'applicationContext == "Production/Editing"'
    requireBackendUserLogin: true
    allowedIpAddresses: '203.0.113.10'

The address is taken from TYPO3's NormalizedParams, so a setup behind a reverse proxy or load balancer needs the usual $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'] configuration to see the real client address - otherwise every visitor arrives with the proxy's address.

Leaving allowedIpAddresses empty (the default) means the backend login is the only way in.

What a denied request gets

A 403 Forbidden carrying a small, self-contained HTML page with a link to the backend, plus an X-Robots-Tag: noindex, nofollow header. Both can be changed in the extension configuration:

Setting Default Meaning
statusCode 403 403 states that the domain exists but is closed, 404 hides it entirely.
templateRootPath EXT:restricted_domains/Resources/Private/Templates/ Point this at your own directory holding an AccessDenied.html to rebrand the page.

The template is rendered with Fluid and gets {backendUri} assigned.

Known limitation

The core eID middleware (typo3/cms-frontend/eid) resolves ahead of this one, so extension eID endpoints stay reachable on a restricted domain.

Compatibility

Extension version TYPO3 versions
0.1.x v12.4, v13, v14, v15

The extension talks to the view layer through a small adapter, because TYPO3 v13.3 introduced the ViewFactory and v14 removed StandaloneView - so the "access denied" template renders the same on every supported version, including your own template override.

Running the tests

composer install
composer ci:tests:unit
typo3DatabaseDriver=pdo_sqlite composer ci:tests:functional
composer ci:php:cgl
composer ci:php:stan

The functional tests send real frontend requests through the middleware stack, so they need a database - sqlite is the least setup, any other TYPO3-supported database works as well. CI runs the whole set against v12, v13 and v14 on the PHP versions each of them supports; the v15 job follows once v15 is released.

License

The extension is licensed under GPL v2+, same as the TYPO3 Core. For details see the LICENSE file in this repository.

Credits

This extension was created by Benni Mack in 2026 for b13 GmbH, Stuttgart.

Find more TYPO3 extensions we have developed that help us deliver value in client projects. As part of the way we work, we focus on testing and best practices to ensure long-term performance, reliability, and results in all our code.