Multi-tenant isolation
Running multiple organizations on one KavachOS instance with per-tenant settings.
What tenants are
A tenant represents an organization or workspace that shares one KavachOS deployment. Each tenant has its own agents, audit log, and policy settings. Data is isolated by tenantId: agents in one tenant cannot be seen or authorized against by another.
This is useful for SaaS products where each customer gets their own isolated agent environment without you running a separate database per customer.
tenantId is nullable everywhere it appears. Existing agents, policies, and audit entries created before you enable multi-tenancy continue to work without modification.
Data model
Prop
Type
TenantSettings
Prop
Type
Creating a tenant
Slugs must be unique and match ^[a-z0-9]+(?:-[a-z0-9]+)*$. KavachOS rejects duplicate slugs at creation time.
const tenant = await kavach.tenant.create({
name: 'Acme Corp',
slug: 'acme',
settings: {
maxAgents: 200,
auditRetentionDays: 365,
allowedAgentTypes: ['autonomous', 'service'],
},
});
console.log(tenant.id); // tnt_...
console.log(tenant.slug); // acmeCreating an agent inside a tenant
Pass tenantId when creating an agent. The agent is then scoped to that tenant.
const agent = await kavach.agent.create({
ownerId: 'user-456',
name: 'acme-data-bot',
type: 'autonomous',
tenantId: tenant.id,
permissions: [
{ resource: 'reports:*', actions: ['read', 'export'] },
],
});Authorization checks respect the tenant boundary: an agent in tnt_acme cannot be authorized against resources in tnt_other.
Listing agents by tenant
const agents = await kavach.agent.list({
tenantId: tenant.id,
status: 'active',
});Fetching and updating a tenant
// By ID
const t = await kavach.tenant.get('tnt_abc123');
// By slug (useful when the slug comes from a URL path)
const t2 = await kavach.tenant.getBySlug('acme');
// Update settings
const updated = await kavach.tenant.update(tenant.id, {
settings: {
maxAgents: 500,
auditRetentionDays: 730,
},
});Settings are merged, not replaced. Fields you omit in the update keep their existing values.
Listing all tenants
const tenants = await kavach.tenant.list();Useful for admin dashboards. Returns all tenants regardless of status.
Suspending and reactivating
When a tenant is suspended, all authorize() calls for agents in that tenant return allowed: false. Existing tokens are not revoked; they fail authorization until the tenant is reactivated.
// Suspend
await kavach.tenant.suspend(tenant.id);
// Reactivate
await kavach.tenant.activate(tenant.id);Budget policies per tenant
Attach a budget policy to a tenant to apply spending limits across all agents in it. See Budget policies for the full policy reference.
await kavach.policy.create({
tenantId: tenant.id,
limits: {
maxTokensCostPerMonth: 5000,
maxCallsPerMonth: 100_000,
},
action: 'block',
});