Skip to main content

Cloudflare Turnstile

Airspace uses Cloudflare Turnstile to protect public-facing forms from bots and automated abuse. Turnstile provides CAPTCHA-like protection with minimal user friction — most visitors will never see a challenge.

Protected Forms

Turnstile is active on the following pages:

  • Login — prevents credential-stuffing attacks
  • Registration — prevents mass account creation
  • Onboarding (public tenant creation) — prevents automated tenant provisioning

Setup

1. Get Turnstile Keys

  1. Log in to your Cloudflare dashboard
  2. Navigate to Turnstile in the sidebar
  3. Click Add site
  4. Enter your site name and domain(s)
  5. Choose widget mode (Managed is recommended)
  6. Copy the Site Key and Secret Key

2. Configure Environment Variables

Add the following to your .env file:

TURNSTILE_SITE_KEY=your-site-key-here
TURNSTILE_SECRET_KEY=your-secret-key-here

Turnstile automatically activates when APP_ENV is staging or production. In local, testing, and any other environment it stays off by default, so developers don't need Cloudflare keys to work on login/registration/onboarding forms. Set TURNSTILE_ENABLED=true only if you want to force it on in a non-production environment (e.g., to verify the widget behavior locally).

3. Deploy

No additional steps are needed. The Turnstile widget will automatically appear on the protected forms.

Disabling Turnstile

To disable Turnstile (e.g., for development), set:

TURNSTILE_ENABLED=false

When disabled:

  • The widget does not render on any form
  • Server-side validation is skipped (always passes)
  • No requests are made to Cloudflare

Troubleshooting

SymptomCauseFix
Widget not appearingTURNSTILE_ENABLED is false or missing site keyCheck .env values
"CAPTCHA verification failed" errorToken expired or invalid secret keyVerify TURNSTILE_SECRET_KEY matches your Cloudflare dashboard
Forms work but no widgetJavaScript blockedEnsure challenges.cloudflare.com is not blocked by CSP or ad blockers
Verification fails after long page idleTurnstile tokens expire after ~5 minutesThe widget auto-refreshes; if issues persist, reload the page