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

# Lifecycle hooks

> Running custom logic before and after authorization, agent creation, and policy violations.

## What hooks are

Hooks are async callbacks you register at startup. KavachOS calls them at specific points in the authorization and agent lifecycle. They let you add custom logic without patching the SDK: log denials to Slack, block agents from running in unsandboxed environments, fire webhooks, or update your own database.

<Warning>
  Hooks are async. `beforeAuthorize` and `beforeAgentCreate` can block requests by returning `{ allow: false }`. All other hooks are fire-and-forget from KavachOS's perspective, but any unhandled exception in a hook will propagate to the caller.
</Warning>

## Available hooks

<ParamField path="beforeAuthorize" type={`(context: { agentId, action, resource, arguments? }) => Promise<{ allow: boolean; reason?: string } | void>`}>Fires before every `authorize()` call. Return `{ allow: false, reason }` to block. Return `void` or `{ allow: true }` to proceed.</ParamField>
<ParamField path="afterAuthorize" type={`(context: { agentId, action, resource, result }) => Promise<void>`}>Fires after authorize() completes with the final result. Useful for logging and alerting.</ParamField>
<ParamField path="beforeAgentCreate" type={`(input: CreateAgentInput) => Promise<{ allow: boolean; reason?: string } | void>`}>Fires before an agent is created. Return `{ allow: false }` to reject the creation.</ParamField>
<ParamField path="afterAgentCreate" type={`(agent: AgentIdentity) => Promise<void>`}>Fires after an agent is successfully created.</ParamField>
<ParamField path="onAgentRevoke" type={`(agentId: string) => Promise<void>`}>Fires when an agent is revoked.</ParamField>
<ParamField path="onViolation" type={`(violation: { type, agentId, action, resource, reason }) => Promise<void>`}>Fires when a permission denial, rate limit, or policy violation is detected.</ParamField>

### Violation types

The `onViolation` hook receives a typed `type` field so you can route each category to a different handler.

| Type                | When it fires                                     |
| ------------------- | ------------------------------------------------- |
| `permission_denied` | The agent lacks the required permission           |
| `rate_limited`      | The agent hit a rate limit                        |
| `ip_blocked`        | The request IP is on a blocklist                  |
| `time_restricted`   | The request is outside the allowed time window    |
| `approval_required` | The action needs human approval before proceeding |

## Registering hooks

Pass a `hooks` object to `createKavach`:

```typescript theme={"system"}
import { createKavach } from 'kavachos';

const kavach = await createKavach({
  database: { provider: 'sqlite', url: 'kavach.db' },
  hooks: {
    async beforeAuthorize({ agentId, action, resource }) {
      // Example: block calls outside business hours
      const hour = new Date().getUTCHours();
      if (hour < 8 || hour >= 20) {
        return {
          allow: false,
          reason: `Agent ${agentId} cannot run outside business hours (08:00–20:00 UTC)`,
        };
      }
      // Return nothing (or { allow: true }) to let the request proceed
    },

    async afterAuthorize({ agentId, action, resource, result }) {
      if (!result.allowed) {
        console.warn(`[kavach] Denied: agent=${agentId} action=${action} resource=${resource} reason=${result.reason}`);
      }
    },
  },
});
```

## Logging every denial

```typescript theme={"system"}
const kavach = await createKavach({
  database: { provider: 'sqlite', url: 'kavach.db' },
  hooks: {
    async afterAuthorize({ agentId, action, resource, result }) {
      if (!result.allowed) {
        await logger.warn('Authorization denied', {
          agentId,
          action,
          resource,
          reason: result.reason,
          auditId: result.auditId,
        });
      }
    },
  },
});
```

The `result.auditId` links this log line to the immutable audit entry. You can use it to correlate your own logs with the KavachOS audit trail.

## Enforcing a sandbox check

```typescript theme={"system"}
const kavach = await createKavach({
  database: { provider: 'sqlite', url: 'kavach.db' },
  hooks: {
    async beforeAgentCreate(input) {
      // Require sandbox metadata on all autonomous agents
      if (input.type === 'autonomous' && !input.metadata?.sandboxId) {
        return {
          allow: false,
          reason: 'Autonomous agents must declare a sandboxId in metadata',
        };
      }
    },
  },
});
```

Returning `{ allow: false }` from `beforeAgentCreate` causes the `kavach.agent.create()` call to throw a `KavachError` with the reason you provided.

## Reacting to violations

The `onViolation` hook fires for any denial that fits a known violation category. Use it to send alerts or update your observability platform.

```typescript theme={"system"}
const kavach = await createKavach({
  database: { provider: 'sqlite', url: 'kavach.db' },
  hooks: {
    async onViolation({ type, agentId, action, resource, reason }) {
      // Send to your alerting system
      await alerts.send({
        severity: type === 'rate_limited' ? 'warning' : 'error',
        title: `KavachOS violation: ${type}`,
        fields: { agentId, action, resource, reason },
      });

      // For repeat offenders, you could revoke here
      if (type === 'ip_blocked') {
        await kavach.agent.revoke(agentId);
      }
    },
  },
});
```

## Cleaning up after revocation

```typescript theme={"system"}
const kavach = await createKavach({
  database: { provider: 'sqlite', url: 'kavach.db' },
  hooks: {
    async onAgentRevoke(agentId) {
      // Remove the agent's discovery card
      await kavach.discovery.removeCard(agentId);

      // Notify your own systems
      await internalApi.notifyAgentRevoked(agentId);
    },
  },
});
```

## Next steps

<CardGroup cols={2}>
  <Card title="Budget policies" href="/budget-policies">
    Block agents when they exceed token or call limits.
  </Card>

  <Card title="Event streaming" href="/event-streaming">
    Stream authorization events to Kafka, NATS, or Webhooks.
  </Card>

  <Card title="Audit log" href="/audit">
    Query the immutable record of every authorization decision.
  </Card>
</CardGroup>
