kavachOS

Configuration

All createKavach() options explained.

createKavach() accepts a KavachConfig object. The only required field is database. Everything else is optional and enables features incrementally.

import { createKavach } from '@kavachos/core';

const kavach = await createKavach({
  database: { provider: 'sqlite', url: 'kavach.db' },
});

Top-level options

Prop

Type

Database config

Prop

Type

// SQLite
database: { provider: 'sqlite', url: './kavach.db' }

// Postgres
database: { provider: 'postgres', url: process.env.DATABASE_URL }

// MySQL
database: { provider: 'mysql', url: process.env.DATABASE_URL }

// In-memory SQLite (tests)
database: { provider: 'sqlite', url: ':memory:' }

Agent config

Controls the agent identity lifecycle.

Prop

Type

agents: {
  enabled: true,
  maxPerUser: 10,
  defaultPermissions: [],
  auditAll: true,
  tokenExpiry: '30d',
},

MCP config

Enables the OAuth 2.1 authorization server for MCP-compliant tool access.

Prop

Type

mcp: {
  enabled: true,
  issuer: 'https://auth.example.com',
  baseUrl: 'https://auth.example.com',
  accessTokenTtl: 3600,
  refreshTokenTtl: 604800,
  enforceAuth: true,
  loginPage: 'https://example.com/login',
  consentPage: 'https://example.com/consent',
},

Auth config

Connects KavachOS to your existing auth provider so it can resolve the human user behind incoming requests.

auth: {
  adapter: betterAuthAdapter(auth),   // resolves user from request
  session: {                          // optional: KavachOS-managed sessions
    secret: process.env.SESSION_SECRET,
    maxAge: 60 * 60 * 24 * 30,       // 30 days in seconds
  },
},

When auth is omitted, kavach.auth.resolveUser() always returns null (manual user management mode).

See Auth adapters for all adapter options.

Anomaly config

Prop

Type

anomaly: {
  highFrequencyThreshold: 200,
  highDenialRateThreshold: 30,
  expectedHours: { start: 8, end: 20 },
},

Environment variables pattern

Never hardcode secrets in config. Pass them through environment variables:

const kavach = await createKavach({
  database: {
    provider: 'postgres',
    url: process.env.DATABASE_URL!,
  },
  secret: process.env.KAVACH_SECRET!,
  mcp: {
    enabled: true,
    issuer: process.env.KAVACH_ISSUER!,
    signingSecret: process.env.KAVACH_SIGNING_SECRET,
  },
});

Dev vs production example

// config/kavach.ts
const isDev = process.env.NODE_ENV !== 'production';

export const kavach = await createKavach({
  database: isDev
    ? { provider: 'sqlite', url: './kavach-dev.db' }
    : { provider: 'postgres', url: process.env.DATABASE_URL! },

  secret: process.env.KAVACH_SECRET!,
  baseUrl: process.env.KAVACH_BASE_URL ?? 'http://localhost:3000',

  agents: {
    enabled: true,
    maxPerUser: isDev ? 100 : 25,
    auditAll: true,
    tokenExpiry: '30d',
  },

  mcp: {
    enabled: true,
    issuer: process.env.KAVACH_BASE_URL ?? 'http://localhost:3000',
    accessTokenTtl: isDev ? 86400 : 3600,
    enforceAuth: !isDev,
    loginPage: '/login',
    consentPage: '/consent',
  },

  anomaly: {
    highFrequencyThreshold: 500,
    highDenialRateThreshold: 50,
  },
});

secret and mcp.signingSecret must be at least 32 characters. In production, generate them with openssl rand -base64 32.

Next steps

On this page