Cloudflare Turnstile

Prev Next

Verify a Turnstile challenge token during a protected form submission, then use the result in your Darwinium decision. This is useful for login, account creation and other interactions where you want challenge verification alongside device, behavior and identity signals.

The Marketplace package provides the server-side verification call. Your page must already render the Turnstile widget and submit its token. The widget's public site key belongs in the browser; the secret key belongs in your secret store.

Prepare the login submission

Install Cloudflare Turnstile, import cloudflare_turnstile.snippet, and add cloudflare turnstile – verify token to the login submission step using Install an integration.

Suppose the login request sends JSON like this:

{"email":"alex@example.com","turnstile_token":"TOKEN_FROM_WIDGET"}

In that step's request-body mappings, map $.turnstile_token to:

custom.general_purpose['cf_turnstile_token']

For a form-encoded request, map the form field instead. Turnstile's default field is cf-turnstile-response; the source name can differ, but the destination above must match the snippet.

Configure verification

Open Workflows → Models on the submission step. Give the operation a recognizable name, such as verify_turnstile, and set Turnstile Secret Key to {{ secret(turnstile_secret) }} after mapping that name on the target.

Turnstile verification configured on a login step with a named secret reference.

Set the operation to depend on LOCAL.REQUEST so the token mapping is available. The supplied condition skips verification when the mapped token is null or empty. It sends the token and secret to Cloudflare's Siteverify endpoint; it does not send the login password.

Read the verification result

The snippet maps these fields under custom.general_purpose:

Attribute key Meaning
cf_turnstile_success Whether Siteverify accepted the token
cf_turnstile_hostname Hostname associated with the challenge
cf_turnstile_action Widget action, if supplied
cf_turnstile_challenge_ts Challenge timestamp
cf_turnstile_cdata Customer data supplied through the widget
cf_turnstile_interactive Interactive metadata, when returned
cf_turnstile_error_codes Verification error codes

An illustrative successful result is success: true, hostname: "login.example.com", action: "login". These are example values, not a captured provider response.

Use the result in a decision

Make the consuming rule depend on verify_turnstile. For a widget configured with the login action, an acceptance condition could be:

custom.general_purpose['cf_turnstile_success'] = true
AND custom.general_purpose['cf_turnstile_hostname'] = "login.example.com"
AND custom.general_purpose['cf_turnstile_action'] = "login"

Replace the expected hostname and action with your widget settings. Handle a missing token, failed verification and unavailable provider response explicitly in your decision strategy. A verified token is one input to that strategy; it does not by itself establish that a login is legitimate.

Verify the complete flow

Deploy to a test target, complete a fresh challenge and submit the form. In Investigations, inspect the verification fields and your decision. Repeat with a missing token and a reused token. Turnstile tokens expire after five minutes and are single-use; obtain a fresh token for a retry. See Cloudflare's server-side validation guide.

If the operation is skipped, check the token mapping and dependency. If verification returns an error, inspect cf_turnstile_error_codes and confirm the target resolves the secret for the same widget configuration.