Skip to main content
One-time tokens are short-lived, single-use strings for flows like email verification, password resets, and invitations. The raw token is handed to the caller once and never stored, only a SHA-256 hash lives in the database. On first use (or expiry), the token is gone.

Setup

The module is part of KavachOS core. No extra plugin needed.
lib/kavach.ts

Token purposes

Each token has a purpose that scopes its validity. Validation fails if the purpose at creation does not match the purpose at consumption.

Creating a token

createToken returns the raw token exactly once. Put it in a link or hand it to your mailer, there is no way to recover it from the database later.
The default TTL is 3600 seconds (1 hour). Override it per call with ttlSeconds, or set defaultTtlSeconds on the module config to change the default for all tokens.

Validating a token

Call validateToken when the user lands on your reset or verification page. On success, the token is consumed immediately, a second call with the same token always fails.
validateToken marks the token as used before it returns. Even if your handler crashes after this call, the token cannot be reused. Handle the downstream action (password update, email confirmation) in the same request.

Revoking tokens

Revoke all active tokens for an identifier when a user takes an action that makes them obsolete, for example, invalidating outstanding reset links when a user changes their password through a different flow.
Revocation is a soft operation, tokens are marked as used, not deleted. Expired tokens are excluded from the count.

Attaching metadata

Pass a metadata object to store arbitrary data alongside the token. It is returned on successful validation.

Error codes

Security notes

Tokens are hashed at rest. Only a SHA-256 hash is stored. A database dump does not expose usable tokens. Single-use enforcement is atomic. The mark-as-used update runs before the result is returned, with a conditional WHERE used = false. Concurrent requests for the same token will fail at the database level. Purpose binding prevents cross-flow reuse. A password-reset token cannot be submitted to an email-verify endpoint.
Last modified on April 18, 2026