DylogDocs

Sessions and cookies

How the session cookie is shared and how to check it from a browser app or its server.

PropertyValue
Name__Secure-dylog.session_token (dylog.session_token over plain http locally)
DomainCOOKIE_DOMAIN of the environment: .dyloginc.workers.dev today, .dylog.ai later
Lifetime7 days, extended once a day while in use
FlagsHttpOnly; Secure; SameSite=Lax

A second cookie caches the session payload for five minutes so most page loads never touch the database.

Because the cookie carries a shared domain, any Dylog app on the same site reads it automatically. When production moves to dylog.ai, apps on admin.dylog.ai and accounts.dylog.ai become same-site and everyone signs in once more.

Browser apps

Pin better-auth to the version accounts runs. Cookie names, the cache format and plugin endpoints are coupled to it.

import { createAuthClient } from "better-auth/react";
import { apiKeyClient, jwtClient, organizationClient } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_BETTER_AUTH_URL, // https://accounts.dylog.ai, inlined at build time
  fetchOptions: { credentials: "include" },
  plugins: [organizationClient(), apiKeyClient(), jwtClient()],
});

const { data } = authClient.useSession(); // { user, session } or null
const { data: orgs } = authClient.useListOrganizations();

Server-side checks

Two layers, cheapest first:

  1. Optimistic: getSessionCookie(request, { cookiePrefix: "dylog" }) from better-auth/cookies tells middleware whether a session cookie exists at all. Use it to redirect anonymous visitors without a network call. It does not prove validity.
  2. Authoritative: forward the incoming cookie header to GET https://accounts.dylog.ai/api/auth/get-session. A null body means signed out. On Cloudflare, bind the accounts Worker as a service binding so the call never leaves the platform.
const res = await fetch("https://accounts.dylog.ai/api/auth/get-session", {
  headers: { cookie: request.headers.get("cookie") ?? "" },
});
const session = await res.json(); // { user, session } | null

Bearer sessions for non-browser clients

Sign-in responses include a set-auth-token header. Clients that cannot store cookies (mobile, CLIs) keep that value and send Authorization: Bearer <token> to /api/auth/*. For calling backends, exchange it for a JWT instead of forwarding the session token.

Revocation

Users revoke individual devices from Account → Security. A password reset revokes every session. Staff can revoke all of a user's sessions or ban the user from the Better Auth Infra dashboard; banned users are rejected at sign-in with a message that points to support.

On this page