Configuration Reference
Duende User Management is configured through a set of strongly-typed options classes. This page documents every configurable property, its type, default value, and purpose.
Registration
Section titled “Registration”Register User Management services in Program.cs using the builder pattern:
using Duende.IdentityServer;using Duende.UserManagement;
builder.Services .AddIdentityServer() .AddUserManagement(um => um .Authentication(auth => auth.Configure(options => { options.Passwords.MinLength = 15; options.Passkeys.RelyingPartyName = "My Application"; options.Passkeys.AllowedOrigins = ["https://app.example.com"]; options.Throttling.MaxFailedAttempts = 3; })) );To configure both options and the feature builder in a single call:
using Duende.IdentityServer;using Duende.UserManagement;
builder.Services .AddIdentityServer() .AddUserManagement(um => um .Authentication(auth => { auth.Configure(options => { options.Passkeys.RelyingPartyName = "My Application"; options.Passkeys.AllowedOrigins = ["https://app.example.com"]; }); auth.ConfigureEndpoints(endpoints => { endpoints.Passkeys.Route = "/auth/passkeys"; }); }) );UserAuthenticationOptions
Section titled “UserAuthenticationOptions”Top-level options class for authentication configuration. Accessed via IOptions<UserAuthenticationOptions>.
| Property | Type | Description |
|---|---|---|
Totp | TotpOptions | Configuration for Time-Based One-Time Password (TOTP) authenticator storage. |
Passkeys | PasskeyOptions | Configuration for passkey registration and authentication. |
Passwords | PasswordOptions | Configuration for the password validator. |
RecoveryCodes | RecoveryCodeOptions | Configuration for recovery code behavior. |
Throttling | AuthenticationThrottlingOptions | Configuration for per-authenticator attempt throttling. |
All sub-option objects are initialized with their defaults automatically. You only need to set the properties you want to override.
PasswordOptions
Section titled “PasswordOptions”Controls the built-in password complexity validator. Accessed via UserAuthenticationOptions.Passwords.
IdentityServer before 8.1
IdentityServer 8.0 defaults
| Property | Type | Default | Description |
|---|---|---|---|
MinLength | int | 8 | Minimum required password length in characters. |
MaxLength | int | 64 | Maximum allowed password length. Capped at 64 characters (512 bits) to avoid PBKDF2 pre-hashing vulnerabilities with SHA-512. |
MinLower | int | 2 | Minimum number of lowercase letters required. |
MinUpper | int | 2 | Minimum number of uppercase letters required. |
MinDigits | int | 2 | Minimum number of numeric digit characters required. |
MinSymbols | int | 2 | Minimum number of symbol characters required. |
HistoryCount | int | 0 | Number of previous passwords to remember and reject on change or reset; 0 disables history. |
MaxAgeDays | int? | null | Maximum password age in days before the password is considered expired; null disables expiration. |
PreferredHashAlgorithm | string | "pbkdf2" | Algorithm used when hashing new passwords; see Password Hashing Algorithms. |
IdentityServer 8.1 and later
IdentityServer 8.1 defaults
| Property | Type | Default | Description |
|---|---|---|---|
MinLength | int | 15 | Minimum required password length in characters. |
MaxLength | int | 64 | Maximum allowed password length. Capped at 64 characters (512 bits) to avoid PBKDF2 pre-hashing vulnerabilities with SHA-512. |
MinLower | int | 0 | Minimum number of lowercase letters required. |
MinUpper | int | 0 | Minimum number of uppercase letters required. |
MinDigits | int | 0 | Minimum number of numeric digit characters required. |
MinSymbols | int | 0 | Minimum number of symbol characters required. |
HistoryCount | int | 0 | Number of previous passwords to remember and reject on change or reset; 0 disables history. |
MaxAgeDays | int? | null | Maximum password age in days before the password is considered expired; null disables expiration. |
PreferredHashAlgorithm | string | "pbkdf2" | Algorithm used when hashing new passwords; see Password Hashing Algorithms. |
Example (custom composition policy):
.Authentication(auth => auth.Configure(options =>{ options.Passwords.MinLength = 12; options.Passwords.MinLower = 1; options.Passwords.MinUpper = 1; options.Passwords.MinDigits = 1; options.Passwords.MinSymbols = 0;}))Nonzero character-class minimums impose composition rules. See the PasswordOptions guidance before changing these defaults.
PasskeyOptions
Section titled “PasskeyOptions”Controls WebAuthn/passkey registration and authentication behavior. Accessed via UserAuthenticationOptions.Passkeys.
IdentityServer before 8.1
| Property | Type | Default | Description |
|---|---|---|---|
RelyingPartyName | string | Assembly name | Human-readable display name of the relying party shown to the user during registration. Does not affect security. |
ServerDomain | string? | null | The effective domain used as the WebAuthn Relying Party ID. Set explicitly to share passkeys across subdomains (e.g. "example.com" for auth.example.com and app.example.com). |
AllowedOrigins | IReadOnlyList<string>? | null | Required. One or more fully-qualified origins (scheme + host + optional port) permitted to use passkeys. The clientDataJSON.origin from the authenticator is validated against this list. |
ChallengeSize | int | 32 | Size of the WebAuthn challenge in bytes (256 bits). Must be at least 16 bytes; smaller values throw ArgumentOutOfRangeException. |
ChallengeTimeout | TimeSpan | 00:05:00 | Maximum lifetime of a passkey challenge. Challenges are single-use and rejected after this duration. |
UserVerificationRequirement | string | "preferred" | User verification requirement for authentication. See User Verification Values. |
AttestationConveyancePreference | string | "none" | Attestation conveyance preference for credential creation. See Attestation Conveyance Values. |
AuthenticatorAttachment | string? | null | Restricts the authenticator attachment modality. null allows any authenticator type. See Authenticator Attachment Values. |
ResidentKeyRequirement | string | "preferred" | Discoverable credential (resident key) requirement for registration. See Resident Key Values. |
SupportedAlgorithms | IReadOnlyList<int> | [] | COSE algorithm identifiers to support, in preference order. An empty list accepts all algorithms supported by the library. Use CoseAlgorithms constants to specify values. |
IdentityServer 8.1 and later
| Property | Type | Default | Description |
|---|---|---|---|
RelyingPartyName | string | Assembly name | Human-readable display name of the relying party shown to the user during registration. Does not affect security. |
ServerDomain | string? | null | The effective domain used as the WebAuthn Relying Party ID. Set explicitly to share passkeys across subdomains (e.g. "example.com" for auth.example.com and app.example.com). |
AllowedOrigins | IReadOnlyList<string>? | null | Required. One or more fully-qualified origins (scheme + host + optional port) permitted to use passkeys. The clientDataJSON.origin from the authenticator is validated against this list. |
ChallengeSize | int | 32 | Size of the WebAuthn challenge in decoded random bytes. Must be at least 16; smaller values fail options validation at host startup. See Challenge Length. |
ChallengeTimeout | TimeSpan | 00:05:00 | Maximum lifetime of a passkey challenge. Challenges are single-use and rejected after this duration. |
UserVerificationRequirement | string | "preferred" | User verification requirement for authentication. See User Verification Values. |
AttestationConveyancePreference | string | "none" | Attestation conveyance preference for credential creation. See Attestation Conveyance Values. |
AuthenticatorAttachment | string? | null | Restricts the authenticator attachment modality. null allows any authenticator type. See Authenticator Attachment Values. |
ResidentKeyRequirement | string | "preferred" | Discoverable credential (resident key) requirement for registration. See Resident Key Values. |
SupportedAlgorithms | IReadOnlyList<int> | [] | COSE algorithms advertised for credential registration, in preference order. An empty list offers all registered verifiers; an explicit list offers only entries with verifiers and removes duplicates. Use CoseAlgorithms constants. See Signature Verifier Extension for ordering. |
User Verification Values
Section titled “User Verification Values”The UserVerificationRequirement property accepts the following string values:
"required": User verification must be performed (PIN, biometric, etc.)."preferred": User verification is preferred but not required. (default)"discouraged": User verification should not be performed.
Attestation Conveyance Values
Section titled “Attestation Conveyance Values”The AttestationConveyancePreference property accepts the following string values:
"none": No attestation statement is needed. (default)"indirect": Attestation statement may be anonymized by the browser."direct": Attestation statement should be provided directly by the authenticator."enterprise": Enterprise attestation for managed authenticators.
Authenticator Attachment Values
Section titled “Authenticator Attachment Values”The AuthenticatorAttachment property accepts the following string values:
null: Any authenticator type is allowed. (default)"platform": Built-in authenticators only (Windows Hello, Touch ID, Face ID)."cross-platform": Roaming authenticators only (USB security keys, Bluetooth).
Resident Key Values
Section titled “Resident Key Values”The ResidentKeyRequirement property accepts the following string values:
"preferred": Discoverable credential is preferred if the authenticator supports it. (default)"required": Discoverable credential is required."discouraged": Non-discoverable credential is preferred.
Passkey Configuration Example
Section titled “Passkey Configuration Example”.Authentication(auth => auth.Configure(options =>{ options.Passkeys.RelyingPartyName = "ACME Corporation"; options.Passkeys.ServerDomain = "example.com"; options.Passkeys.AllowedOrigins = [ "https://app.example.com", "https://auth.example.com" ]; options.Passkeys.UserVerificationRequirement = "required"; options.Passkeys.AuthenticatorAttachment = "platform"; options.Passkeys.ChallengeTimeout = TimeSpan.FromMinutes(3);}))TotpOptions
Section titled “TotpOptions”Controls TOTP authenticator app configuration. Accessed via UserAuthenticationOptions.Totp.
| Property | Type | Description |
|---|---|---|
Storage | StorageOptions | Controls how TOTP secrets are stored. |
StorageOptions
Section titled “StorageOptions”Nested within TotpOptions. Controls TOTP secret storage behavior.
| Property | Type | Default | Description |
|---|---|---|---|
ProtectKeys | bool | true | When true, TOTP secrets are encrypted at rest using ASP.NET Core Data Protection before being stored. Disable only if your storage layer provides its own encryption. |
Example (disable key protection; not recommended unless storage is encrypted externally):
.Authentication(auth => auth.Configure(options =>{ options.Totp.Storage.ProtectKeys = false;}))AuthenticationThrottlingOptions
Section titled “AuthenticationThrottlingOptions”Controls the built-in per-authenticator failed-attempt throttling policy. Accessed via UserAuthenticationOptions.Throttling.
| Property | Type | Default | Description |
|---|---|---|---|
MaxFailedAttempts | int | 5 | Number of failed attempts allowed within the FailureWindow before throttling is applied. |
FailureWindow | TimeSpan | 00:15:00 | Rolling window from the last failure during which the failure count is tracked. If LastFailedAtUtc + FailureWindow has elapsed, the count resets to zero. |
ThrottleDuration | TimeSpan | 00:05:00 | How long to block further attempts after the threshold is exceeded, measured from the last failed attempt. |
MaxAttemptsPerWindow | int | 5 | Maximum total authentication attempts (successful and failed) allowed within the VelocityWindow. |
VelocityWindow | TimeSpan | 00:00:10 | Sliding window for counting total authentication attempts. |
VelocityThrottleDuration | TimeSpan | 00:00:30 | How long to block further attempts after the velocity threshold is exceeded. |
EscalatingThrottleDurations | IReadOnlyList<TimeSpan>? | null | Per-lockout durations for escalating lockout; when set, each successive lockout uses the next duration in the list; when null or empty, ThrottleDuration applies. |
Example (stricter throttling):
.Authentication(auth => auth.Configure(options =>{ options.Throttling.MaxFailedAttempts = 3; options.Throttling.FailureWindow = TimeSpan.FromMinutes(30); options.Throttling.ThrottleDuration = TimeSpan.FromMinutes(15); options.Throttling.MaxAttemptsPerWindow = 5; options.Throttling.VelocityWindow = TimeSpan.FromSeconds(10); options.Throttling.VelocityThrottleDuration = TimeSpan.FromSeconds(30);}))RecoveryCodeOptions
Section titled “RecoveryCodeOptions”Controls recovery code generation and authentication. Accessed via UserAuthenticationOptions.RecoveryCodes.
| Property | Type | Default | Description |
|---|---|---|---|
Count | int | 10 | Number of recovery codes generated per call to TryCreateRecoveryCodesAsync; valid range is 1 to 50. |
Enabled | bool | true | When false, recovery codes are disabled; TryCreateRecoveryCodesAsync returns null and TryAuthenticateAsync returns false. |
UserAuthenticationEndpointOptions
Section titled “UserAuthenticationEndpointOptions”Controls the HTTP endpoint routes exposed by the web layer. Configure via ConfigureEndpoints() on the authentication builder:
.Authentication(auth =>{ auth.Configure(options => { /* UserAuthenticationOptions */ }); auth.ConfigureEndpoints(endpoints => { endpoints.Passkeys.Route = "/auth/passkeys"; });})Or bind from configuration:
.Authentication(auth =>{ auth.Configure(options => { }); auth.ConfigureEndpoints( builder.Configuration.GetSection("UserAuthentication:Endpoints") );})| Property | Type | Description |
|---|---|---|
Passkeys | PasskeysRouteOptions | Route configuration for all passkey endpoints. |
PasskeysRouteOptions
Section titled “PasskeysRouteOptions”Controls the individual route paths for passkey HTTP endpoints. All paths under Passkeys are relative to the Route prefix. Accessed via UserAuthenticationEndpointOptions.Passkeys.
| Property | Type | Default | Description |
|---|---|---|---|
Route | string | "/passkeys" | Base route prefix for all passkey endpoints. |
BeginRegistration | string | "/register/begin" | Path for the passkey registration initiation endpoint (relative to Route). Full default: /passkeys/register/begin. |
CompleteRegistration | string | "/register/complete" | Path for the passkey registration completion endpoint (relative to Route). Full default: /passkeys/register/complete. |
BeginAuthentication | string | "/authenticate/begin" | Path for the passkey authentication initiation endpoint (relative to Route). Full default: /passkeys/authenticate/begin. |
BeginDiscoverableAuthentication | string | "/authenticate/discoverable/begin" | Path for the discoverable (usernameless) passkey authentication initiation endpoint (relative to Route). Full default: /passkeys/authenticate/discoverable/begin. |
CompleteAuthentication | string | "/authenticate/complete" | Path for the passkey authentication completion endpoint (relative to Route). Full default: /passkeys/authenticate/complete. |
PasskeysJavaScript | string | "/js" | Path for the passkeys JavaScript helper endpoint (relative to Route). Full default: /passkeys/js. |
Example (custom route prefix):
auth.ConfigureEndpoints(endpoints =>{ endpoints.Passkeys.Route = "/auth/webauthn";})This changes all passkey endpoints to use /auth/webauthn as the base, so registration begins at /auth/webauthn/register/begin, and so on.
IdentityServer 8.1 and later
SCIM support is experimental. Enable it with IUserManagementBuilder.EnableScim(...) and map its endpoints with app.MapScim(). See SCIM Provisioning for setup, authorization, and known issues.
ScimOptions
Section titled “ScimOptions”Controls which SCIM resources and capabilities are available, along with response and request limits.
| Property | Type | Default | Description |
|---|---|---|---|
EnableUsers | bool? | Auto-detected | Enables SCIM User endpoints. When null, detected from whether IUserProfileAdmin is registered. |
EnableGroups | bool? | Auto-detected | Enables SCIM Group endpoints. When null, detected from whether IGroupAdmin is registered. |
ChangePassword | bool? | Auto-detected | Advertises SCIM change-password support. When null, detected from whether IPasswordAuthenticator is registered. |
MaxResults | int | 200 | Maximum number of resources returned in one list response. |
MaxGroupMembersInResponse | int | 100 | Maximum number of group members included in one group response. Additional members are truncated and a warning is logged. |
MaxBulkOperations | int | 100 | Maximum operations allowed in one bulk request. Requests that exceed the limit receive HTTP 413. |
MaxBulkPayloadSize | int | 1,048,576 | Maximum bulk request body size in bytes (1 MB). Requests that exceed the limit receive HTTP 413. The limit applies even when Content-Length is absent. |
ScimEndpointOptions
Section titled “ScimEndpointOptions”Controls the route prefixes for SCIM resources. Configure these through the optional endpoint configuration argument to EnableScim.
| Property | Type | Default | Description |
|---|---|---|---|
Route | string | "/scim/Users" | Base route for SCIM User endpoints. |
GroupsRoute | string | "/scim/Groups" | Base route for SCIM Group endpoints. |
MetadataRoute | string | "/scim" | Base route for ServiceProviderConfig, ResourceTypes, and Schemas metadata endpoints. |
BulkRoute | string | "/scim/Bulk" | Route for the SCIM Bulk endpoint. |
ScimOAuthOptions
Section titled “ScimOAuthOptions”Controls authentication and authorization for SCIM data endpoints. Metadata endpoints remain anonymous.
| Property | Type | Default | Description |
|---|---|---|---|
Authority | string? | null | Authority used for JWT bearer token validation and discovery. In the IdentityServer integration, it resolves from IdentityServerOptions.IssuerUri when not set explicitly. Without either value, default SCIM authorization fails startup validation. |
Audience | string | "urn:duende:scim" | Expected audience in SCIM bearer tokens. |
AuthorizationPolicyName | string? | null | Uses the named ASP.NET Core authorization policy instead of the built-in scope-based policies. The custom policy applies to all SCIM data endpoints. |
RequireHttpsMetadata | bool | true | Requires HTTPS when retrieving authority metadata. Disable only in development environments. |
Membership Module
Section titled “Membership Module”The membership module provides administrative services for managing users, roles, and groups within your application. It is registered automatically by AddUserManagement(...) when your application needs to programmatically create or modify users, assign roles, or manage group membership from server-side code (for example, in admin UIs or API endpoints).
The following services are registered automatically with the service provider:
| Service | Description |
|---|---|
IMembershipAdmin | Provides administrative operations for user accounts: creating, updating, deleting, and querying users. |
IRoleAdmin | Provides administrative operations for roles: creating, updating, deleting, and assigning roles to users. |
IGroupAdmin | Provides administrative operations for groups: creating, updating, deleting, and managing group membership. |
All three services are registered with scoped lifetime and can be injected wherever you need to perform administrative operations on the user store.