Learn Keycloak - Brute Force Protection & Security
Episode 24 of 31

Learn Keycloak - Brute Force Protection & Security

Enabling Brute Force Detection at the realm, strengthening security headers, protecting sessions and tokens from hijacking, and establishing security auditing routines to keep Keycloak safe in production.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 23 you installed MFA at the authentication door: TOTP, WebAuthn, and recovery codes. Episode 24 completes the defense from a different side — protecting that door itself from brute force attacks, then strengthening the often-forgotten areas: security headers, sessions, tokens, and security audit routines. If episode 22 discussed what gets recorded in logs, this episode discusses how to prevent bad things from happening in the first place.

Brute Force Protection at the Realm

Brute force is an attack that guesses credentials by trying millions of password combinations. Keycloak provides a built-in mechanism called Brute Force Detection, enabled per realm via Realm Settings → Security Defenses → Brute Force Detection. Once enabled, Keycloak records every failed login attempt and holds back authentication once the count crosses the threshold.

How Failure Counting Works

Each failed login raises the counter for that user, and Keycloak also keeps a separate count by source IP. Two kinds of lockout result:

  • Temporary account lockout — occurs as soon as failureFactor is reached; the account is held for waitIncrementSeconds before the next attempt is allowed.
  • Permanent lockout — if failed attempts keep coming, the hold duration rises step by step until it hits maxFailureWaitSeconds, creating a practically permanent lockout effect.

Key settings you need to master:

SettingFunction
failureFactornumber of failed attempts before the account is temporarily held
waitIncrementSecondshold duration, increasing with each continued attempt
maxFailureWaitSecondsupper cap on the hold, creating a prolonged lockout effect
maxDeltaTimeSecondstime window during which failed attempts still count
quickLoginCheckMilliSecondsgap between attempts considered too fast
minimumQuickLoginWaitSecondsextra penalty for super-fast attempts

failureFactor is the most important threshold: with a value of 5, the account is held temporarily after five failed attempts. waitIncrementSeconds determines the hold duration, and its value rises with each continued failed attempt — until finally maxFailureWaitSeconds creates a prolonged lockout. This combination is what makes the attacker run out of time before managing to guess.

Tip

Start with moderate values: failureFactor 5, waitIncrementSeconds 60, and maxFailureWaitSeconds 900. Values that are too aggressive can lock out your real users when a script mistypes a password — and spawn unnecessary helpdesk tickets.

IP-Based Blocking

Keycloak counts failed attempts per user and per source IP. For the per-IP count to be accurate, Keycloak must recognize the client's real IP address. With a reverse proxy in front, what's visible is the proxy IP — unless the X-Forwarded-For header is used:

Recognizing the client IP behind a proxy
kc.sh start --proxy-headers xforwarded

kc.sh start --proxy-headers xforwarded makes Keycloak trust the headers forwarded by the proxy. Without it, attacks from many IPs are counted as if they came from the same single proxy IP, and per-IP lockout loses its meaning.

CAPTCHA Integration

For an extra layer, Keycloak has an Insert CAPTCHA step in the browser authentication flow. In the Authentication → Flows menu, copy the browser flow with the Copy button, give it a new name (for example browser captcha), then add the Insert CAPTCHA execution and place it right after the Password step. When a suspicious pattern is detected, humans can pass by typing the code, while bots will stumble.

Security Headers

Keycloak sends several security headers by default. You should still understand what they mean, because a reverse proxy in front can override or add to them:

HeaderFunction
Content-Security-Policylimits the resource sources the browser may load
X-Frame-Optionsprevents Keycloak pages from being framed by other sites (clickjacking)
X-Content-Type-Optionsprevents the browser from guessing content types (MIME sniffing)
Strict-Transport-Securityforces the browser to use HTTPS for this domain
X-XSS-Protectionlegacy defense against reflected XSS, now obsolete in modern browsers

If the default policy isn't strict enough, strengthen it at the proxy layer — an NGINX example:

LinuxAdding security headers in NGINX
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

An important note: X-XSS-Protection isn't a replacement for CSP. Focus your effort on a correct Content-Security-Policy, not a header many browsers already ignore.

Session Security

Sessions are the softest target: once a session is hijacked, the attacker becomes the user. Layered defense:

  • Session hijacking prevention — transport always HTTPS, cookies with the Secure attribute so they don't leak over HTTP, and SameSite to limit cross-site cookie sending.
  • Session fixation prevention — Keycloak replaces the session ID on successful login, so attackers can't force the victim to use a session ID they already know.
  • Secure cookies — make sure Keycloak cookies use HttpOnly, Secure, and SameSite appropriate to your architecture.
  • CSRF protection — the OIDC flow uses the state parameter to prove a request comes from the same application; never discard it.

Token Security

Tokens are identity in motion. Protect them in layers:

  • Signature verification — clients must verify the JWT signature using the public key from the JWKS endpoint. Never trust a token without verification.
  • Token encryption — for exchanges carrying sensitive data, use JWT signed plus encrypted so the payload can't be read by an intermediary.
  • Token binding — bind the token to connection characteristics, for example the client's TLS certificate, so the token can't be used from another connection.
  • Token revocation — use the revoke endpoint to cancel leaked refresh tokens, and rotate realm keys periodically via Realm Settings → Keys.

Security Auditing

All the controls above need routine maintenance, not a set-and-forget:

  • Regular security reviews — review realm, client, and token policy configuration periodically.
  • Penetration testing — test login flows, redirects, and admin endpoints from an attacker's perspective.
  • Vulnerability scanning — monitor CVE databases for Keycloak, the JDK, and the container images in use.
  • Security patching — always know the running version and design a fast upgrade path (covered in episode 29).

The admin events from episode 22 are the raw material for auditing: combine them with rejected login attempts to see attack patterns earlier.

Threat and Mitigation Summary

ThreatMitigation
Password brute forceBrute Force Detection with a reasonable failureFactor
Attacks from many IPsIP-based blocking based on X-Forwarded-For
Automated botsCAPTCHA on the browser flow
ClickjackingX-Frame-Options and a strict CSP
Hijacked sessionHttpOnly + Secure + SameSite cookies, HTTPS
Stolen tokenRevoke endpoint, key rotation, signature verification
Unpatched vulnerabilityRoutine auditing, patching, penetration test

Closing

Episode 24 taught you to close the gaps in the layer closest to the attacker: Brute Force Detection with failureFactor, waitIncrementSeconds, and maxFailureWaitSeconds; IP-based blocking that depends on X-Forwarded-For; CAPTCHA on the browser flow; security headers; session and token security; and auditing routines that keep everything fresh.

Key takeaways:

  • Brute force isn't a capacity problem but a time problem — the gradual hold with maxFailureWaitSeconds makes attacks uneconomical.
  • IP accuracy is the foundation — without --proxy-headers xforwarded, all per-IP protections go blind.
  • Layer sessions and tokens — secure cookies, signature verification, and a revoke endpoint are the mandatory minimum.
  • Security is a routine — patching and periodic audits matter as much as the initial configuration.

In the next episode (episode 25), you move from protecting the entrance to governing what users may do inside: fine-grained authorization with Keycloak's Authorization Services — deciding access per resource, not just per role.

Learn Keycloak - Brute Force Protection & Security | Learn SSO with Keycloak