Captcha
captcha.turnstile() and captcha.recaptcha() protect public application
routes with managed CAPTCHA verification. Layeron keeps the user-facing API
route-shaped while compiling the security behavior into the normal platform
pipeline.
Use Captcha when a public route needs a human verification step before business logic runs. Common places include signup, contact forms, checkout steps, password reset, invitation acceptance, and other routes where a bot should be stopped at the Gateway boundary.
What Captcha Handles
Section titled “What Captcha Handles”Captcha can:
- Create and maintain Cloudflare Turnstile widgets during deploy.
- Adopt Google reCAPTCHA widgets with explicit sitekeys and Layeron secret references.
- Inject provider secrets into the Gateway Worker.
- Expose public sitekeys for client rendering.
- Verify tokens before route handlers run.
- Support manual verification for custom control flow.
- Adopt an existing Turnstile widget through an explicit sitekey and secret reference.
- Return stable failure responses.
- Keep widget resources, bindings, and secret usage visible in deployment state.
How It Fits
Section titled “How It Fits”Captcha is an ingress capability. The Gateway receives the request, extracts the provider token from the configured source, verifies it with the provider Siteverify API, and continues to the route handler only after verification succeeds.
route declaration -> captcha guard metadata -> provider widget or adopted sitekey -> Gateway Worker bindings -> Gateway runtime verification -> deployment stateManaged Captcha instances use Cloudflare Turnstile resources in the user’s Cloudflare account. Adopted instances, including Google reCAPTCHA, keep the existing widget and use a Layeron secret reference for the provider secret.
Automatic And Manual Verification
Section titled “Automatic And Manual Verification”Use automatic verification for routes where every request must pass Captcha before the handler runs:
app.post("/signup", { use: [signupCaptcha] }, async () => { return { ok: true }})Use manual verification when the handler owns the request flow, response shape, or token location:
app.use(signupCaptcha)
app.post("/api/signup", async (request) => { const body = await request.json() const result = await signupCaptcha.verifyToken(body.captchaToken, { request, hostname: "app.example.com", action: "signup", })
if (!result.ok) { return result.response() }
return { ok: true }})Both paths use the same Gateway-bound provider secret and provider Siteverify endpoint. Automatic verification returns the configured failure response immediately. Manual verification returns a structured result so the handler can choose the response.
Production Checklist
Section titled “Production Checklist”- Set
domainsfor every production widget so hostname validation uses an explicit allowlist. - Set
actionfor each user flow and keep it aligned with the clientdata-actionvalue. - Set
minScorefor reCAPTCHA v3 flows that should reject low-confidence traffic. - Use separate Captcha instances for flows with different risk or abuse profiles.
- Keep adopted provider secrets in Layeron secret references when adopting an existing widget.
- Return a stable JSON failure body through
failureso clients can handle verification errors consistently. - Restrict
dev: { mode: "bypass" }to local or test environments.
Next Steps
Section titled “Next Steps”- Get started: Choose a provider, protect a route, submit client tokens, and run manual verification.
- Cloudflare Turnstile: Create a managed widget, adopt an existing widget, and configure production behavior.
- Google reCAPTCHA: Verify reCAPTCHA tokens with a Layeron secret reference and score checks.
- API reference: Review provider options, token sources, failure behavior, and verification results.