Skip to content

User Store

Create new IDP

Steps to create a new IDP:

  • Navigate to the ProAuth Admin UI and login with a user assigned to role SubscriptionAdmin or higher
  • Navigate to Idp Instances and click on Create Idp Instance
  • Choose the IDP Type UserStore
  • Enable the flag Active
  • Enable the flag Auto Create ProAuth User
  • Choose the proper Subscription
  • Click Save

Create UserStore IDP

Configure new IDP

After the creation of the IDP in the step before, it's now necessary to configure the IDP. Invalid IPDs aren't available in ProAuth.

It's necessary to already have an existing and deployed UserStore database. The connection string with Read/Write permissions to this database is one of the mandatory options.

Steps to complete the configuration of the IDP:

  • Open the IDP in the extended edit view
  • Assign the IDP to the required Tenants

Edit UserStore IDP

Configure mandatory Options:

  • Set the ConnectionString for the SQL database
  • Set the CallbackPath (e.g. /signin-userstore)
  • Set the ClaimIssuer (default: UserStore)
  • Set the HashAlgorithmName (default: System.Security.Cryptography.SHA256)
  • Set the IsDatabaseReadOnlyMode (default: false)

UserStore IDP optionsUserStore IDP optionsUserStore IDP options

Enable UserStore login by email address:

The UserStore identifies its users by their unique username. The user entry also contains an e-mail field which is primarily used for notifications. People are used to login by their e-mail address. There are two possibilities to achieve that behavior. Either the username is set to the users e-mail or you can enable to UserStore to accept logins by the username or the e-mail address. The latter option only works, if the e-mail addresses are unique across all users in the same user store. To enable login by e-mail, please set the following options:

  • Set the LoginByEmailEnabled option to true

    UserStore IDP options

INFO

  • The user input (username or e-mail) is always checked against the username first. If no username is found and this option is enabled, the e-mail address is used to identify the user. This order is necessary because e-mail addresses can also be used as usernames in the user store.

  • If more than one user is found due to the email address (two or more users have entered the same email address) an error message is displayed (username/email or password wrong). We treat this case as if the e-mail address does not exist. For these users a login via username is mandatory. For security reasons, only a general error message is returned.

  • The password reset works similar to the login: If the option is enabled, the password reset can be requested via the e-mail address. If the e-mail address is used more than once, the password reset must be requested via the username.

Configure mail setting Options

  • Set the EMailSenderAddress
  • Set the MailServerConfig

UserStore IDP optionsUserStore IDP options

MailServerConfiguration sample data for SMTP Server:

json
{
    "MailType": "SMTP",
    "Host": "<smtp-host-address>",
    "Port": 465,
    "EnableSSL": true,
    "UserName": "<smtp-username>",
    "Password": "<smtp-password>",
    "Timeout": 20000
}

MailServerConfiguration sample data for Microsoft365:

json
{
    "MailType": "M365",
    "ClientId": "<aad-app-clientid>",
    "ClientSecret": "<aad-app-clientsecret>",
    "TenantId": "<aad-app-tenantid>",
    "UserId": "<aad-user-objectid>"
}

User lock notifications Options

An email notification can be enabled to inform administrators about locked users (due to too many wrong login attempts).

  • Enable notification by the option LockedUserNotificationEnabled
  • Configure the recipients by adding a semicolon separated list of e-mail addresses in the option LockedUserNotificationRecipients

The subject and the content of the e-mail message can be customized. The following options are used for this:

  • LockedUserNotificationMailSubjectTemplate: Contains the reference for a label used as the e-mail subject
  • LockedUserNotificationCulture: This defines the culture which is used to translate the labels (The culture name in the format languagecode2-country/regioncode2)

The following syntax is used within templates or options:

  • Labels: In the form of [[labelname]]
  • Placeholders for data values: In the form of . Each template has a fixed set of placeholders.

The values of the labels can be modified by overwriting the label values in the label management of ProAuth.

UserStore IDP options

Configure Password Hashing Algorithm

ProAuth provides a modular password hashing functionality for its UserStore which means that different hashing algorithms can be used side-by-side. Password hashes can be migrated to other algorithms upon a user login. Besides our standard algorithms, custom algorithms can be developed to ease the migration of UserStores from other systems.

We currently support 3 algorithms:

  • AspNetCoreIdentity V2
  • AspNetCoreIdentity V3
  • ProAuthPasswordHasher V1

Each UserStore defines a default hasher which is used for newly created users or to upgrade existing hashes during a login. Our current system default is AspNETCoreIdentity V3. The two other algorithms indicate a "rehash needed" flag which triggers the password hash migration to the default algorithm if configured accordingly.

Password Hashing Algorithm Options

  • DefaultPasswordHasher

    With this option the default password hash algorithm can be defined. By default, the most current one is always configured.

    UserStore IDP options

    Possible password hashers:

    • ProAuthPasswordHasher
      • ProAuthPasswordHasherV1
    • AspNetCoreIdentity
      • AspNetCoreIdentityV2
      • AspNetCoreIdentityV3

    For the password hasher a generic hasher (e.g. AspNetCoreIdentity) can be chosen as well as an explicit hasher (e.g. AspNetCoreIdentityV3). With a generic hasher, the latest version of this hasher is always used.

  • AutomaticPasswordRehash

    UserStore IDP options

    This option defines whether a password hash that should be rehashed is automatically rehashed the next time it is used

UserStore to ProAuth synchronization (implicit SCIM synchronization)

By default, UserStore groups and users are synchronized with ProAuth users and groups (one-way only). All possible properties of groups and users are synchronized. For users, all profiles are also synchronized, for groups all metadata as well. The synchronized ProAuth groups and users are read-only, they cannot be edited. It is only possible to define ProAuth Roles or TwoFactor settings on synchronized objects.

UserStore to ProAuth synchronization can be configured via the UserStore option: ProAuthSynchronizationEnabled.

UserStore IDP options

UserStore AuditTrail

By default, failed login attempts are audited in UserStore. Optionally, all successful logins to ProAuth can also be audited.

The auditing of logins can be controlled by following UserStore options:

UserStore IDP options

User Store DB Deployment Worker

ProAuth provides a worker container which is able to automatically create and configure databases for newly created UserStore IDP instances. To deploy and run the DB deployment worker container, please enable it in the Helm values and configure the appropriate settings corresponding to your setup.

The DB deployment worker listens for ProAuth UserStore changed events. Either a change on an active UserStore IDP with a configured ConnectionString or the change of the ConnectionString itself triggers the worker to create the potentially missing database.

If a change event is received, the DB deployment worker performs the following steps:

  • Identify the database type based on the connection string information (Azure SQL or SQL Server)
  • Create the database if it does not already exist.
  • Add the SQL users if they do not already exist.
  • Apply the security roles to the users

User Store Password Change

The password of a user can be changed by the user as follows:

  • During the login process, the user can choose to change the password which is then changed withing the login process.
  • The client application may provide a password change link which takes the user to the password change page and routes him back to the application or shows a confirmation page.
  • By choosing "forgot password" on the login page. The user will then receive a password reset link via e-mail if there is a validated e-mail address associated to the user.

An administrator is also able to perform the following password change operations through the admin UI:

  • Send a password reset e-mail to the user
  • Set a new initial password and provide the password to the user (e.g. by phone, e-mail, etc.). Since the administrator sets an initial password, the user is required to change the password on the next login.

The password change is also possible through a client application with the proper permissions. Here the logic to handle the password change safely is completely up to the client application.

The easiest way to provide a password change functionality which is not part of the login process, is to present the user with a link to change the password.

The password change link is defined as follows:

https://<ProAuthBaseUrl>/UserStore/ChangePassword?loginName=<UserStoreUserLoginName>&tenantid=<TenantId>&idpinstanceid=<IdpInstanceId>

In addition to the required query parameters, the following optional query parameters can be added:

  • clientId

    The id of the client app. This information will be used to find the proper view customization if the views are customized for a specific client application

  • changePwReturnUrl

    If the password change has been successful, a confirmation page will be shown. If the changePwReturnUrl is provided, the user will be redirected to this URL without showing a confirmation page.

To simplify the usage of the password change links, the claim engine can be used to add a new claim for the identity token which contains the password change link. The claim engine rule definition is as follows:

  • RuleType

    Create

  • Type Transformation Replacement

    i.e. pwchangeurl

  • Value Transformation Replacement

    {% if Context.IsUserStoreLogin %}https://{{ Context.Host }}/UserStore/ChangePassword?loginName={{ Context.LoginName }}&tenantid={{ Context.TenantId }}&idpinstanceid={{ Context.IdpInstanceId }}&clientid={{ Context.ClientAppId }}{% endif %}

Brute Force Protection

ProAuth provides comprehensive brute force protection for UserStore authentication. Three independent mechanisms can be configured to protect user accounts from unauthorized access attempts: permanent account locking, temporary account locking, and progressive login throttling. Each mechanism is configured per UserStore IDP instance and can be enabled independently or combined for a layered defense.

Permanent Account Locking

When enabled, a user account is permanently locked after a configured number of consecutive failed login attempts. A locked account must be unlocked manually by an administrator through the Admin UI, the Management API, or the UserStore API.

A successful login resets the failed attempt counter to zero.

Configuration

OptionDescriptionDefault
AttemptsBeforeUserLockedMaximum number of consecutive failed login attempts before the account is permanently locked. Set to 0 or leave empty to disable permanent locking.disabled

TIP

Permanent locking is well suited for high-security environments. Combine it with the user lock notification (see User lock notifications) to alert administrators when an account is locked so they can take immediate action.

WARNING

If permanent locking is the only mechanism enabled, an attacker can deliberately lock out legitimate users by repeatedly submitting wrong passwords. Consider enabling temporary locking or throttling in addition.

Temporary Account Locking

Temporary locking automatically locks a user account for a configurable duration after a number of consecutive failed login attempts. Once the lock duration expires, the user can attempt to log in again. This protects accounts without requiring administrator intervention.

While a temporary lock is active, all login attempts are rejected — even if the correct password is provided. The failed attempt counter is not incremented during the lock period.

Configuration

OptionDescriptionDefault
TemporaryLockEnabledEnable or disable temporary account locking.false
TemporaryLockThresholdNumber of consecutive failed login attempts before a temporary lock is applied.5
TemporaryLockDurationSecondsDuration of the temporary lock in seconds. After this period, the account is automatically unlocked.3600 (1 hour)

INFO

Temporary locking and permanent locking use the same failed attempt counter but operate independently. If both are enabled, make sure the permanent lock threshold is higher than the temporary lock threshold. Otherwise the account will be permanently locked before a temporary lock can take effect.

Example

With TemporaryLockThreshold = 3 and TemporaryLockDurationSeconds = 600:

  1. The user fails 3 consecutive login attempts.
  2. The account is temporarily locked for 10 minutes.
  3. After 10 minutes, the user can attempt to log in again.
  4. If the user then enters the correct password, the counter resets and the lock is cleared.

Progressive Login Throttling

Throttling introduces an artificial, progressively increasing delay before each login response. The delay grows exponentially with the number of consecutive failed attempts, making automated brute force attacks impractical while keeping the impact on legitimate users minimal.

Configuration

OptionDescriptionDefault
ThrottlingEnabledEnable or disable progressive login throttling.false
ThrottlingBaseDelayMsBase delay in milliseconds applied after the first failed login attempt.1000
ThrottlingMaxDelayMsMaximum delay cap in milliseconds. The delay will never exceed this value.30000

Delay Formula

The delay for each failed attempt is calculated using exponential backoff:

$$\text{delay} = \min!\bigl(\text{BaseDelayMs} \times 2^{(\text{failedAttempts} - 1)},; \text{MaxDelayMs}\bigr)$$

A successful login resets the failed attempt counter and the delay returns to zero.

Example Delay Progression

With ThrottlingBaseDelayMs = 1000 and ThrottlingMaxDelayMs = 30000:

Failed AttemptsDelay
11,000 ms (1 s)
22,000 ms (2 s)
34,000 ms (4 s)
48,000 ms (8 s)
516,000 ms (16 s)
6+30,000 ms (30 s, capped)

TIP

Throttling is the least disruptive protection mechanism. It does not prevent correct passwords from succeeding, it only adds a delay. This makes it a good default choice that can be combined with the other mechanisms.

Combining Mechanisms

All three protection mechanisms can be enabled at the same time for defense in depth. They are evaluated in the following order:

  1. Temporary lock — if active, the request is rejected immediately without checking credentials.
  2. Throttling — an artificial delay is applied before the credential check.
  3. Credential check — password validation is performed.
  4. Counter update — on failure, the failed attempt counter increments.
  5. Lock evaluation — permanent and temporary lock thresholds are evaluated against the updated counter.

When using all three mechanisms together, configure the thresholds so they take effect in the desired order:

MechanismRecommended Threshold
Throttlingenabled (base: 1000 ms, max: 30000 ms)
Temporary Lockthreshold: 5 attempts, duration: 300 seconds
Permanent Lockthreshold: 10 attempts

This ensures:

  • Attempts 1–4: progressively increasing delays slow down attackers
  • Attempt 5: temporary lock engages, blocking all attempts for 5 minutes
  • After unlock: if the user continues to fail, delays resume
  • Attempt 10: permanent lock engages, requiring admin intervention

INFO

The failed attempt counter is shared across all three mechanisms. A successful login at any point resets the counter and clears any active temporary lock.

Lock Message Behavior

By default, when a user submits the correct password while the account is locked, ProAuth shows a specific error message indicating the lock state ("This account is locked out." for permanent locks, "This account is temporarily locked. Please try again later." for temporary locks). When the password is wrong, a generic "Invalid username or password." message is always returned regardless of the lock state.

In penetration-tested or high-security environments, showing a specific lock message after a correct password can be considered a side-channel — it reveals that the attacker guessed the correct password. To mitigate this, the InformAboutLockAfterSuccessfulLogin option can be set to false. When disabled, ProAuth returns the generic error message for both correct and incorrect passwords while the account is locked.

OptionDescriptionDefault
InformAboutLockAfterSuccessfulLoginWhen true, shows specific lock messages after a successful credential check on a locked account. When false, returns the generic "Invalid username or password" message in all cases.true

TIP

For internal or enterprise deployments where users need to understand why they cannot log in, keep the default (true). For public-facing or pentest-hardened deployments, set this option to false.

Configuration via Management API

Brute force protection options are configured as UserStore IDP instance options through the Management API. Options are set per IDP instance using the standard option endpoint:

http
PUT /api/v1/options
Content-Type: application/json

{
  "name": "ThrottlingEnabled",
  "value": "true",
  "applyToIdpInstanceId": "<idp-instance-id>"
}

All brute force protection options follow the same pattern. Replace name and value accordingly:

Option NameTypeExample Value
AttemptsBeforeUserLockedinteger10
TemporaryLockEnabledbooleantrue
TemporaryLockThresholdinteger5
TemporaryLockDurationSecondsinteger3600
ThrottlingEnabledbooleantrue
ThrottlingBaseDelayMsinteger1000
ThrottlingMaxDelayMsinteger30000
InformAboutLockAfterSuccessfulLoginbooleantrue

Infrastructure Rate Limiting

ProAuth's brute force protection operates at the application level and tracks failed attempts per user account. This is the primary security mechanism and should always be enabled.

Infrastructure-level rate limiting at your reverse proxy or load balancer provides an additional layer for protecting system resources:

Why Per-User Protection is Primary

ProAuth tracks failed attempts per username, not per IP or session:

  • Protection applies regardless of the client's network origin
  • Effective for users behind shared IPs (corporate NAT, VPNs, mobile carriers)
  • Consistent enforcement across load-balanced deployments

Infrastructure rate limiting complements this by protecting system resources (CPU, connections, bandwidth) from high-volume attacks.

LayerMechanismPurpose
CDN / WAFIP reputation and anomaly detectionBlock known malicious sources
Reverse ProxyConnection rate limitingPrevent resource exhaustion
Load BalancerConnection limitsProtect backend capacity

Example: NGINX Rate Limiting

nginx
http {
    limit_req_zone $binary_remote_addr zone=login:10m rate=10r/s;

    server {
        location /signin {
            limit_req zone=login burst=20 nodelay;
            proxy_pass http://proauth;
        }
    }
}

TIP

Infrastructure rate limiting protects system resources. ProAuth's per-user mechanisms protect individual accounts. Enable both for defense in depth.

Best Practices

Defense in Depth

Brute force protection is one layer of a comprehensive authentication security strategy. For robust protection, combine it with:

MeasurePurpose
Strong password policiesReduce effectiveness of dictionary attacks
Multi-factor authenticationRequire additional verification beyond passwords
Password breach detectionPrevent use of compromised credentials
Security monitoring (SIEM)Detect and respond to attack patterns

For most deployments, enable all three mechanisms with the following configuration:

OptionRecommended ValueRationale
ThrottlingEnabledtrueLow-impact baseline protection
ThrottlingBaseDelayMs1000Noticeable delay without impacting legitimate users
ThrottlingMaxDelayMs30000Caps delay at 30 seconds
TemporaryLockEnabledtrueAuto-recovers without admin intervention
TemporaryLockThreshold5 to 10Balance between security and usability
TemporaryLockDurationSeconds300 to 9005–15 minutes deters automated attacks
AttemptsBeforeUserLocked15 to 20 (or disabled)Only for high-security environments
InformAboutLockAfterSuccessfulLoginfalseRecommended for public-facing deployments

High-Security Environments

For deployments requiring stricter controls:

  • Enable permanent locking with administrator notification
  • Set InformAboutLockAfterSuccessfulLogin to false
  • Require multi-factor authentication for all users
  • Integrate with a SIEM for real-time alerting
  • Enable CAPTCHA protection for public-facing login pages

Distributed Deployments

ProAuth stores protection state in the database, ensuring consistent enforcement across all instances in a load-balanced deployment. No additional configuration is required for clustered environments.

Monitoring and Alerting

ProAuth exposes OpenTelemetry metrics for security events:

MetricDescription
userstore_temporary_lock_totalTemporary locks applied
userstore_permanent_lock_totalPermanent locks applied

Configure alerts for elevated lock rates, which may indicate an attack in progress or misconfigured thresholds affecting legitimate users.

Configure your monitoring system (Prometheus, Azure Monitor, Datadog, etc.) to alert on:

  • Sudden spikes in lock events (possible attack in progress)
  • Sustained elevated lock rates (credential stuffing campaign)
  • Locks on privileged accounts (admin, service accounts)

CAPTCHA Protection

In addition to throttling and locking, ProAuth supports CAPTCHA challenges to distinguish human users from automated bots. CAPTCHA provides an additional layer of protection against credential stuffing and brute force attacks, particularly effective for public-facing login pages.

Supported Providers

ProAuth integrates with three privacy-focused CAPTCHA providers. All providers are GDPR-compliant and do not use invasive tracking.

ProviderDescriptionDocumentation
Cloudflare TurnstileFree, privacy-focused, invisible challenges. Default provider.developers.cloudflare.com/turnstile
hCaptchaPrivacy-focused alternative to reCAPTCHA, supports accessibility.docs.hcaptcha.com
Friendly CaptchaEU-based, proof-of-work based, no cookies required.docs.friendlycaptcha.com

Recommended Provider

Cloudflare Turnstile is the recommended CAPTCHA provider. It is free, fully compatible with ProAuth's default security headers, and requires no additional configuration beyond the site key and secret key.

Cross-Origin-Embedder-Policy Override Required

hCaptcha and Friendly Captcha require cross-origin resources that are blocked by ProAuth's default Cross-Origin-Embedder-Policy: require-corp header. To use these providers, set the CrossOriginEmbedderPolicy base service setting to UnsafeNone:

json
"BaseServiceSettings": {
  "CrossOriginEmbedderPolicy": "UnsafeNone"
}

Or via Helm values:

yaml
appsettings:
  baseservicesettings:
    crossoriginembedderpolicy: "UnsafeNone"

This relaxation is safe because ProAuth applies other security headers (Content-Security-Policy, X-Frame-Options, Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy) that prevent framing and cross-origin attacks. The strict require-corp default is retained because it provides defense-in-depth for deployments that use Turnstile or do not use CAPTCHA.

INFO

Google reCAPTCHA is intentionally not supported due to privacy concerns. The supported providers offer comparable bot detection while respecting user privacy.

Activation Modes

CAPTCHA can be configured with three activation modes to balance security and user experience:

ModeDescription
DisabledCAPTCHA is never shown. This is the default.
AlwaysCAPTCHA is required on every login attempt.
AfterFailuresCAPTCHA is required only after a configured number of consecutive failed login attempts.

The AfterFailures mode provides a good balance — legitimate users entering correct credentials are not challenged, while repeated failures trigger CAPTCHA to stop automated attacks.

Configuration

CAPTCHA is configured per UserStore IDP instance. You must first register with your chosen CAPTCHA provider to obtain a site key and secret key.

OptionDescriptionDefault
CaptchaActivationModeWhen CAPTCHA is required: Disabled, Always, or AfterFailures.Disabled
CaptchaFailureThresholdNumber of consecutive failed login attempts before CAPTCHA is required (only applies when mode is AfterFailures).3
CaptchaProviderCAPTCHA provider to use: Turnstile, HCaptcha, or FriendlyCaptcha.Turnstile
CaptchaSiteKeyPublic site key from your CAPTCHA provider. Displayed in the browser.
CaptchaSecretKeySecret key for server-side verification. Keep this confidential.

Configuration via Management API

CAPTCHA options are configured as UserStore IDP instance options through the Management API:

http
PUT /api/v1/options
Content-Type: application/json

{
  "name": "CaptchaActivationMode",
  "value": "AfterFailures",
  "applyToIdpInstanceId": "<idp-instance-id>"
}

Configure all required options:

Option NameTypeExample Value
CaptchaActivationModestringAfterFailures
CaptchaFailureThresholdinteger3
CaptchaProviderstringTurnstile
CaptchaSiteKeystring0x4AAA...
CaptchaSecretKeystring0x4AAA...

WARNING

The CaptchaSecretKey is sensitive and must be kept confidential. Store it securely and avoid logging or exposing it in client-side code.

Provider Setup

Cloudflare Turnstile

  1. Sign up at dash.cloudflare.com and navigate to Turnstile
  2. Add a new site and configure your domain
  3. Choose widget mode: Managed (recommended), Non-interactive, or Invisible
  4. Copy the Site Key and Secret Key to ProAuth configuration

hCaptcha

  1. Sign up at dashboard.hcaptcha.com
  2. Add a new site and configure your domain
  3. Copy the Site Key and Secret Key to ProAuth configuration
  4. Optionally enable Enterprise features for passive detection

Friendly Captcha

  1. Sign up at friendlycaptcha.com
  2. Create an application and configure your domain
  3. Copy the Site Key and API Key to ProAuth configuration

Integration with Other Protections

CAPTCHA operates alongside the other brute force protection mechanisms. The evaluation order is:

  1. Temporary lock — if active, reject immediately
  2. CAPTCHA — if required based on activation mode, verify challenge
  3. Throttling — apply progressive delay
  4. Credential check — validate password
  5. Counter update and lock evaluation — update failed attempts, check lock thresholds

TIP

For maximum protection, enable CAPTCHA in AfterFailures mode (threshold 2–3) combined with throttling and temporary locking. This provides layered defense: CAPTCHA stops bots, throttling slows attackers, and locking halts persistent attacks.

ScenarioCaptchaActivationModeCaptchaFailureThreshold
Internal enterprise applicationDisabled
Public-facing applicationAfterFailures3
High-security or under attackAlways

INFO

The AfterFailures mode tracks failed attempts per user account. An attacker targeting multiple accounts will trigger CAPTCHA on each account individually after the threshold is reached.