Checkpoint Docs
Server IntegrationsExpress

Express Observability & Storage

Session tracking and Redis event storage for the Express middleware

Overview

There is no separate "enhanced" Express middleware. The legacy createEnhancedAgentShieldMiddleware was removed from @kya-os/checkpoint-express in 1.3.0. Session tracking and event storage are now composable primitives you wire into the one middleware factory, withCheckpoint, through its onResult callback.

This page covers the Express-specific storage and session-tracking exports. For the full middleware reference (config options, response headers, response shape) covering Next.js, Express, and .NET, see Middleware Enforcement.

Setup

Record detection events from onResult. Construct a storage adapter with the async createStorageAdapter factory (Upstash Redis for production):

import express from 'express';
import { randomUUID } from 'node:crypto';
import { withCheckpoint, createStorageAdapter } from '@kya-os/checkpoint-express';

const app = express();
app.use(express.json());

const storage = await createStorageAdapter({
  type: 'redis',
  ttl: 86400, // 24 hours (default)
  redis: {
    url: process.env.REDIS_URL!,
    token: process.env.REDIS_TOKEN!,
  },
});

app.use(
  withCheckpoint({
    tenantHost: 'your.tenant.example',
    apiKey: process.env.CHECKPOINT_API_KEY,
    onResult: async (result, req) => {
      await storage.storeEvent({
        eventId: randomUUID(),
        sessionId: req.headers['x-request-id']?.toString() ?? randomUUID(),
        timestamp: new Date().toISOString(),
        agentType: result.detectionDetail.detectionClass.type,
        agentName: result.detectionDetail.detectedAgent?.name ?? 'unknown',
        confidence: result.detectionDetail.confidence,
        path: req.path,
        method: req.method,
        userAgent: req.headers['user-agent'],
        detectionReasons: result.detectionDetail.reasons,
        verificationMethod: result.detectionDetail.verificationMethod,
      });
    },
  })
);

app.listen(3000);

Errors thrown inside onResult are swallowed so an observability failure can't break the verdict path.

Storage Adapters

@kya-os/checkpoint-express exports MemoryStorageAdapter, RedisStorageAdapter, and the async createStorageAdapter factory.

Memory

For development and single-instance deployments. Data is lost on restart. This is the default — createStorageAdapter() with no argument (or { type: 'memory' }) returns a MemoryStorageAdapter.

import { createStorageAdapter } from '@kya-os/checkpoint-express';

const storage = await createStorageAdapter(); // in-memory

Redis

For production. Persists events and sessions across restarts and instances via Upstash Redis.

import { createStorageAdapter } from '@kya-os/checkpoint-express';

const storage = await createStorageAdapter({
  type: 'redis',
  ttl: 86400, // 24 hours (default)
  redis: {
    url: process.env.REDIS_URL!,
    token: process.env.REDIS_TOKEN!,
  },
});

Memory storage is not suitable for production — data is lost on restart and not shared across instances. Use Redis for production deployments.

Custom Adapter

Implement the StorageAdapter interface and pass it as { type: 'custom', custom: myAdapter }:

import type { StorageAdapter } from '@kya-os/checkpoint-express';

const myAdapter: StorageAdapter = {
  storeEvent: async (event) => {
    /* persist an AgentDetectionEvent */
  },
  storeSession: async (session) => {
    /* upsert an AgentSession */
  },
  getEvents: async (sessionId, limit) => {
    return [];
  },
  getSession: async (sessionId) => {
    return null;
  },
  getRecentEvents: async (limit) => {
    return [];
  },
  getActiveSessions: async (limit) => {
    return [];
  },
  cleanup: async (before) => {
    /* optional */
  },
};

Session Tracking

For cookie/header-based session continuity, wrap the middleware with withSessionTracking. When enabled, a returning agent's session is attached to req.agentShield on subsequent requests:

import { withCheckpoint, withSessionTracking } from '@kya-os/checkpoint-express';

const checkpoint = withCheckpoint({ tenantHost: 'your.tenant.example' });

app.use(withSessionTracking(checkpoint, { enabled: true }));

The package also exports the ExpressSessionTracker class directly if you need finer control over check / track.

req.agentShield is populated only when session tracking is wired via withSessionTracking. Plain withCheckpoint attaches nothing to req — read the verdict from the onResult callback.

Response Headers

The engine path sets X-Checkpoint-* headers and a __checkpoint_verdict cookie (byte-identical to the Next.js sibling package). In observe mode it adds X-Checkpoint-Would-Have-Been.

When session tracking is wired, ExpressSessionTracker additionally emits kya-session, kya-session-agent, and kya-session-id (and withSessionTracking sets kya-detected / kya-agent on a continued session).

Next Steps