> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kavachos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

<Info>
  `tenantId` is nullable everywhere it appears. Existing agents, policies, and audit entries created before you enable multi-tenancy continue to work without modification.
</Info>

## Data model

<ParamField path="id" type="string">Stable identifier with a tnt\_ prefix, e.g. tnt\_acme.</ParamField>
<ParamField path="name" type="string">Display name for the tenant.</ParamField>
<ParamField path="slug" type="string">URL-safe identifier. Lowercase letters, numbers, and hyphens only. Must be unique.</ParamField>
<ParamField path="settings" type="TenantSettings">Per-tenant configuration overrides.</ParamField>
<ParamField path="status" type="'active' | 'suspended'">Suspended tenants cannot authorize requests.</ParamField>
<ParamField path="createdAt" type="Date">When the tenant was created.</ParamField>
<ParamField path="updatedAt" type="Date">When the tenant was last modified.</ParamField>

### TenantSettings

<ParamField path="maxAgents" type="number" default="undefined (uses global limit)">Maximum active agents allowed in this tenant. Overrides the global default.</ParamField>
<ParamField path="maxDelegationDepth" type="number" default="undefined">How deep delegation chains can go. Defaults to the global setting.</ParamField>
<ParamField path="auditRetentionDays" type="number" default="undefined (no automatic pruning)">How long audit entries are kept for this tenant, in days.</ParamField>
<ParamField path="allowedAgentTypes" type="string[]" default="undefined (all types allowed)">Restrict which agent types can be created. E.g. \['autonomous'] to disallow delegated agents.</ParamField>

## Creating a tenant

Slugs must be unique and match `^[a-z0-9]+(?:-[a-z0-9]+)*$`. KavachOS rejects duplicate slugs at creation time.

```typescript theme={"system"}
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); // acme
```

## Creating an agent inside a tenant

Pass `tenantId` when creating an agent. The agent is then scoped to that tenant.

```typescript theme={"system"}
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

```typescript theme={"system"}
const agents = await kavach.agent.list({
  tenantId: tenant.id,
  status: 'active',
});
```

## Fetching and updating a tenant

```typescript theme={"system"}
// 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

```typescript theme={"system"}
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.

```typescript theme={"system"}
// 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](/guides/budget-policies) for the full policy reference.

```typescript theme={"system"}
await kavach.policy.create({
  tenantId: tenant.id,
  limits: {
    maxTokensCostPerMonth: 5000,
    maxCallsPerMonth: 100_000,
  },
  action: 'block',
});
```

## Next steps

<CardGroup cols={2}>
  <Card title="Budget policies" href="/budget-policies">
    Apply cost limits at the tenant, agent, or user level.
  </Card>

  <Card title="Agent identity" href="/agents">
    Create agents scoped to a tenant.
  </Card>

  <Card title="Audit log" href="/audit">
    Filter the audit trail by tenant.
  </Card>
</CardGroup>
