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

# GDPR compliance

> Data export, account deletion, and audit log anonymization to meet GDPR requirements.

KavachOS includes built-in tools for the three GDPR obligations that most commonly require custom code: giving users their data, deleting their account on request, and anonymizing audit trails.

<Info>
  These tools cover the technical layer. Your privacy policy, data processing agreements, and response timelines are your responsibility.
</Info>

## Setup

```typescript title="lib/kavach.ts" theme={"system"}
import { createKavach } from 'kavachos';
import { gdpr } from 'kavachos/auth'; // [!code highlight]

const kavach = await createKavach({
  database: { provider: 'postgres', url: process.env.DATABASE_URL! },
  secret: process.env.KAVACH_SECRET!,
  baseUrl: 'https://auth.example.com',
  plugins: [
    gdpr({ // [!code highlight]
      requireDeletionConfirmation: true, // [!code highlight]
    }), // [!code highlight]
  ],
});
```

## Export user data

`POST /auth/gdpr/export`

Returns a JSON bundle of all data KavachOS holds for the authenticated user: profile, sessions, audit events, and any plugin-specific records.

```typescript title="Request export (client)" theme={"system"}
const res = await fetch('/auth/gdpr/export', {
  method: 'POST',
  credentials: 'include',
});

const { data } = await res.json();
// data.user, data.sessions, data.auditLog, data.agents, ...
```

The export runs synchronously for small datasets. For accounts with large audit logs, the response includes a `downloadUrl` that expires after 24 hours instead of embedding the full payload.

## Delete account

`POST /auth/gdpr/delete`

Permanently deletes the user account and all associated data. Sessions are revoked immediately. If `requireDeletionConfirmation` is `true`, the user must provide their password (or a confirmation token sent by email):

```typescript title="Delete account (client)" theme={"system"}
const res = await fetch('/auth/gdpr/delete', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    confirmation: 'DELETE', // literal string // [!code highlight]
    password: 'correct horse battery', // if requireDeletionConfirmation is true // [!code highlight]
  }),
});
```

<Warning>
  Deletion is irreversible. Any app data you store outside KavachOS that references the user ID will become orphaned. Use the `onBeforeDelete` hook to cascade deletes in your own tables first.
</Warning>

### onBeforeDelete hook

```typescript title="lib/kavach.ts" theme={"system"}
gdpr({
  onBeforeDelete: async (userId) => { // [!code highlight]
    await db.delete(posts).where(eq(posts.authorId, userId)); // [!code highlight]
    await db.delete(comments).where(eq(comments.userId, userId)); // [!code highlight]
  }, // [!code highlight]
}),
```

## Anonymize audit log

For cases where you need to retain audit records for compliance but cannot keep personal data, KavachOS can anonymize the audit log for a user without deleting it:

```typescript title="Anonymize audit log (server)" theme={"system"}
import { anonymizeAuditLog } from 'kavachos/modules/gdpr';

await anonymizeAuditLog(kavach, {
  userId: 'usr_abc123',
  replacement: '[deleted]', // replaces email, name, IP in log entries
});
```

The audit events remain in place with timestamps and action types intact. Personal identifiers are overwritten with the replacement string.

## Configuration reference

<ParamField path="requireDeletionConfirmation" type="boolean" default="true">Require the user's password before processing a deletion request.</ParamField>
<ParamField path="onBeforeDelete" type={`(userId: string) => Promise<void>`}>Async callback invoked before the user record is deleted. Use this to clean up app-level data.</ParamField>
<ParamField path="exportFormat" type="'json' | 'url'" default="'json'">Format for the data export response. 'json' returns inline data, 'url' returns a signed download URL.</ParamField>
