Sessions & refresh
KolayLogin ships a two-cookie session model. A short-lived JWT handles authorization; a long-lived rotating cookie refreshes it without exposing the user to replay or hijack.
Copy this quickstart guide as a prompt for LLMs to implement KolayLogin in your application.
Cookies
__client: HttpOnly, Secure (prod), SameSite=lax. Value isclientId.rotatingToken. Plan-aware max age: Hobby 7 days, Pro 30 days, Business / Enterprise 365 days. Rotated on every refresh. JS cannot read it.__session: JS-readable, Secure (prod), SameSite=None (prod) / lax (dev). 60-second RS256 JWT signed with the app's RSA keypair, verifiable via public/.well-known/jwks.json.
JWT claims
{
"sid": "session-uuid",
"sub": "user-uuid",
"env": "environment-uuid",
"org": "active-org-uuid",
"org_role": "admin",
"iss": "https://api.kolaylogin.com",
"iat": 1761940000,
"exp": 1761940060
}Refresh
When __session is near its exp, the client POSTs /v1/auth/sessions/refresh. The API reads__client, verifies the rotating token, writes a new one, and mints a fresh __session JWT. If the rotating token ever shows up twice (browser replay, stolen cookie), we revoke the whole client.
// The React provider does this automatically:
const res = await fetch(base + '/v1/auth/sessions/refresh', {
method: 'POST',
credentials: 'include',
});Sign out
POST /v1/auth/sign-out— end this browser. Clears cookies, marks the sessionended, rotates the stored token so the cookie (if stolen) is dead.POST /v1/auth/sign-out/all— end every session for the signed-in user. Use after a password reset or compromised-device alert.
Verifying a session on your own API
import { verifySessionJwt } from '@kolaylogin/backend';
app.use(async (req, res, next) => {
const jwt = getCookie(req, '__session');
if (!jwt) return res.status(401).end();
try {
req.auth = await verifySessionJwt(jwt, {
jwksUrl: "https://api.kolaylogin.com" + '/.well-known/jwks.json',
issuer: process.env.KL_JWT_ISSUER,
});
} catch {
return res.status(401).end();
}
next();
});Why 60 seconds for the JWT?
Short TTLs limit damage from cookie theft. The
__client cookie carries the long-lived trust; the JWT is a transient proof of that trust. If your API caches auth state on a gateway, stale-JWT latency is bounded to 60s — reverse proxies can keep their JWKS cache indefinitely.Plan caps
The __client cookie's max age is clamped by the workspace plan's maxSessionTtlSeconds. A dashboard admin cannot raise it above the plan limit.
- Hobby — 7 days
- Pro — 30 days
- Business / Enterprise — 365 days