Attack Protection
Auris ships with multiple defense layers that activate on every authentication request. These systems operate independently but are layered in a specific pipeline — each check runs in sequence so that later, more expensive checks are only reached after cheaper initial filters pass.
Rate Limiting
Auris applies sliding-window rate limiting to all API endpoints. Rate limits are enforced in-memory per instance and are not shared across instances in a multi-node deployment — if you require distributed rate limiting, configure a Redis-backed shared store.
Tiers
| Tier | Applies to | Default limits |
|---|---|---|
| auth | Login, signup, and logout endpoints | Strict limits to prevent credential stuffing |
| sensitive | Password reset, 2FA enrollment, 2FA verification | Strict limits, separate per-user and per-IP buckets |
| api | General authenticated API endpoints | Moderate limits per authenticated user |
| public | Open endpoints (status pages, SCIM, public checkout) | Liberal limits, IP-based only |
Exact limit values are configurable per-tier via environment variables or the Console (Console → Security → Rate Limiting).
Response headers
All API responses from rate-limited endpoints include standard headers:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the current window resets |
Retry-After | Seconds until the client may retry (only present on 429 responses) |
When a rate limit is exceeded, Auris returns HTTP 429 Too Many Requests with the Retry-After header. Clients should respect this header and back off accordingly.
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1718016000
Retry-After: 47
Content-Type: application/json
{
"ok": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please try again in 47 seconds."
}
}Brute-Force Protection
Auris tracks failed login attempts per user account and per IP address. After a configurable number of consecutive failures, the account or IP is locked out for an escalating duration.
How lockout works
- Each failed login attempt creates a
LoginAttemptrecord with timestamp, IP, and user agent. - When the failure count for an account or IP exceeds the configured threshold within the observation window, an
AccountLockoutrecord is created. - During a lockout, all login attempts for the affected account return
HTTP 423 Lockedimmediately — Keycloak authentication is not attempted. - Lockout duration escalates with repeated lockouts: first lockout = 5 minutes, second = 30 minutes, third = 24 hours (configurable).
Configuration
Configure via Console → Security → Brute-Force Protection:
| Setting | Default | Notes |
|---|---|---|
| Failed attempts before lockout | 5 | Count resets after a successful login |
| Observation window | 15 minutes | Only attempts within this window count toward the threshold |
| Initial lockout duration | 5 minutes | |
| Escalation multiplier | 6x | Each subsequent lockout is 6× longer |
| Maximum lockout duration | 24 hours | |
| IP-based lockout | Enabled | Lock the IP after failures across multiple accounts |
Manual unlock
Administrators can manually unlock accounts via the Console (User detail → Security → Unlock Account) or API:
/api/admin/lockouts/[userId]Requires: manage:usersClears all active lockouts for the specified user and resets the failed attempt counter.
/api/admin/lockoutsRequires: manage:usersLists currently locked accounts with lockout reason, start time, and expiry.
Password Security
HaveIBeenPwned integration
When a user sets or changes a password, Auris checks it against the HaveIBeenPwned (HIBP) Pwned Passwords database using the k-Anonymity API. Only the first 5 characters of the SHA-1 hash are sent to HIBP — the plaintext password never leaves Auris.
If the password appears in known breach datasets, Auris rejects it and asks the user to choose a different password. This check applies to:
- User registration
- Password change requests
- Admin-created passwords via API
The HIBP check is enabled by default. To disable it (not recommended), set HIBP_CHECK_ENABLED=false in the environment. The check may add up to 200ms of latency on password operations due to the external API call.
Complexity requirements
Configure minimum password requirements in Console → Security → Password Policy:
| Requirement | Default |
|---|---|
| Minimum length | 8 characters |
| Require uppercase letter | No |
| Require lowercase letter | No |
| Require number | No |
| Require special character | No |
| Reject common passwords (HIBP) | Yes |
Requirements are enforced on Auris-managed passwords. SSO users authenticate via their corporate IdP and are not subject to Auris password policies.
Suspicious Login Detection
Auris analyzes each login for behavioral anomalies. Detection runs after successful Keycloak authentication — if the login credentials are correct but the context is suspicious, Auris can notify the user, block the login, or trigger MFA step-up.
Detection methods
1. New device
Auris computes a fingerprint hash from a combination of browser user agent, screen resolution, and other stable signals. If the fingerprint has not been seen for this user before, the login is flagged as “new device”. The device record is stored in DeviceFingerprint after the first successful login from that context.
2. New IP address
Auris tracks which IP addresses a user has previously logged in from. A login from an IP that has never been seen for this account is flagged.
3. New country
GeoIP lookup determines the country of the login IP. If the country differs from the user’s login history, the login is flagged. Country detection uses the built-in offline DB-IP City Lite database by default (no external network calls, EU-compliant). ip-api.com and MaxMind GeoIP2 are available as opt-in alternatives via the GEOIP_PROVIDER environment variable.
4. Impossible travel
Auris computes the geographic distance (Haversine formula) between the current login location and the most recent login location, then divides by the elapsed time to derive an implied travel speed. If the speed exceeds a configurable threshold (default: 800 km/h — faster than commercial aviation), the login is flagged as impossible travel.
5. VPN / proxy / datacenter detection
GeoIP lookup includes metadata indicating whether the IP belongs to a known VPN provider, proxy, or cloud datacenter. Logins from such IPs are flagged by default but can be allowed if your users commonly access the service via VPN.
Configured actions
Each detection method can trigger independent actions:
| Action | Behavior |
|---|---|
log | Record the suspicious login event to audit logs only. No user impact. |
notify | Send a notification email to the user informing them of the suspicious login. |
block | Reject the login entirely with an error message. |
require_mfa | Allow the login but require MFA completion even if MFA is not normally required. |
GeoIP provider configuration
| Provider | Setting | Notes |
|---|---|---|
| DB-IP City Lite | Default (built-in) | Offline local lookup, no external calls, EU-compliant, bundled with Auris |
| ip-api.com | GEOIP_PROVIDER=ip-api | External API call per login, free tier rate-limited |
| MaxMind GeoIP2 | GEOIP_PROVIDER=maxmind, MAXMIND_DB_PATH=/path/to/GeoLite2-City.mmdb | Local lookup, no external call, requires free MaxMind account for DB download |
Reviewing suspicious login events
/api/admin/suspicious-loginsRequires: manage:usersLists suspicious login events across all users, filterable by severity, reason, user, and date range.
/api/admin/suspicious-logins/[id]/reviewRequires: manage:usersMarks a suspicious login event as reviewed by an administrator.
CAPTCHA Integration
Auris supports three CAPTCHA providers on the login, signup, and password reset pages. CAPTCHA can be set to trigger always, only when risk is elevated, or only after a number of failed attempts.
Supported providers
| Provider | Type | Notes |
|---|---|---|
| Cloudflare Turnstile | Proof-of-work, privacy-preserving | Recommended. No image challenges. Free tier available. |
| hCaptcha | Image-based challenge | Privacy-focused alternative to reCAPTCHA |
| reCAPTCHA v3 | Score-based, invisible | No user interaction, returns a risk score |
Trigger modes
| Mode | Behavior |
|---|---|
ALWAYS | CAPTCHA appears on every login/signup attempt |
ON_SUSPICIOUS | CAPTCHA is triggered when the risk score (from adaptive MFA) exceeds the configured threshold |
AFTER_FAILURES | CAPTCHA appears after N consecutive failed login attempts from the same IP |
Configuration
Configure via Console → Security → CAPTCHA:
- Select the CAPTCHA provider.
- Enter the Site Key (used in the browser) and Secret Key (used server-side for verification).
- Set the trigger mode and (for
AFTER_FAILURES) the attempt threshold. - For reCAPTCHA v3, set the minimum score threshold (0.0–1.0) below which a login is blocked.
CAPTCHA verification is performed server-side on the Auris API before credentials are checked. Even if a client bypasses the CAPTCHA UI, the login will fail without a valid verification token.
IP Allow/Block Lists
Auris supports CIDR-based IP rules at the tenant level and per-application. Rules are evaluated before any authentication attempt.
Rule types
| Type | Behavior |
|---|---|
ALLOW | Explicitly permit traffic from this IP or range |
BLOCK | Reject all requests from this IP or range with HTTP 403 Forbidden |
Precedence: BLOCK rules always take precedence over ALLOW rules within the same scope.
Scope: Rules can be scoped to the entire tenant (scope: TENANT) or to a specific application (scope: APPLICATION, applicationId: ...).
Temporary rules: Set isTemporary: true and provide expiresAt to create rules that auto-expire. Useful for temporary bans after a detected attack.
Managing IP rules
/api/ip-rulesRequires: manage:usersList all IP rules for the tenant. Supports filtering by type (ALLOW/BLOCK), scope, and status.
/api/ip-rulesRequires: manage:usersCreate a new IP rule.
{
"cidr": "203.0.113.0/24",
"type": "BLOCK",
"scope": "TENANT",
"label": "Suspicious ASN",
"note": "Block following credential stuffing attack on 2025-06-01",
"isTemporary": true,
"expiresAt": "2025-07-01T00:00:00Z"
}/api/ip-rules/[id]Requires: manage:usersUpdate a rule — extend its expiry, change the label, or toggle active status.
/api/ip-rules/[id]Requires: manage:usersDelete an IP rule.
CIDR notation
Auris supports both IPv4 and IPv6 CIDR notation:
- Single IP:
203.0.113.42/32 - Subnet:
203.0.113.0/24(256 addresses) - Full range:
10.0.0.0/8(16.7 million addresses) - IPv6 single:
2001:db8::1/128 - IPv6 range:
2001:db8::/32
The Login Security Pipeline
Every login request passes through the following checks in order. Each check can short-circuit the pipeline by returning an error:
Incoming login request
|
v
1. IP Allow/Block Check
BLOCK rule matched? → HTTP 403, stop
ALLOW rule present? → continue
|
v
2. CAPTCHA Verification
Mode = ALWAYS? → require valid token
Mode = ON_SUSPICIOUS? → evaluate risk score, require if high
Mode = AFTER_FAILURES? → check IP failure count
Invalid/missing token? → HTTP 400, stop
|
v
3. Rate Limiting
Per-IP limit exceeded? → HTTP 429, stop
Per-user limit exceeded? → HTTP 429, stop
|
v
4. Brute-Force / Lockout Check
Account or IP currently locked? → HTTP 423, stop
|
v
5. Keycloak Authentication
Invalid credentials? → record failed attempt, HTTP 401, stop
Valid credentials? → continue
|
v
6. Suspicious Login Analysis
(non-blocking — runs async, records events)
High-severity detection? → trigger configured action (notify/block/require MFA)
|
v
7. Adaptive MFA Risk Scoring
Risk score computed from 5 factors
Score above threshold? → require MFA step-up
|
v
8. Token Issuance
ACR and AMR claims set based on completed auth methods
Access token and refresh token returnedSteps 1–4 are synchronous and blocking. Steps 6–7 may add latency if GeoIP lookups are enabled. The default DB-IP offline database adds minimal latency (sub-millisecond local lookup). Only switch to ip-api.com if you need real-time reputation signals and can tolerate the external network call per login.
Required Permissions
| Operation | Permission |
|---|---|
| View / manage IP rules | manage:users |
| View suspicious login events | manage:users |
| Review suspicious events | manage:users |
| View / manage lockouts | manage:users |
| Configure security settings (Console) | Tenant OWNER or ADMIN only |
Related Pages
- Multi-Factor Authentication — TOTP, SMS OTP, WebAuthn, and adaptive MFA
- Console: Security Settings — Full Console walkthrough for all security features
- Concepts: Login Flow — Detailed breakdown of the authentication pipeline
- API Reference: Security — Full endpoint documentation for IP rules, lockouts, and suspicious logins