Configuration

Full reference for every option accepted by the configuration function.

The IAM service is initialized by calling configuration() with a single typed object. The schema is validated at startup with Zod and any missing or invalid field throws immediately, preventing the service from starting with a broken config.

server.ts
import { configuration } from '@riavzon/auth'

await configuration({
  store: { /* ... */ },
  password: { pepper: process.env.PEPPER! },
  botDetector: { enableBotDetector: true },
  htmlSanitizer: { IrritationCount: 50, maxAllowedInputLength: 50000 },
  magic_links: { /* ... */ },
  jwt: { /* ... */ },
  email: { resend_key: process.env.RESEND_KEY!, email: '[email protected]' },
})
Call configuration() once before mounting any routes. The service reads the resolved config on every request: calling it more than once replaces the previous config globally.

store

Database connection pools for the main application database and the rate-limiter store. Both pools accept any valid mysql2 PoolOptions object.

main
mysql.PoolOptions required
Primary MySQL connection pool used for visitor persistence, token storage, user accounts, and all core queries.
rate_limiters_pool
object required
Connection pool dedicated to the rate-limiter tables. Keeping rate-limiter state in a separate database prevents lock contention with the main application pool under heavy load.
store
mysql.PoolOptions required
MySQL connection options for the rate-limiter database.
dbName
string required
Database name for the limiter tables. Must match the database created for rate-limiter state.
server.ts
store: {
  main: { host: 'localhost', user: 'root', password: 'secret', database: 'auth' },
  rate_limiters_pool: {
    store: { host: 'localhost', user: 'root', password: 'secret', database: 'auth_limiters' },
    dbName: 'auth_limiters',
  },
}
You can point both pools at the same MySQL server with different database names, or use separate servers for isolation.

service

Runtime service settings for proxy trust, port binding, and optional HMAC inter-service authentication. This entire section is optional.

Hmac
object
When present, enables HMAC request signing and verification for inter-service calls. See the HMAC guide for full details.
proxy
object required
Proxy and IP extraction settings. Required when service is provided.
port
number
Port the service listens on when running in standalone mode.
ipAddress
string
IP address to bind when running in standalone mode.
clientIp
string
Override for client IP extraction. Use this when your reverse proxy sets a non-standard header for the real client IP.
sharedSecret
string required
Shared secret used to sign and verify HMAC request signatures. Must match between all communicating services.
clientId
string required
Client identifier sent with every HMAC-signed request. The receiving service uses this to look up the correct shared secret.
maxClockSkew
number required
Maximum allowed clock skew in milliseconds between the signing and verifying services. Defaults to 300000 (5 minutes). Requests with a timestamp outside this window are rejected.
trust
boolean required
Whether to trust X-Forwarded-* headers from the upstream proxy. Set to true when running behind a reverse proxy such as Nginx or Caddy.
ipToTrust
string required
Specific proxy IP address to trust. Only X-Forwarded-* headers from this IP are accepted.
server
string
Optional upstream server identifier for logging and diagnostics.

password

Controls Argon2id password hashing parameters. The pepper value is combined with the user's password before hashing: rotate it to invalidate all existing hashes.

pepper
string required
Secret added to every password before hashing. Store this in an environment variable or a secrets manager. Never commit it to version control.
hashLength
number
Default: 50. Output hash length in bytes.
timeCost
number
Default: 4. Argon2 time cost (number of iterations). Higher values increase resistance to brute-force attacks at the cost of slower hashing.
memoryCost
number
Default: 262144 (256 MiB). Memory usage in KiB. Higher values make GPU-based attacks more expensive.
Store pepper in an environment variable or a secrets manager. Never commit it to version control.

botDetector

Controls whether the Bot Detector module runs during authentication flows. When enabled, IP geolocation and device fingerprinting data feed directly into anomaly detection. This is a discriminated union keyed on enableBotDetector.

enableBotDetector
boolean required
Set to true to enable the Bot Detector middleware with active scoring and blocking. Set to false to switch to passive mode (see below).
settings
BotDetectorConfigInput
Only available when enableBotDetector is true. Optional custom configuration passed directly to the Bot Detector module. See the Bot Detector Configuration for the full reference.
// Passive mode
botDetector: { enableBotDetector: false }

// Enabled with defaults
botDetector: { enableBotDetector: true }

// Enabled with custom settings
botDetector: {
  enableBotDetector: true,
  settings: { banScore: 75, checkers: { enableTorAnalysis: { enable: false } } },
}

Passive mode

Setting enableBotDetector to false does not shut the Bot Detector down. The middleware still runs and maintains its database connection, but it switches to a passive configuration that disables all active scoring:

  • All 17 security checkers are disabled (IP checks, geo checks, TOR analysis, browser/device checks, session coherence, velocity fingerprinting, and so on).
  • maxScore is raised from 100 to 300, making it virtually impossible for any request to reach the ban threshold.
  • restoredReputationPoints drops from 10 to 1, so scores heal much more slowly across requests.
  • logLevel changes from info to warn, reducing noise to only warnings.

The bot detector still tracks requests and maintains reputation data in the database. This means you can switch back to active mode at any time without losing historical context. Passive mode is useful during development, initial deployment, or when you want to observe traffic patterns before enforcing scoring rules.


htmlSanitizer

Controls the multi-pass XSS sanitization pipeline applied to all user-supplied strings before they reach the database. See XSS Protection for full details on the sanitization process.

IrritationCount
number required
Default: 50. Number of sanitization loop iterations. Each pass strips one layer of encoded or obfuscated HTML. Keep this high enough to catch layered obfuscation but not so high that it becomes a CPU exhaustion vector under load.
maxAllowedInputLength
number required
Default: 50000. Maximum number of bytes accepted in a single input string. Inputs exceeding this length are rejected before sanitization begins.

Configuration for signed temporary JWT links used in email MFA and password-reset flows. See Magic Links and MFA for usage details.

jwt_secret_key
string required
HMAC secret used to sign and verify magic link tokens. Must be different from the main JWT secret.
expiresIn
string | number
Token lifetime as a string ("20m") or number of seconds (1200). Mutually exclusive with expiresInMs.
expiresInMs
number
Token lifetime in milliseconds. Mutually exclusive with expiresIn.
domain
string required
Full origin including the protocol. Used to construct the magic link URL sent in emails.
maxCacheEntries
number
Maximum number of issued link tokens held in the in-memory LRU cache. Each token is cached until it is consumed or expires.
thresholds
object
Per-flow thresholds that limit how many times a user can request or consume a magic link before the flow is temporarily locked.
linkToResetPasswordPage
string
Default: "https://localhost/accounts". The URL the user is redirected to when they click a password-reset magic link.
emailImages
object
URLs for images embedded in OTP and notification emails.
paths
object
Route paths the magic link URLs resolve to on your frontend.
notificationEmail
object required
Branding and link configuration for system notification emails.

thresholds

Each threshold object controls how many GET requests (page loads) and POST requests (form submissions) a user can make to a specific magic link flow before the service stops issuing new links.

allowedPerSuccessfulGet
number
Default: 5. Maximum page loads allowed for the adaptive MFA verification page.
allowedPerSuccessfulPost
number
Default: 3. Maximum form submissions allowed for the adaptive MFA verification page.
allowedPerSuccessfulGet
number
Default: 5. Maximum page loads for the password-reset verification page.
allowedPerSuccessfulPost
number
Default: 3. Maximum form submissions for the password-reset verification page.
allowedPerSuccessfulGet
number
Default: 5. Maximum page loads for custom MFA and email-change flows.
allowedPerSuccessfulPost
number
Default: 3. Maximum form submissions for custom MFA and email-change flows.

emailImages

URLs for images embedded in outgoing emails. All fields have default values pointing to the Riavzon media CDN.

bannerImage
string
URL for the banner image shown at the top of OTP emails.
device_image
string
URL for the device icon shown next to the device name in OTP emails.
location_image
string
URL for the location icon shown next to the geographic location in OTP emails.
date_image
string
URL for the date/time icon shown next to the timestamp in OTP emails.
emailImages.notificationBanner
string
Default banner image URL for notification emails.

paths

Route paths that magic link URLs resolve to on your frontend. All defaults point to /auth/bounce.

pathForCustomFlow
string
Default: "/auth/bounce". Path used for custom MFA flow magic links.
pathForPasswordResetLink
string
Default: "/auth/bounce". Path used for password-reset magic links.
pathForAdaptiveMfaLink
string
Default: "/auth/bounce". Path used for adaptive MFA magic links.

notificationEmail

Branding and navigation links included in all system notification emails (login alerts, password-change alerts, etc.).

websiteName
string
Default: "Security Service". Display name shown in the email header and subject line.
privacyPolicyLink
string required
URL to your privacy policy page. Included in the email footer.
contactPageLink
string required
URL to your contact page. Included in the email footer so users can report suspicious activity.
changePasswordPageLink
string required
URL to your password-change page. Included in login-alert emails so users can immediately secure their account.
loginPageLink
string required
URL to your login page. Included in notification emails as a navigation link.

providers

Defines the OAuth social login providers the service accepts. Each entry maps an incoming OAuth profile to the internal user schema. This field is optional: omit it entirely if your application does not use social login.

Each provider is defined using one of two approaches:

Custom Zod schema: Full control over validation and transformation.

providers: [
  {
    name: 'github',
    schema: z.object({
      id: z.number(),
      login: z.string(),
      email: z.string().email(),
      avatar_url: z.string().url(),
    }),
  },
]

Field-type map: A shorthand that builds the schema automatically from a record of field names to type tokens.

providers: [
  {
    name: 'google',
    useStandardProfile: true,
    fields: {
      sub: 'string',
      email: 'email',
      name: 'safeString',
      picture: 'url?',
    },
  },
]

FieldToken is one of: 'string', 'string?', 'email', 'email?', 'boolean', 'boolean?', 'url', 'url?', 'number', 'number?', 'int', 'int?', 'safeString', 'safeString?'. Append ? to mark a field optional.

See OAuth for a full provider definition example.


trustUserDeviceOnAuth

trustUserDeviceOnAuth
boolean
Default: false. When true, a successful login marks the device as trusted and skips adaptive MFA when the canary cookie is missing on the next session. This reduces friction for users who log in from the same device frequently but weakens the anomaly detection layer.

jwt

Controls both access token and refresh token behavior.

jwt_secret_key
string required
HMAC or RSA key used to sign access tokens. Must be kept secret. Use an environment variable or secrets manager.
access_tokens
object required
Configuration for short-lived access tokens.
refresh_tokens
object required
Configuration for long-lived refresh tokens stored hashed in MySQL.

access_tokens

expiresIn
string | number
Token lifetime as a string ("15m") or number of seconds. Mutually exclusive with expiresInMs.
expiresInMs
number
Token lifetime in milliseconds. Mutually exclusive with expiresIn.
algorithm
string
Signing algorithm. Supported values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512.
audience
string
aud claim set on every access token.
issuer
string
iss claim set on every access token.
subject
string
sub claim set on every access token.
maxCacheEntries
number
LRU cache size for verified access tokens. Cached tokens skip the cryptographic verification step on subsequent requests within their lifetime.
payload
Record<string, unknown>
Extra claims merged into every access token payload. Use this to include application-specific data such as roles or permissions.

refresh_tokens

refresh_ttl
number required
Refresh token lifetime in milliseconds. After this duration, the token is considered expired and the user must re-authenticate.
domain
string required
Cookie domain for the refresh token cookie. Set this to your root domain (e.g. "example.com") so the cookie is sent on all subdomains.
MAX_SESSION_LIFE
number required
Maximum total session lifetime in milliseconds. Even if the refresh token is continuously rotated, the session is forcibly ended after this duration.
maxAllowedSessionsPerUser
number required
Maximum number of concurrent active sessions allowed per user. When a new login exceeds this limit, the oldest session is invalidated.
byPassAnomaliesFor
number required
Duration in milliseconds after a successful MFA verification during which anomaly detection checks are bypassed. This prevents the user from being challenged again immediately after proving their identity.

See Tokens for full token lifecycle details.


email

Resend API credentials used for all outgoing system and MFA emails.

resend_key
string required
Your Resend API key.
email
string required
The From address for all outgoing emails (e.g. "[email protected]"). This address must be verified in your Resend account.

rate_limiters

Fine-grained rate-limiter configurations for every sensitive endpoint. This entire section is optional, and every individual limiter group within it is also optional. When the section or any group is omitted, the service falls back to built-in defaults. Rate limiting is always active. Every individual limiter within each group shares the same shape:

inMemoryBlockOnConsumed
number
Number of consumed points at which the in-memory block triggers. This provides fast rejection without hitting the database.
points
number
Number of allowed requests per duration window.
duration
number
Window length in seconds.
blockDuration
number
How long in seconds the client is blocked after exceeding the limit.
inMemoryBlockDuration
number
How long in seconds the in-memory block lasts.

See Rate Limiting for detailed usage examples, union limiter patterns, and the full schema for each group.

linkVerificationLimiter

Protects /auth/verify-mfa and /auth/reset-password endpoints.

unionLimiter.burstLimiter
LimiterConfig
Short-window burst limiter. Catches rapid-fire verification attempts.
unionLimiter.slowLimiter
LimiterConfig
Long-window slow limiter. Catches distributed or slow-burn enumeration attempts.

loginLimiters

Protects POST /login.

unionLimiter.burstLimiter
LimiterConfig
Short-window burst limiter for login attempts.
unionLimiter.slowLimiter
LimiterConfig
Long-window slow limiter for login attempts.
ipLimiter
LimiterConfig
Per-IP limiter applied independently of the union limiter.
emailLimiter
LimiterConfig
Per-email limiter that prevents credential stuffing against a single account.

oauthLimiters

Protects POST /auth/OAuth/:providerName.

unionLimiter.ipLimiterBrute
LimiterConfig
Short-window burst limiter keyed by IP.
unionLimiter.ipLimiterSlow
LimiterConfig
Long-window slow limiter keyed by IP.
subLimiter
LimiterConfig
Per-subject limiter that limits attempts per OAuth subject identifier.
compositeKeyLimiter
LimiterConfig
Composite key limiter combining IP and subject for fine-grained control.

signupLimiters

Protects POST /signup.

unionLimiters.uniLimiterIp.ipLimit
LimiterConfig
Short-window IP burst limiter for signups.
unionLimiters.uniLimiterIp.slowIpLimit
LimiterConfig
Long-window IP slow limiter for signups.
unionLimiters.uniLimiterComposite.compositeKeyLimit
LimiterConfig
Short-window composite key (IP + email) burst limiter.
unionLimiters.uniLimiterComposite.slowCompositeKeyLimit
LimiterConfig
Long-window composite key slow limiter.
emailLimit
LimiterConfig
Per-email limiter that prevents mass account creation with variations of the same address.

tempPostRoutesLimiters

Protects temporary POST routes such as email update and custom MFA initiation.

unionLimiters.limit
LimiterConfig
Short-window burst limiter.
unionLimiters.slowLimit
LimiterConfig
Long-window slow limiter.
ipLimit
LimiterConfig
Per-IP limiter applied independently of the union limiter.

tokenLimiters

Protects the /auth/user/refresh-session rotation route and the /auth/logout route.

unionLimiters.refreshAccessTokenLimiter.accessTokenBrute
LimiterConfig
Short-window burst limiter for access token refresh.
unionLimiters.refreshAccessTokenLimiter.accessTokenSlow
LimiterConfig
Long-window slow limiter for access token refresh.
unionLimiters.refreshTokenLimiterUnion.refreshTokenBrute
LimiterConfig
Short-window burst limiter for refresh token rotation.
unionLimiters.refreshTokenLimiterUnion.refreshTokenSlow
LimiterConfig
Long-window slow limiter for refresh token rotation.
refreshTokenLimiter
LimiterConfig
Standalone limiter applied to all refresh token operations.

initPasswordResetLimiters

Protects POST /auth/forgot-password.

unionLimiters.limit
LimiterConfig
Short-window burst limiter.
unionLimiters.longLimiter
LimiterConfig
Long-window slow limiter.
ipLimiter
LimiterConfig
Per-IP limiter.
emailLimiter
LimiterConfig
Per-email limiter that prevents password-reset spam against a single account.

emailMfaLimiters

Protects email MFA sending endpoints.

unionLimiters.limit
LimiterConfig
Short-window burst limiter.
unionLimiters.longLimiter
LimiterConfig
Long-window slow limiter.
ipLimiter
LimiterConfig
Per-IP limiter.
userIdLimiter
LimiterConfig
Per-user limiter that prevents a single user from triggering excessive MFA emails.
globalEmailLimiter
LimiterConfig
Global limiter that caps the total number of MFA emails sent across all users. Protects your Resend quota from abuse.

logLevel

logLevel
'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'
Pino log level for the service logger. Use 'debug' during development to see detailed request processing. Set 'warn' or 'error' in production to reduce log volume.
Logo