kavachOS
Authentication

Captcha

Protect sign-up and sign-in endpoints with Cloudflare Turnstile, hCaptcha, or reCAPTCHA.

The captcha plugin adds bot protection to any KavachOS endpoint. It validates a client-side token before the request is processed, blocking automated sign-ups and credential stuffing without extra middleware.

Supported providers

ProviderValue
Cloudflare Turnstile'turnstile'
hCaptcha'hcaptcha'
Google reCAPTCHA v2'recaptcha-v2'
Google reCAPTCHA v3'recaptcha-v3'

Setup

lib/kavach.ts
import { createKavach } from 'kavachos';
import { captcha } from 'kavachos/plugins/captcha'; 

const kavach = await createKavach({
  database: { provider: 'postgres', url: process.env.DATABASE_URL! },
  secret: process.env.KAVACH_SECRET!,
  baseUrl: 'https://auth.example.com',
  plugins: [
    captcha({ 
      provider: 'turnstile', 
      secretKey: process.env.TURNSTILE_SECRET_KEY!, 
      endpoints: ['/auth/sign-up', '/auth/sign-in'], 
    }), 
  ],
});

Client-side token

Add the provider's widget to your form. When the user completes the challenge, include the token in the request body as captchaToken.

Sign up with captcha token (client)
const res = await fetch('/auth/sign-up', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'user@example.com',
    password: 'correct horse battery',
    captchaToken: turnstile.getResponse(), 
  }),
});

The captchaToken field is stripped from the request before it reaches other plugins. Other plugin handlers never see it.

Error codes

CodeStatusMeaning
CAPTCHA_MISSING400Request did not include a token
CAPTCHA_INVALID403Provider rejected the token

reCAPTCHA v3 score threshold

For reCAPTCHA v3, set a minimum score (0.0–1.0). Requests below the threshold are rejected:

lib/kavach.ts
captcha({
  provider: 'recaptcha-v3',
  secretKey: process.env.RECAPTCHA_SECRET!,
  minScore: 0.5, 
  endpoints: ['/auth/sign-up'],
}),

Configuration reference

Prop

Type

On this page