Defaults
| Attribute | Value |
|---|---|
| Name | kavach_session |
HttpOnly | true |
Secure | inferred from baseUrl scheme |
SameSite | Lax |
Path | / |
Domain | unset (host-only) |
Max-Age | 30 days, rolling |
Secure is true whenever your baseUrl starts with https://. For local http://localhost it is false so the cookie survives a dev session. This is the most common source of “cookie missing in production” bug reports, so Kavach flips it automatically.
Overriding
Cross-subdomain
Share sessions acrossapp.example.com and auth.example.com by setting a leading-dot domain.
A leading dot is the shape browsers accept even if the spec no longer requires it. It is still the interoperable choice across every browser that matters.
Cross-origin (different registrable domains)
If your auth server and your app live on different registrable domains (auth.example.com and app.example.org), cookies are not enough. Use the JWT session path instead. Cookies do not cross registrable domains under any SameSite mode that browsers accept in 2026.
Rolling vs absolute expiry
By default, the cookie’sMax-Age resets on every authenticated request. A user signed in thirty days ago but still active stays signed in. Flip to absolute expiry to force a re-auth on a schedule:
Reading the cookie yourself
Most code never needs to. Usekavach.auth.getSession({ request }) and let Kavach handle it. If you do want the raw string (for a custom route that bypasses the SDK), the cookie value is the opaque session token; hand it back to kavach.auth.verifySession(token) to get the user.
Troubleshooting
Cookie missing in production, present in dev
Cookie missing in production, present in dev
Cookie missing on a subdomain
Cookie missing on a subdomain
User signed out after every deploy
User signed out after every deploy
You are probably changing the
secret. The cookie value is signed with it; a new secret invalidates existing cookies. Keep secret stable across deploys, or pass an array (secret: [current, previous]) during a rotation window.SameSite=Lax rejected by a mobile webview
SameSite=Lax rejected by a mobile webview
Some older mobile webviews treat
Lax inconsistently across top-level POSTs. Drop to SameSite: 'none'; Secure: true and make sure you are on HTTPS.