Skip to main content

Bot protection with reCAPTCHA

Self-service flows are reachable without a session, which makes them the flows a bot reaches first. SecureAuth CIAM can put a Google reCAPTCHA check in front of them, so an automated client is stopped before it consumes an activation code or triggers a message send.

The check runs on every self-service flow a bot can reach without a session:

  • Activation links. The check happens before the activation code is consumed, so a link that fails it stays usable.
  • Credential reset, for passwords, TOTP, and passkeys.
  • Device pairing.
  • Self-registration.

How the check behaves

The gate uses reCAPTCHA v3 first. v3 is invisible: it scores the client in the background without asking the user to do anything. Most users never see a challenge.

What the check does depends only on which key pairs are configured:

  • Both v3 and v2. v3 runs first, invisibly. When a score falls below the threshold, or reCAPTCHA rejects the response outright (a reused or expired token), the user gets the v2 checkbox instead. A second invisible check would score the same client the same way, so the checkbox is the only thing that lets a real person through.
  • v2 only. The checkbox is shown directly, with no invisible pre-check.
  • v3 only. There is no checkbox to fall back to. A client whose score is too low is refused, because a second invisible check would reach the same verdict. A reused or expired token is different: the client was never the problem, so it gets a fresh invisible check.

Configure both pairs unless you have a reason not to: v3 alone turns a low score into a hard failure, and v2 alone shows every user a checkbox.

Configuration

The check is controlled entirely by the deployment captcha configuration. Two things must be true for it to run:

SettingWhereNotes
captcha.enabledPlatform configurationTurns reCAPTCHA on for the deployment.
At least one key pairPlatform configurationA v2 pair (site_key / secret_key), a v3 pair (site_key_v3 / secret_key_v3), or both.

There is no per-tenant feature flag: if captcha is enabled with a usable key pair, the check runs on every flow above. captcha.threshold is the minimum v3 score a client must reach, from 0.0 to 1.0, defaulting to 0.5. Raising it challenges more users with the checkbox; lowering it lets more automated traffic through. See the platform configuration reference.

If captcha.enabled is true but no usable key pair is configured, the check does not run and the flows continue unprotected. The activation flow logs a warning in that state; the other flows do not.

note

The activation_captcha tenant feature flag no longer has any effect. Earlier releases used it to gate the activation check; it is kept only so tenants and provisioning that still set it do not break. Enabling or disabling it changes nothing.

Exempting addresses from the check

captcha.whitelist takes a list of address suffixes that skip verification entirely, which is useful for automated testing against a deployment that has the gate on:

captcha:
whitelist:
- "@example.com"

On an activation link the suffix is matched against the address the code was issued to, not against anything the caller submits, so an exemption cannot be claimed for someone else's link.

Credential reset, device pairing, and self-registration have no such issued address to match against - the caller types the identifier - so there the suffix is matched against the submitted value, and anyone who submits a whitelisted address skips the check. Keep the whitelist empty on any deployment where those flows are reachable by the public.

Relationship to the other activation protections

An active captcha supersedes two older activation protections. When captcha is configured and running on the activation link:

  • two_step_activation, an interstitial page that auto-submits so an email scanner following a link with a GET request cannot activate the account, is replaced by the captcha interstitial, which gives the same protection.
  • activation_bot_protection, which rejects requests by User-Agent, is skipped. reCAPTCHA assesses the client directly, so User-Agent matching only adds false positives.

Leave both older flags set. They still apply on any deployment where captcha is not configured, and clearing them there would leave the activation link with no protection.