@kiavi/kiavi-js
v0.2.0
Published
Server-side verification for APIs behind a Kiavi-hosted auth server. Use this to check that an incoming request is from a real, signed-in user.
Readme
@kiavi/kiavi-js
Server-side verification for APIs behind a Kiavi-hosted auth server. Use this to check that an incoming request is from a real, signed-in user.
Install
pnpm add @kiavi/kiavi-jsUsage
import { KiaviClient } from '@kiavi/kiavi-js'
const kiavi = new KiaviClient('https://auth.your-domain.com', 'my-api-audience')
// In your request handler:
const token = request.headers.get('authorization')?.replace(/^Bearer /i, '') ?? ''
const user = await kiavi.verifyToken(token)
if (!user) {
return new Response('Unauthorized', { status: 401 })
}
// user.sub, user.email, user.app_id, etc. are now trusted.That's it for the common case. Instantiate once, call verifyToken() on every request.
When to use verifyToken vs verifySession
verifyToken() is the default. It's offline (no network hop after the initial JWKS fetch),
checks signature / issuer / audience / expiration, and is what you want for essentially every
normal request.
What it doesn't know is anything that changed on the server after the token was issued:
a revoked session, a disabled user, a password reset. Those only become visible to
verifyToken when the current token expires and the client has to mint a new one — so the
staleness window is roughly "one access-token lifetime."
Kiavi currently issues access tokens with a 5-minute lifetime, so in practice the worst
case is that a revoked session stays usable for up to 5 minutes after revocation. If that's
acceptable for the operation you're protecting, stick with verifyToken(). If it isn't, use
verifySession() below.
verifySession() round-trips to the auth server on every call, so it always sees live state.
Reach for it when that staleness window is unacceptable for the operation at hand — e.g.
high-value money movement, permissions changes, anything where a just-revoked session
absolutely must not go through. The cost is an extra network hop per request and a hard
dependency on the auth server being reachable.
Rule of thumb: use verifyToken() everywhere; use verifySession() only on the handful of
endpoints where the trade-off is worth it, and cache its result for the duration of the
request if you call it more than once.
Options
new KiaviClient('https://auth.your-domain.com', 'my-api-audience', {
debug: true, // logs to console.debug; pass a function to route logs elsewhere
})Reference
Methods
verifyToken(token)— verifies a JWT from anAuthorization: Bearerheader. Returns the payload (sub,email,app_id, etc.) on success ornullon any failure. Never throws.verifySession(cookieHeader)— for routes that receive a session cookie directly instead of a bearer token. Forwards the cookie to the auth server and returns the resolved session, ornullif it's missing/invalid. Never throws. UnlikeverifyToken(), this makes a network round-trip on every call — cache the result per request if you use it.
Types
KiaviClient, JWTPayload, SessionPayload, KiaviClientOptions, KiaviTokenError,
KiaviDebugLogger.
How it works (if you're curious)
verifyToken() fetches the auth server's JWKS from ${authBaseUrl}/api/auth/jwks on first
use, then verifies tokens offline against the cached keys (rotation is handled automatically
by jose). It checks signature, iss, aud, and
expiration — so a bad token is a null return, not an exception to catch.
verifySession() exists for the less common case where your service sees the session cookie
directly (same-site rendered routes). It just forwards the cookie header to
${authBaseUrl}/api/auth/get-session and trusts the auth server's response.
The browser-side counterpart that obtains these tokens in the first place is
@kiavi/kiavi-browser.
