Skip to content

Configuration ​

The optional AuthCredentials section is bound to AuthCredentialsSettings, with lockout and two-factor values on nested objects. Token issuer, secret, and lifetimes live in the Auth section instead, because they describe token minting rather than credentials.

json
{
    "AuthCredentials": {
        "AbsoluteSessionLifetimeDays": 30,
        "PasswordResetMinutes": 60,
        "EmailVerificationMinutes": 1440,
        "ForgotPasswordMinimumMilliseconds": 200,
        "Lockout": {
            "Enabled": false,
            "MaxFailedAttempts": 5,
            "DurationMinutes": 15
        },
        "TwoFactor": {
            "Issuer": null,
            "RecoveryCodeCount": 10,
            "Digits": 6,
            "PeriodSeconds": 30,
            "PendingSecretMinutes": 10,
            "ChallengeMinutes": 5
        }
    }
}

DANGER

Changing Digits or PeriodSeconds invalidates every existing enrolment. An authenticator was set up from the values in force when the user scanned the code, and it keeps generating codes to those, so every enrolled user has to enrol again after the change.

AuthCredentialsSettings

The AuthCredentials section itself. Every value has a default, so the section may be absent.

Fields

Lockout: LockoutPolicy
The nested Lockout object, bound to LockoutPolicy.

TwoFactor: TwoFactorPolicy
The nested TwoFactor object, bound to TwoFactorPolicy.

AbsoluteSessionLifetimeDays: int?
Ceiling on a session's total life, measured from creation, so refreshing cannot extend it forever. It bounds the expiry written when a session opens as well, and a session already that old is refused its next refresh rather than renewed. An explicit null removes the cap; an absent key keeps 30 days.
Default: 30

PasswordResetMinutes: int
How long a password reset token stays usable after it is issued. Shorter is safer, because the token arrives by email and email is not a secure channel.
Default: 60

EmailVerificationMinutes: int
How long a verification token stays redeemable after it is issued. One value covers both confirming a sign-up address and confirming a change of address, and the default is a day because such a link is commonly opened on another device.
Default: 1440

ForgotPasswordMinimumMilliseconds: int
The floor a forgot-password request is held to, so issuing a token and finding no account take the same time. Raise it above the slower of the two paths on your own hardware, or the difference stays measurable.
Default: 200

LockoutPolicy

The nested AuthCredentials:Lockout section. Disabled by default, deliberately: locking on failure count alone lets anyone deny service to a known account by failing logins against it.

Fields

Enabled: bool
Whether repeated login failures lock the account. Enable it when you have a way to distinguish an attacker from the account owner, such as rate limiting by IP in front of the application.
Default: false

MaxFailedAttempts: int
Consecutive failures before the account locks, counting wrong two-factor codes alongside wrong passwords. Every attempt is counted before the password or code it presents is checked, so this bounds concurrent guesses as well as sequential ones. The counter resets on any completed sign-in, so it measures a run of failures rather than a lifetime total. A correct password that only buys a two-factor challenge finishes nothing, so it neither clears the run nor adds to it.
Default: 5

DurationMinutes: int
How long the account stays locked. The expiry is carried on the lockout failure so a client can say when to try again.
Default: 15

TwoFactorPolicy

The nested AuthCredentials:TwoFactor section, describing the codes this package generates and accepts.

Fields

Issuer: string?
The name an authenticator app shows above the code. When left unset, the issuer passed to BeginEnrolmentAsync is used, which lets one deployment label each app it hosts differently.
Default: null

RecoveryCodeCount: int
How many single-use recovery codes are issued when enrolment completes. They are shown once and stored only as hashes.
Default: 10

Digits: int
The length of a generated code. Six is what authenticator apps assume; eight is accepted by most but not all of them.
Default: 6

PeriodSeconds: int
How long one code stays valid. The adjacent windows are also accepted, so the real tolerance is roughly three times this value.
Default: 30

PendingSecretMinutes: int
How long a secret offered by an enrolment stays confirmable before it is refused. An enrolment left unfinished expires without touching the secret already in use, so an interrupted setup cannot cost a user their working authenticator.
Default: 10

ChallengeMinutes: int
How long the challenge a sign-in hands back stays redeemable, which is what bounds the code prompt. Past it the user has to send their password again. Long enough to fetch a code from a phone, short enough that a half-finished sign-in left on a shared machine stops being completable.
Default: 5

All packages are released under the MIT License.