kavachOS
Authentication

Phone number

Verify users by sending a one-time code to their phone number via SMS.

The phoneAuth plugin registers and authenticates users with a phone number and a one-time code. You supply the SMS delivery function — KavachOS handles code generation, expiry, and rate limiting.

Setup

lib/kavach.ts
import { createKavach } from 'kavachos';
import { phoneAuth } from 'kavachos/plugins/phone-auth'; 
import { Twilio } from 'twilio';

const twilio = new Twilio(process.env.TWILIO_SID!, process.env.TWILIO_TOKEN!);

const kavach = await createKavach({
  database: { provider: 'postgres', url: process.env.DATABASE_URL! },
  secret: process.env.KAVACH_SECRET!,
  baseUrl: 'https://auth.example.com',
  plugins: [
    phoneAuth({ 
      onSendCode: async (phone, code) => { 
        await twilio.messages.create({ 
          body: `Your verification code: ${code}`, 
          from: process.env.TWILIO_FROM!, 
          to: phone, 
        }); 
      }, 
      codeLength: 6, 
      codeExpiry: 300, // seconds
    }), 
  ],
});

Mount the handler the same way as any other plugin — see adapters.

Send code

POST /auth/phone/send-code

Sends a one-time code to the given phone number. Creates the user account on first send.

Send code (client)
const res = await fetch('/auth/phone/send-code', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    phone: '+14155550123', // E.164 format
  }),
});

// Always returns { success: true } to prevent phone enumeration

Phone numbers must be in E.164 format (+ prefix, country code, number).

Error codes

CodeStatusMeaning
PHONE_INVALID422Not a valid E.164 phone number
RATE_LIMITED429Too many codes sent to this number

Verify code

POST /auth/phone/verify-code

Submits the code the user received. Returns a session on success.

Verify code (client)
const res = await fetch('/auth/phone/verify-code', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    phone: '+14155550123', 
    code: '482910', 
  }),
});

if (res.ok) {
  const { user, session } = await res.json();
}

Error codes

CodeStatusMeaning
INVALID_CODE401Code is wrong or expired
CODE_EXPIRED401Code was valid but has passed its expiry window

Configuration reference

Prop

Type

On this page