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.

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 (or mysite.local)
  • Staging: staging.example.com
  • Production: www.example.com

Environment-specific configuration 

Use TYPO3_CONTEXT to apply different settings per environment:

config/system/additional.php
// 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
// (disablePasswordLogin defaults to '0')
Copied!

Because enforcement is per user (only users with registered passkeys are affected), enabling disablePasswordLogin on production is safe even if not all users have passkeys yet -- they can still log in with a password. Keeping the setting disabled on development means all users (including those with passkeys) can use password login for convenience.

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:

Example: exclude from mysqldump
mysqldump \
    --ignore-table=mydb.tx_nrpasskeysbe_credential \
    mydb > dump.sql
Copied!
Example: exclude in DDEV
ignore_tables:
  - tx_nrpasskeysbe_credential
Copied!

After importing a production database dump, users simply register fresh passkeys on the local or staging environment. Because enforcement is per user, users with no credentials in the table can log in with a password regardless of the disablePasswordLogin setting.

Shared rpId across subdomains 

WebAuthn allows the rpId to be set to a registrable domain suffix. For example, setting rpId to example.com allows passkeys registered on staging.example.com to also work on www.example.com.

If you still need shared subdomains (e.g. staging and www), set rpId only on those environments and keep local development on auto-detect:

config/system/additional.php
if (str_starts_with(
    (string)getenv('TYPO3_CONTEXT'),
    'Production'
)) {
    $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']
        ['nr_passkeys_be']['rpId'] = 'example.com';
    // Leave 'origin' empty -- auto-detected per
    // subdomain. Setting it explicitly would break
    // verification on other subdomains.
}
// Development: rpId stays empty
// -> auto-detect -> mysite.ddev.site
Copied!