Sessions

sessionMiddleware is the built-in session layer - HMAC-SHA256-signed cookies, 144-bit ids, crypto.timingSafeEqual verification, secret rotation, and a pluggable SessionStore interface.

Usage

import { sessionMiddleware, type Session } from 'ingenium'

app.use(sessionMiddleware({
  secret: [process.env.SESSION_SECRET!, ...rotatedSecrets],
  cookieName: 'ingenium.sid',
  maxAgeSeconds: 7 * 86_400,
  rolling: false,
  cookie: { secure: true, sameSite: 'lax', httpOnly: true },
}))

declare module 'ingenium' {
  interface IngeniumContext { session: Session }
}

app.post('/login', async (ctx) => {
  const { user } = await ctx.body.json()
  await ctx.session.regenerate()       // new id, fresh against fixation
  ctx.session.set('userId', user.id)
  return { ok: true }
})

app.post('/logout', async (ctx) => {
  await ctx.session.destroy()
  return { ok: true }
})

What it provides

  • HMAC-SHA256-signed cookies.
  • 18-byte (144-bit) session ids.
  • crypto.timingSafeEqual verification.
  • Secret rotation - index 0 signs, all entries verify.
  • regenerate() for post-login session fixation defense.
  • Pluggable SessionStore interface (default SessionMemoryStore).

Multi-instance deploys

The default SessionMemoryStore does not share state across pods. For multi-instance production, a Redis-backed adapter is the next P0 - see the roadmap. Until then, sticky sessions at the load balancer are the operational workaround.

Where to next?