Deployment Scenarios
Passkeys are bound to a specific domain (the Relying Party ID). This chapter explains how to configure the extension across different environments and how to handle common deployment patterns.
On this page
Single environment
The simplest setup: one TYPO3 instance with one domain.
Leave rpId and origin empty (the default). The extension auto-detects both values from the incoming HTTP request. Each passkey is registered against the domain it was created on.
This works for:
- A single production instance (e.g.
cms.example.com) - A local DDEV site (e.g.
mysite.ddev.site)
No additional configuration is needed.
Multi-environment (local / staging / production)
A typical setup has three environments:
- Local development:
mysite.ddev.site(ormysite.local) - Staging:
staging.example.com - Production:
www.example.com
Recommended: separate passkeys per environment
Leave rpId empty on all environments. Each environment auto-detects its own domain, so passkeys are environment-specific. Users register a separate passkey on each environment they need access to.
Modern authenticators (iCloud Keychain, Windows Hello, 1Password, YubiKey) make registering on multiple environments trivial -- it takes about 10 seconds per environment.
Tip
This is the recommended approach. It avoids sharing secrets across environments and keeps each environment fully independent.
Environment-specific configuration
Use TYPO3_CONTEXT to apply different settings per environment:
// Production and Staging: enforce passkey-only login
if (str_starts_with((string)getenv('TYPO3_CONTEXT'), 'Production')) {
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['nr_passkeys_be']['disablePasswordLogin'] = '1';
}
// Development: keep password login available for convenience
// (disablePasswordLogin defaults to '0', no override needed)
This lets you enforce passkey-only login on production while keeping password login available locally for new users or quick access.
Important
Before enabling disablePasswordLogin on production:
- Verify all regular backend users have registered at least one passkey.
- Ensure at least one admin account has multiple passkeys on different authenticators for emergency recovery.
- Communicate the change to all backend users in advance.
- Consider enabling on staging first to verify the workflow.
Database synchronisation
When syncing the production database to staging or local (a common workflow), the passkey credential table will contain credentials bound to the production domain. These credentials will not work on a different domain.
Exclude the credential table from database syncs:
mysqldump --ignore-table=mydb.tx_nrpasskeysbe_credential mydb > dump.sql
ignore_tables:
- tx_nrpasskeysbe_credential
After importing a production database dump, users simply register fresh passkeys on the local or staging environment. If disablePasswordLogin is active but environment-specific (see above), password login is available on non-production environments for this initial registration.
Note
You do not need to exclude be_users or any other table. Only
tx_nrpasskeysbe_credential is domain-specific. If the credential
table is accidentally included in a sync, the imported credentials
will not work on the different domain -- users simply register fresh
passkeys. No security data is exposed because the public keys are
useless without the private keys stored on users' authenticators.
User onboarding
Onboarding workflow with disablePasswordLogin
When disablePasswordLogin is enabled, the extension enforces passkey-only login per user: password login is blocked only for users who have at least one registered passkey. Users without passkeys can still log in with a password.
This enables a smooth onboarding workflow:
- Admin creates a new backend user with a password (as usual in TYPO3).
- User logs in with their password for the first time.
- User registers a passkey in User Settings > Passkeys.
- From this point on, the user must use their passkey -- password login is no longer accepted for this account.
Note
An admin cannot register a passkey on behalf of another user. The WebAuthn ceremony requires physical interaction with the user's own authenticator (TouchID, YubiKey, etc.).
Recovery scenarios
If a user loses access to their authenticator:
- An admin revokes the user's passkeys via the Admin API. Each revocation is recorded with the admin's UID and timestamp for audit purposes.
- Once all passkeys are revoked, password login becomes available again for that user (the per-user enforcement lifts when no active credentials remain).
- The user logs in with their password and registers a new passkey.
Tip
Consider requiring users to register at least two passkeys on different authenticators (e.g. laptop + phone) for redundancy.
Containerized and multi-server deployments
When running TYPO3 in Docker containers or behind a load balancer, the file-based cache backends lose state on container restart and are not shared across servers. This affects nonce replay protection and rate limiting.
See Multi-server cache backends for Redis configuration, and Reverse proxy and IP detection for rate limiting behind a load balancer.
Local development with DDEV
DDEV sites (*.ddev.site) use HTTPS by default and are treated as
secure contexts by browsers. Passkeys work out of the box.
ddev start
# Open https://mysite.ddev.site/typo3 -- passkeys work immediately
For http://localhost (without HTTPS), most browsers also treat this
as a secure context, so passkeys will work. However, custom local
domains over plain HTTP (e.g. http://mysite.local) will not
work -- WebAuthn requires a secure context.
See also Troubleshooting: HTTPS requirement.
See also
Security: Production deployment requirements for trusted hosts pattern, reverse proxy configuration, and multi-server cache backends.