emailPassword plugin handles user registration, sign-in, email verification, and password management. Passwords are hashed with scrypt (N=16384, r=8, p=1) using Node’s built-in node:crypto module, no extra dependencies.
If you prefer username-based auth instead of email, see the username plugin.
Setup
Dev vs production config
1
Install the plugin
lib/kavach.ts
2
Mount the handler
The plugin registers endpoints automatically. You still need to route incoming requests to KavachOS from your framework adapter.- Next.js
- Express
- Hono
app/api/auth/[...kavach]/route.ts
Sign up
POST /auth/sign-up
Creates a new user account. Returns a session token on success. If requireVerification is true, the user also receives a verification email immediately.
Sign up (client)
string
required
User email address.
string
required
Password. Must meet the configured length and complexity rules.
string
Display name for the user.
201 Created
You can extend the user record with additional fields (e.g.
avatarUrl, role) by hooking into the onUserCreated lifecycle. The name field is the only optional built-in.Sign in
POST /auth/sign-in
Authenticates a user and returns a session token. Always returns a generic “Invalid email or password” message for wrong credentials. The response does not distinguish between a missing account and a wrong password.
Sign in (client)
string
required
User email address.
string
required
User password.
200 OK
Sign out
POST /auth/sign-out
Revokes the current session. The session cookie is cleared by the server.
Sign out (client)
Email verification
WhenrequireVerification: true, sign-in returns 401 with code EMAIL_NOT_VERIFIED until the user clicks the link sent at registration. The link hits your app’s callback URL, which should POST the token to /auth/verify-email.
Enable verification
lib/kavach.ts
Handle the callback
Your app receives the token in the URL. Send it to the endpoint:app/auth/verify-email/page.tsx (Next.js)
Resend verification
If the user lost the email, they can trigger a new one:Resend verification (client)
Email enumeration protection
WhenrequireVerification: true, the sign-up endpoint returns 201 even if the email is already registered. The existing user gets a “someone tried to create an account with your email” notification instead of an error being exposed to the attacker.
This prevents an attacker from harvesting valid email addresses by observing which registrations fail with 409 Conflict.
The password reset endpoint (/auth/request-reset) follows the same pattern. It always returns 200 regardless of whether the email exists.
See OWASP: Prevent Username Enumeration for background.
Password reset
1
Configure the reset email
lib/kavach.ts
2
3
Submit the new password
POST /auth/reset-passwordYour reset page receives the token from the URL. Collect the new password and post both:Reset password (client)
Change password
POST /auth/change-password
Requires an active session. The endpoint reads the user identity from the session, no userId in the request body.
Change password (client)
string
required
The user’s current password.
string
required
The new password. Must meet configured strength requirements.
Password configuration
Passwords are hashed with scrypt using Node’s built-innode:crypto module (N=16384, r=8, p=1, keylen=64 bytes). These parameters match OWASP interactive login recommendations and require no external dependencies.
Custom strength rules
lib/kavach.ts
Custom hash function
If you need a different algorithm, bring your own hash and verify functions. Edge runtimes (Cloudflare Workers, Deno Deploy, Vercel Edge): use PBKDF2 via the Web Crypto API, which is available everywhere:lib/kavach.ts
@node-rs/argon2 for stronger memory-hard hashing on full Node.js servers:
lib/kavach.ts
The default scrypt implementation is fine for most Node.js deployments. Use a custom hasher when you are migrating from an existing system, need edge runtime support, or want stronger memory-hard guarantees.
Configuration reference
string
required
Base URL for verification and reset links. Links are constructed as appUrl + /auth/verify-email?token=… and appUrl + /auth/reset-password?token=…
required
Called after sign-up with the recipient email, raw token, and fully constructed URL.
required
Called when a user requests a password reset. Same signature as sendVerificationEmail.
boolean
default:"true"
Block sign-in until the user clicks the email verification link.
number
default:"86400 (24h)"
Verification token lifetime in seconds.
number
default:"3600 (1h)"
Password reset token lifetime in seconds.