Passkeys
The Passkeys authenticator enables strong, public key-based credentials for user authentication. Passkeys are WebAuthn credentials that require user verification and are available across different contexts/devices. Authenticating using a Passkey usually requires a user to perform a biometric gesture in the device or enter a device's PIN. The Passkeys specification refers to an authentication device as authenticator. An authenticator has a different meaning in Curity Identity Server, and thus we use the word device.
Use Cases#
The Curity website has some design articles and tutorials that you can use to learn more about ways to use passkeys:
- Article: What are Passkeys?
- Article: Passkeys - Design your Solution
- Passkeys Authenticator Tutorial
- Native Passkeys Configuration
Creating a Passkeys authenticator#
The most common way to get started is to create a Passkeys authenticator in the Admin UI. To do so, navigate to Profiles → Authentication Service → Authenticators and select the + New Authenticator option. Then select the passkeys option to see the following user interface.

When you edit settings, you can select the View XML option to see a serialized representation of the authenticator’s settings.
<authenticator>
<id>passkeys</id>
<authentication-actions>
<login>passkeys_claims</login>
</authentication-actions>
<description>Sign in with a passkey</description>
<required-authenticator-for-registration>email</required-authenticator-for-registration>
<passkeys xmlns="https://curity.se/ns/conf/authenticators/passkeys">
<allow-registration-during-login>true</allow-registration-during-login>
<enable-discoverable-credentials>true</enable-discoverable-credentials>
<account-manager>
<id>default-account-manager</id>
</account-manager>
</passkeys>
</authenticator>
Configuring a Passkeys authenticator#
When creating a Passkeys authenticator, there are some configuration options that can be used.
-
allow-registration-during-login- Toggle to enable registration for the authenticator. If disabled, none of the registration possibilities will be available, and the authenticator device will have to be registered out of band.
-
account-manager- An account manager holding the accounts that have the devices, and if registration is allowed, where to store details for new devices, like public keys.
-
enable-discoverable-credentials- Toggle to enable user authentication without explicitly providing the username, relying on credentials known to the browser or operating system.
-
require-user-to-set-alias- Require users to set a device alias every time they register a new device. This may help users to identify their devices later.
-
relying-party-id- The WebAuthn Relying Party ID. If not set, the hostname of the server’s base URL is used. See Relying Party ID.
-
credential-id-attribute- Adds the credential ID of the passkey the user authenticated with to the authentication attributes.
-
related-origins- Additional origins, outside the Relying Party ID’s domain, from which passkey ceremonies are accepted. See Related Origin Requests.
Relying Party ID#
By default the authenticator derives the WebAuthn Relying Party ID (rpId) from the hostname of the request’s base URL (for example iam.example.com). A passkey is bound to that exact host and can only be used on it.
The optional relying-party-id setting lets an administrator set the rpId explicitly. Per the WebAuthn specification the value must be a registrable domain suffix of (or equal to) the origin the ceremony runs on. For example, a server running on iam.example.com may set it to example.com. When configured this way, a passkey registered through the Curity Identity Server becomes usable across the parent domain and all of its subdomains (app.example.com, account.example.com, and so on). When the setting is left empty, the previous host-based behavior is preserved.
When relying-party-id is set, the server accepts WebAuthn ceremonies from any subdomain of that value. Only set it to a domain whose subdomains you fully control — a subdomain that is compromised or subject to takeover could be used to complete a WebAuthn ceremony for the configured Relying Party. The value is not validated against the server’s origin; if it is not a registrable suffix of that origin, the WebAuthn ceremony simply fails in the browser.
Changing relying-party-id invalidates every passkey already registered under the previous value. Setting it
for the first time counts as a change: until it is set the Relying Party ID is the request host, so
configuring a parent domain moves it.
A passkey stores a hash of the Relying Party ID it was created under, and the authenticator compares that
hash exactly. Accepting ceremonies from subdomains does not help here — that rule governs which origins
may claim a Relying Party ID, never which passkeys answer for one. A passkey registered under
iam.example.com is therefore unusable once the Relying Party ID becomes example.com, even on
iam.example.com itself.
New registrations keep working and nothing reports an error, so the breakage surfaces only for users who
already had a passkey, and each of them has to register again. There is no migration. Decide the value
before rolling passkeys out, and when the goal is to accept ceremonies from an origin outside the current
domain, add that origin to related-origins rather than moving the Relying
Party ID.
Related Origin Requests#
The Relying Party ID covers a single domain and its subdomains. Related Origin Requests extend a passkey’s reach to origins on other domains entirely — for example letting a passkey with the rpId example.com be used on example.co.uk and myexamplerewards.com. This is only relevant when the WebAuthn ceremony itself runs on one of those other domains; in a redirect-based login the ceremony always runs on the Identity Server’s own origin, which the Relying Party ID already covers. For that reason the WebAuthn specification recommends federation ahead of Related Origin Requests, so reach for this feature only where the ceremony deliberately runs elsewhere, such as API-driven authentication.
The feature has two halves, and both must be in place.
1. The server accepts the origin. List each additional origin in the related-origins setting, as a complete origin with the https scheme and no path:
https://example.co.uk
https://myexamplerewards.com
The Identity Server then accepts a ceremony whose origin is one of these, in addition to the ones the Relying Party ID already covers. This list is per authenticator, so origins trusted by one authenticator are not implicitly trusted by another.
related-origins requires relying-party-id to be set on the same authenticator. Related origins only have meaning relative to a Relying Party ID, and it is the Relying Party ID that decides where the document below is published.
2. A document is published at the Relying Party ID’s origin. The browser fetches https://{rpId}/.well-known/webauthn and only proceeds if the ceremony’s origin is listed there:
{
"origins": [
"https://example.co.uk",
"https://myexamplerewards.com"
]
}
The Identity Server publishes this document at its own /.well-known/webauthn path, for those Relying Party IDs it is itself reachable on.
The document is generated from configuration only. Unlike the apple-app-site-association and assetlinks.json documents described below, a file placed in $IDSVR_HOME/usr/share/webroot/.well-known/ is not served for this path.
When relying-party-id points at a domain the Identity Server does not serve — for example rpId example.com with the server running on iam.example.com — the browser fetches the document from https://example.com/.well-known/webauthn, which is not this server. That domain must publish an equivalent document itself, served over HTTPS with a Content-Type of application/json. Configuring related-origins alone is not enough in that case.
One document per Relying Party ID#
A browser only ever fetches this document from the Relying Party ID itself, so the host a request for /.well-known/webauthn arrives on is the Relying Party ID being asked about. The Identity Server answers accordingly: it publishes the origins configured beside a matching relying-party-id, and nothing else.
related-originsis per authenticator. Origins trusted by one authenticator are not trusted by another, and a ceremony is always validated against the list of the authenticator handling it./.well-known/webauthnis per Relying Party ID. Requesting it onexample.comreturns the origins of the authenticators whoserelying-party-idisexample.com, with duplicates collapsed and the configured order preserved. Origins belonging to a different Relying Party ID are not included, and404 Not Foundis returned for a host no authenticator is configured for.
Authenticators sharing a Relying Party ID share one document, with their origins merged into it. The server still validates against the handling authenticator’s own list, so an origin configured on one but not another produces a ceremony the browser allows and the server then rejects. Add it to the authenticator serving the flow.
Credentials are isolated per tenant, so authenticators in different tenants do not share the passkeys registered under that Relying Party ID.
If the document is missing, unreachable, served with the wrong content type, or does not list the ceremony’s origin, the browser rejects the ceremony outright before showing any credential picker. There is no partial behavior to fall back on.
Every origin listed in related-origins can complete WebAuthn ceremonies for this Relying Party, so only add origins you fully control. Unlike relying-party-id, related origins are matched exactly: a configured https://example.co.uk does not admit https://sub.example.co.uk, which must be listed in its own right if it should be usable.
Registering devices#
When allowing for a device registration for this authenticator, a prerequisite authenticator is mandatory to configure. This prerequisite authenticator is used to establish a subject by which to lookup an account using the configured Account Manager.
Hypermedia Authentication API#
The Passkeys authenticator supports the Hypermedia Authentication API. The HAAPI model utilises the following two client-operation - webauthn-registration and webauthn-authentication. A client that does not implement them can fall back to an external browser flow, which the server offers as an error action on both operations.
Web clients#
A HAAPI web client runs the WebAuthn ceremony in its own origin, not in the Identity Server’s. The browser only starts the ceremony when the Relying Party ID is a registrable domain suffix of, or equal to, that origin, so a client served from a different host than the Identity Server needs one of the two settings above:
- When the client and the Identity Server share a registrable domain, set
relying-party-idto that shared domain. A client onhttps://app.example.comand an Identity Server onhttps://login.example.comboth work under a Relying Party ID ofexample.com. - When they share no domain, keep the Relying Party ID on a host the Identity Server serves and add the client’s origin to
related-origins. The browser then fetches the published document from the Relying Party ID’s origin before allowing the ceremony, so that host has to be reachable from the browser on port 443.
Credentials stay scoped to the Relying Party ID rather than to the client’s origin. Passkeys registered through a web client are therefore usable in every other flow under the same Relying Party ID, including the Identity Server’s own login pages and the mobile SDKs, and the reverse holds as well.
Without either setting, the Relying Party ID defaults to the host of the Identity Server’s base URL, and the browser refuses the ceremony with a SecurityError before anything reaches the server. A web client should offer the external browser flow error action for that case.
Discoverable Credentials#
When Discoverable Credentials are enabled, the username prompt is omitted during the authentication flow and instead the browser presents to the user a list of known credentials or displays a QR code to be used with credentials stored on a mobile device. Use of discoverable credentials requires a database structure update, please refer to the product’s upgrade guides for details.
iOS Domain Association#
The iOS domain association allows for the creation of a connection between the Identity Server and mobile application for passkey generation. To serve the apple-app-site-association (association) file from Identity Server, application details need to be configured in environments/environment/service/zones/{appropriate zone}/mobile-app-association/ios-app-configuration. Alternatively the file can be placed in dist/usr/share/webroot/.well-known/ directory.
Android Domain Association#
The Android domain association allows for the creation of a connection between Identity Server and android application for WebAuthn key generation. To serve the assetlinks.json file from Identity Server, application details needs to be configured in environments/environment/service/zones/{appropriate zone}/mobile-app-association/android-app-configuration alternatively the file can be placed in $IDSVR_HOME/usr/share/webroot/.well-known/ directory and file generation disabled by configuring environment/services/service-role/<service-role>/disable-android-assetlinks-generation.
Known limitations#
The following limitations are known about the Passkeys authenticator:
- A HAAPI web client served from a different host than the Identity Server needs either
relying-party-idorrelated-originsconfigured; see Web clients. Related Origin Requests additionally depend on browser support.