Configuration map
app is the management application (Apache, Django, and the browser interface); idp is the Shibboleth IdP with the passkey plugin. For native installations, these labels identify the corresponding application or IdP host.
| Component | File | Location | Purpose |
|---|---|---|---|
app |
.env |
/var/www/registration-server/.env |
Defines server identity, relying-party ID, Django secret material, host allow-list, and runtime mode. |
app |
env.js |
/var/www/html/passkey/env.js |
Publishes the API base URL and logout URL used by the browser. |
app |
passkey-database.properties |
/var/www/registration-server/passkey-database.properties |
Points Django at the shared PostgreSQL or MySQL/MariaDB backend. Must target the same backend as the IdP copy. |
app |
omnipasskey.conf |
/etc/apache2/conf-available/omnipasskey.conf (Debian/Ubuntu)/etc/httpd/conf.d/omnipasskey.conf (Rocky Linux/RHEL and the shipped container) |
Controls routing, session protection, admin and helpdesk access, and the internal inline-registration alias. |
idp |
passkey-database.properties |
${idp.home}/conf/authn/passkey-database.properties |
Points the IdP plugin at the shared PostgreSQL or MySQL/MariaDB backend. Must target the same backend as the app copy. |
idp |
passkey.properties |
${idp.home}/conf/authn/passkey.properties |
Controls relying-party values, authentication modes, conditional mediation, diagnostics, and inline-registration behavior. |
idp |
authn.properties |
${idp.home}/conf/authn/authn.properties |
Controls which Shibboleth authentication flows are enabled and, when passkeys are fronted by authn/MFA, which principals the top-level MFA flow advertises. |
idp |
mfa-authn-config.xml |
${idp.home}/conf/authn/mfa-authn-config.xmlMerge source: ${idp.home}/conf/authn/mfa-authn-config.xml.passkey |
Defines how passkey-related authentication steps participate in your MFA map. |
idp |
login.vm |
${idp.home}/views/login.vmPasskey-enabled source: ${idp.home}/views/login.vm.passkey |
Provides the password login page and, when the passkey-enabled version is activated, the passkey button and conditional passkey prompt. |
${idp.home} is the Shibboleth IdP installation directory, commonly /opt/shibboleth-idp. In the extracted container source, the management files begin under app/container_files/; the paths above are where Apache, Django, and the browser use them in the running container or native package installation.
Management interface settings
Application environment file
The management interface uses /var/www/registration-server/.env for core server identity values.
SERVER_NAME="Example University"
ID=example.edu
DJANGO_SECRET_KEY=<strong-random-secret>
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,app.example.edu
DJANGO_DEBUG=false
SERVER_NAMEis the friendly organization name shown to the WebAuthn server logic.IDis the WebAuthn relying-party ID and must match the IdP plugin configuration.DJANGO_ALLOWED_HOSTSshould include the management interface hostname.DJANGO_DEBUGshould remainfalsein customer-facing deployments.
Frontend runtime configuration
The frontend reads its API base and logout target from /var/www/html/passkey/env.js.
window.__ENV__ = {
API_BASE: "https://app.example.edu",
LOGOUT_URL: "https://app.example.edu/Shibboleth.sso/Logout"
}
API_BASE must point at the user-facing OmniPasskey host. The default LOGOUT_URL uses the local Shibboleth SP logout handler. If your institution requires combined SP/IdP logout, deploy that page separately and point LOGOUT_URL to it.
Apache and Shibboleth authorization
The shipped omnipasskey.conf enforces Shibboleth sessions for the customer-facing application and starts with deny-by-default blocks for privileged areas.
/passkey/adminand/registration-server/webauthn/adminstay denied until you add your admin allow-list./passkey/helpdeskand/registration-server/webauthn/helpdeskstay denied until you add your helpdesk allow-list./registration-server-backendstays denied until you explicitly allow only the IdP host or network.
# Example admin policy
Require shib-user admin1@example.edu admin2@example.edu
# Example attribute-based policy
Require shib-attr eduPersonEntitlement urn:mace:example.edu:passkey:admin
Branding
The management interface can be branded with a custom logo and a simple theme override.
-
Replace
/var/www/html/logo.pngto show your organization’s logo in the application header. The image is scaled to fit without cropping; in the desktop navigation it is displayed at 24px high and no more than 72px wide.There is no application-enforced file-size or source-dimension limit for
logo.png. Use a reasonably sized PNG with the desired aspect ratio; very large files increase page-load costs, and very wide or tall logos will be scaled down in the available display areas. -
Add
/var/www/html/theme.jsonwith a custom primary color if you want the interface to follow your design palette.{ "main": "#244278" }
IdP plugin settings
Passkey flow properties
Set the following values in ${idp.home}/conf/authn/passkey.properties.
idp.authn.passkey.relyingPartyId=example.edu
idp.authn.passkey.relyingPartyOrigin=https://idp.example.edu
idp.authn.passkey.relyingPartyName=Example University IdP
relyingPartyIdmust match the management interfaceIDvalue.relyingPartyOriginis the exact origin of the IdP, not the OmniPasskey management host.relyingPartyNameis the friendly name shown by authenticators during passkey ceremonies.
Choose the authentication pattern
Conditional mediation helps users sign in with an existing discoverable passkey by offering it in the login form’s autofill suggestions on supported browsers. Inline registration helps users create a passkey after a successful password sign-in, so they can use it on future visits without going to the management interface. You can enable both: one makes sign-in easier, and the other encourages enrollment.
Passkey after Password
Set idp.authn.passkey.2fa=true and idp.authn.passkey.2fa.factorsAllowed=authn/Password, enable authn/MFA, and add a Password-success transition to authn/passkey in your MFA map. The properties authorize the factor sequence; the MFA transition map actually runs it.
Passwordless with username collection
Set idp.authn.passkey.usernameless=false when the IdP should collect the username first and then ask the authenticator for one of that user’s registered credentials.
Usernameless with automatic prompts
Let users choose an existing discoverable passkey without first entering a username. Follow Activate the passkey-enabled login page below to enable conditional mediation and connect the login page to the MFA flow.
Match this IdP-side choice to the policy you configure in OmniPasskey. The IdP setting idp.authn.passkey.2fa=true globally permits second-factor use; it does not make every passkey MFA-only or disable primary-factor passkey use. The Default MFA Rule and per-device MFA Only choices decide whether a device type may be used as a primary factor. An MFA-only device requires idp.authn.passkey.2fa=true and a completed first factor listed in idp.authn.passkey.2fa.factorsAllowed. Otherwise, it is blocked as both a primary and a second factor.
MFA configuration
The plugin ships a passkey-oriented MFA configuration example. Merge the passkey-specific transitions into your live MFA map rather than replacing your full MFA policy.
Enable the MFA flow in ${idp.home}/conf/authn/authn.properties:
idp.authn.flows = MFA
The installed conf/authn/mfa-authn-config.xml.passkey example starts with Password, accepts the passkey events raised by the combined login page, and can branch after a successful password into inline registration. For a required Password-then-Passkey sequence, adapt the successful authn/Password transition so it selects authn/passkey; do not leave success unmapped, because an unmapped proceed event ends the MFA flow. Keep any existing risk, attribute, or service-provider-specific branches in your live mfa-authn-config.xml.
Activate the passkey-enabled login page
For Usernameless with automatic prompts, enable these settings in ${idp.home}/conf/authn/passkey.properties. Both default to true; setting them explicitly makes the intended behavior clear.
idp.authn.passkey.usernameless=true
idp.authn.passkey.conditionalMediation=true
Complete the MFA configuration above, including the usePasskey transition from authn/Password that uses PasskeyRequestedFlowStrategy. Then activate the template below: the properties alone do not add passkey suggestions to the stock IdP login page.
The plugin installs ${idp.home}/views/login.vm.passkey beside the IdP’s active views/login.vm. It is not activated automatically, because replacing login.vm could overwrite local branding and login customizations. The supplied page adds the passkey button, conditional mediation, and the events expected by the sample MFA transitions.
Back up or version-control the active template, merge any site-specific changes, and then make the passkey-enabled template the active login page. For an uncustomized IdP, this can be as simple as:
cd /opt/shibboleth-idp
cp views/login.vm views/login.vm.before-passkey
cp views/login.vm.passkey views/login.vm
Restart the IdP and test both the Password and Passkey choices. After an IdP or theme update, compare the active template with both the new IdP default and login.vm.passkey before carrying the customization forward.
Test automatic suggestions with a registered discoverable passkey in a browser that supports conditional mediation. Users still select a passkey and complete the authenticator’s verification; enabling suggestions does not silently sign them in. The passkey button remains available when suggestions are unavailable. To keep usernameless sign-in through the button without automatic suggestions, set idp.authn.passkey.conditionalMediation=false.
Supported principals and assurance signaling
If passkeys are exposed through authn/MFA, the assurance classes advertised by the dedicated passkey flow and by the top-level MFA flow must match the branches your transition map can really satisfy.
| Property | Why it matters |
|---|---|
idp.authn.passkey.supportedPrincipals |
Defines the classrefs the passkey flow itself is allowed to assert when it completes successfully. Configure values that accurately describe the assurance provided by the flow. |
idp.authn.MFA.supportedPrincipals |
Defines what the top-level MFA flow advertises to service providers. Replace the stock sample with values your real MFA branches can produce. |
Inline registration controls
Enable inline registration when you want password users to enroll a passkey during sign-in, or want to encourage additional backup passkeys. It is disabled by default and can be used whether or not conditional mediation is enabled.
-
Set these properties in
${idp.home}/conf/authn/passkey.properties, replacingapp.example.eduwith your management application hostname:idp.authn.passkey.inlineRegistration.enabled=true idp.authn.passkey.inlineRegistration.backendUrl=https://app.example.edu/registration-server-backend/webauthn/idp/inline-registration idp.authn.passkey.inlineRegistration.promptTargetPasskeys=1 idp.authn.passkey.inlineRegistration.promptIntervalDays=30 - Enable
authn/MFAas described in MFA configuration. Merge the sampleauthn/Passwordsuccess (proceed) transition toPasskeyInlineRegistrationFlowStrategyinto your live${idp.home}/conf/authn/mfa-authn-config.xml, preserving your existing authentication policy. This transition runs the enrollment step after password authentication. - On the app host, update the
<Location /registration-server-backend>block inomnipasskey.confto allow only the IdP host or network. See installation step 4 for the file locations and access rule. -
Open the admin Manage Settings page at
https://app.example.edu/passkey/admin/settings. In Registration Allowed Origins, include the IdP origin because inline registration runs on the IdP page, and keep the management application origin for self-service registration. Enter one origin per line and save the setting:https://app.example.edu https://idp.example.eduUse your actual HTTPS origins, including any nonstandard port, and match the IdP entry to
idp.authn.passkey.relyingPartyOrigin. Each hostname must equal the relying-party ID or be its subdomain. - Reload Apache after changing its access rule and restart the IdP after changing its configuration. Test a password sign-in with a user below the configured passkey target who has not recently dismissed the prompt, then select Set up a passkey.
The properties control when the prompt appears and how the IdP reaches the backend-only Django endpoint:
| Property | What it controls |
|---|---|
idp.authn.passkey.inlineRegistration.enabled |
Turns on the optional post-password enrollment prompt. |
idp.authn.passkey.inlineRegistration.backendUrl |
Points the IdP at the backend-only Django endpoint under /registration-server-backend. |
idp.authn.passkey.inlineRegistration.promptTargetPasskeys |
Keeps prompting until the user has at least this many registered passkeys, which is useful when you want to encourage backup credentials. |
idp.authn.passkey.inlineRegistration.promptIntervalDays |
Waits this many days after dismissal before prompting again. The reminder state is tracked by an IdP-host cookie. |
The browser prompt shown during inline registration also follows Registration Client Hints from the Manage Settings page, so you can influence whether browsers favor an authenticator on this device, a physical security key, or a phone or other cross-device passkey.
In the admin Manage Settings page, the default Inline Registration Experience choice, Standard inline setup (default), waits for the user to select Set up a passkey. Select Automatic Conditional Create (with fallback) only when you want to opt into automatic WebAuthn Level 3 Conditional Create. This enrollment setting is separate from the IdP’s conditional mediation setting for sign-in. After the user successfully signs in with a recently used saved password, a capable browser and its default password manager may create and save a passkey without another site interaction or prominent WebAuthn prompt. The provider may show a completion notice.
The default password manager must already have a password for the site, the user must select that saved password for the successful sign-in, and its saved username must exactly match the user’s full canonical username. A stored but unused password, a manually typed password, a short-name or alias entry, or a passwordless, federated, or other non-password login is not eligible for automatic setup.
OmniPasskey tries automatic setup only when the browser reports that it supports the feature. Browser support does not guarantee that the password manager will accept the request; its privacy, account, existing-passkey, and eligibility rules still apply. If automatic setup is unsupported, ineligible, declined, cancelled, or times out, the Set up a passkey button remains available.
While Conditional Create is pending, OmniPasskey shows an animated, screen-reader-announced setup status. The setup and skip controls remain available so the user can cancel a request that the browser or password manager leaves pending. During passkey sign-in, a full-page status prevents duplicate interaction until sign-in completes; if an error occurs, the controls return. These indicators are part of the OmniPasskey page and remain consistent when browsers use different native prompts.
OmniPasskey uses Standard inline setup instead when Registration User Verification is Required or Allow Untrusted Registrations is set to Do not allow devices with untrusted attestation to register. The user must then select Set up a passkey, and the configured verification and attestation requirements remain enforced.
Requiring trusted attestation cannot be combined with an Attestation Conveyance Preference of None. Select Direct, Indirect, or Enterprise before choosing Do not allow devices with untrusted attestation to register.
Values that must match
| Value | Management interface | IdP plugin |
|---|---|---|
| Relying-party ID | ID=example.edu |
idp.authn.passkey.relyingPartyId=example.edu |
| Management URL | API_BASE=https://app.example.edu |
Used by inline registration backend URL when enabled |
| Database engine and credentials | passkey-database.properties |
passkey-database.properties |
| Inline registration backend path | /registration-server-backend must be reachable only from the IdP |
idp.authn.passkey.inlineRegistration.backendUrl=... |
If passkey registration appears to succeed but sign-in fails, first confirm the relying-party ID, hostnames, origin, and shared database settings are aligned exactly.
Diagnostics and testing overrides
| Property | When to use it |
|---|---|
idp.authn.passkey.ui.debug |
Temporarily enables scrollable on-page diagnostic panels in the IdP passkey views. Application diagnostics stay in these panels instead of the browser console. Output can include usernames, helper-cookie state, request details, and WebAuthn objects, so redact it before sharing. |
idp.authn.audit.enabled |
Turns on the standard IdP authentication audit trail so passkey outcomes can be correlated with wider Shibboleth authentication events. |
idp.authn.passkey.allowAnyOriginPort |
Relaxes exact origin matching to any port for the configured origin. Reserve this for controlled testing setups. |
idp.authn.passkey.allowAnyOriginSubdomain |
Relaxes origin matching to subdomains of the relying-party ID. Use only when you intentionally rely on multiple IdP subdomains. |
Policy and client-hint controls
Manage the settings below on the OmniPasskey admin Manage Settings page at https://app.example.edu/passkey/admin/settings. Replace app.example.edu with your management application hostname and sign in with an authorized admin account.
| Setting | What it controls |
|---|---|
| Default Registration Rule | Whether new device types may register by default or must first have an explicit entry on the Rules page. |
| Default Authentication Rule | Whether registered devices may authenticate by default or must appear in an explicit rule first. |
| Default MFA Rule | Whether passkeys may act as a primary factor or are limited to MFA-only use by default. |
| Allow Untrusted Registrations | Whether devices may register when their attestation cannot be verified to a trusted metadata root. Blocking them can also block common consumer phones, computers, synced passkeys, and authenticators that provide no usable attestation. |
| Attestation Conveyance Preference | What evidence the browser is asked to return: Direct requests authenticator attestation, Indirect permits privacy-preserving attestation, Enterprise requests identifying attestation for an enterprise-managed deployment, and None requests none. This is a browser request, not a guarantee; the untrusted-registration choice determines whether the result is acceptable. |
| Require Resident/Discoverable Key | Whether the passkey should be discoverable on the authenticator for passwordless use. |
| Authenticator Attachment | Whether to allow any authenticator, only built-in platform authenticators, or only cross-platform security keys. |
| Registration User Verification | Whether biometrics or PIN verification are required, preferred, or discouraged during registration. |
| Registration Allowed Origins | Exact HTTPS origins allowed to host registration, entered one per line. Each host must equal the relying-party ID or be its subdomain. Include the IdP origin when inline registration is enabled. |
| Backup Eligibility Policy | Allows both credential classes, requires backup-eligible syncable passkeys, or requires single-device credentials. The policy is enforced at registration and authentication. |
| Inline Registration Experience | Standard inline setup is the default and waits for the post-password setup button. Automatic Conditional Create opts into a capability-gated saved-password upgrade while preserving the fallback. Required registration verification or trusted attestation selects standard inline setup. |
| Preferred COSE Algorithms | The algorithm preference order the server will request during registration. |
| Registration Client Hints | The ordered WebAuthn browser hints used during self-service and inline registration ceremonies. |
| Authentication Client Hints | The ordered WebAuthn browser hints used during IdP passkey sign-in and conditional mediation. |
For either client-hint setting, select Add Client Hint, choose from Authenticator on this device, Physical security key, and Phone or other cross-device passkey, then drag the selected rows or use their Up and Down buttons to set the preference order. Leave the selected list empty to let the browser choose its default passkey UI. Hints guide the browser’s presentation while registration and authentication policies remain enforced.
Registration User Verification applies only while a credential is created. Authentication has a separate IdP property in ${idp.home}/conf/authn/passkey.properties: idp.authn.passkey.userVerificationRequirement, with required, preferred, or discouraged. Set that property to required when every passkey sign-in must include a biometric, PIN, or equivalent authenticator verification step.
The Discoverable column on My Passkeys and Manage Credentials shows Yes, No, or Not reported based on information supplied by the browser during registration. Use this information to help diagnose usernameless sign-in. Registration and authentication policies remain enforced.
Set Registration Allowed Origins on the admin Manage Settings page. Enter one exact HTTPS origin per line, including any nonstandard port, and save the setting. Each entry consists of the scheme, hostname, and optional port. Complete registration in a top-level browser page.
If your rollout depends on trusted attestation or strict per-device rules, treat metadata refresh as part of the policy path. When Allow Untrusted Registrations blocks untrusted devices, unavailable or invalid metadata pauses registration so verification cannot be bypassed. Allowing untrusted registrations still verifies any supplied attestation statement’s cryptographic integrity, but does not require a trusted metadata root.
Blocking untrusted attestation is appropriate for tightly managed authenticator fleets, but it commonly prevents consumer devices and synced passkeys from registering because many do not expose attestation that can be linked to a trusted metadata root. Start with untrusted registrations allowed unless your organization controls the supported authenticator inventory and has verified its metadata coverage.