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

# Compliance & Privacy

> Data privacy, compliance, and audit features in KaireonAI.

KaireonAI includes built-in compliance infrastructure for multi-tenant data isolation, immutable audit trails, data subject access requests (DSAR), PII masking, and configurable data retention. These features support GDPR, CCPA, and SOC 2 readiness out of the box.

## Tenant Isolation

Every API request is scoped to a single tenant. Cross-tenant data access is architecturally prevented at the query layer.

**How it works:**

* **Tenant resolution** -- Each request resolves a `tenantId` from either the JWT session (`user.tenantId`) or the `X-Tenant-Id` header (for API key auth). API key authentication binds the tenant to the key itself, ignoring any `X-Tenant-Id` header to prevent spoofing.
* **Database validation** -- The resolved tenant ID is validated against the `Tenant` table in the database. If the tenant does not exist, the request is rejected with `403 Forbidden`. The system fails closed: if the database is unreachable during validation, the request is denied.
* **Query enforcement** -- A tenant-filter helper injects `tenantId` into every database `where` clause. A scoped-query wrapper provides find / create / update / delete primitives that automatically include the tenant filter. Calling these helpers without a `tenantId` throws an error.
* **Single-tenant mode** -- For self-hosted deployments, set `SINGLE_TENANT_MODE=true` to bypass tenant resolution and use `tenantId: "default"` for all requests.

<Note>
  Every database query in every API route passes through tenant filtering. There is no "admin bypass" that returns data across tenants.
</Note>

## Audit Logging

All entity mutations (create, update, delete) are recorded in an immutable audit log with a cryptographic integrity chain.

### What Gets Logged

Every write operation on platform entities produces an audit record with the following fields:

| Field           | Description                                                                                            |
| --------------- | ------------------------------------------------------------------------------------------------------ |
| `action`        | The operation: `create`, `update`, `delete`, or domain-specific actions like `retention_config.upsert` |
| `entityType`    | The type of entity (e.g., **Offer**, **Decision Flow**, **Retention Config**, `dsar_request`)          |
| `entityId`      | The unique ID of the affected entity                                                                   |
| `entityName`    | A human-readable name for the entity                                                                   |
| `changes`       | A JSON object capturing the before/after or the input data                                             |
| `userId`        | The authenticated user who performed the action                                                        |
| `userName`      | Display name of the user (defaults to `"system"`)                                                      |
| `tenantId`      | The tenant scope                                                                                       |
| `requestId`     | Correlation ID for tracing across services                                                             |
| `timestamp`     | When the event occurred                                                                                |
| `integrityHash` | SHA-256 hash of the record contents plus the previous hash (see Verification below)                    |
| `prevHash`      | The integrity hash of the preceding audit record in the chain                                          |

### Immutability

Audit logs cannot be modified or deleted through the API. The audit log endpoint explicitly rejects DELETE, PUT, and PATCH requests with a `405 Method Not Allowed` response:

> "Audit logs are immutable and cannot be deleted."

### Resilience

The audit system uses a circuit breaker pattern. If the database becomes temporarily unavailable, audit events are buffered in memory (up to 500 events) and flushed when connectivity is restored. A per-tenant mutex prevents hash chain forks from concurrent writes.

### Querying Audit Logs

```bash theme={null}
GET /api/v1/audit-logs
```

**Headers:** `X-Tenant-Id` or session cookie. Requires `admin` role.

**Query parameters:**

| Parameter    | Default | Description                |
| ------------ | ------- | -------------------------- |
| `entityType` | --      | Filter by entity type      |
| `page`       | `1`     | Page number                |
| `limit`      | `50`    | Results per page (max 100) |

**Response:**

```json theme={null}
{
  "logs": [ ... ],
  "total": 1234,
  "page": 1,
  "limit": 50
}
```

## Audit Verification

Each audit log entry includes a SHA-256 integrity hash computed over its contents and the hash of the previous entry, forming a cryptographic chain. Tampering with any record breaks the chain from that point forward.

### How the Hash Chain Works

1. Each audit record's hash is computed as: `SHA-256(action + entityType + entityId + entityName + changes + userId + userName + tenantId + requestId + prevHash)`
2. The first record in the chain uses `"genesis"` as the previous hash.
3. Each subsequent record references the `integrityHash` of the record before it.

### Verification Endpoint

```bash theme={null}
GET /api/v1/audit-logs/verify
```

**Headers:** `X-Tenant-Id` or session cookie. Requires `admin` role.

**Query parameters:**

| Parameter | Default | Description                                                                       |
| --------- | ------- | --------------------------------------------------------------------------------- |
| `limit`   | --      | Only verify the last N entries (quick check mode). Omit to verify the full chain. |

**Response:**

```json theme={null}
{
  "intact": true,
  "verified": 847,
  "total": 847,
  "scanned": 847
}
```

If tampering is detected:

```json theme={null}
{
  "intact": false,
  "verified": 412,
  "total": 847,
  "scanned": 847,
  "brokenAtId": "clxyz...",
  "brokenReason": "hash_mismatch"
}
```

**Broken reasons:**

* `hash_mismatch` -- The recomputed hash does not match the stored `integrityHash`. The record's contents were modified after creation.
* `chain_link_mismatch` -- The record's `prevHash` does not match the `integrityHash` of the preceding record. A record was inserted or deleted in the middle of the chain.

## Audit Export

Bulk export of audit logs for regulatory reporting and SOC 2 evidence collection.

```bash theme={null}
GET /api/v1/audit-export
```

**Headers:** `X-Tenant-Id` or session cookie. Requires `admin` role. Rate limited to 10 requests per minute.

**Query parameters:**

| Parameter    | Default | Description                                     |
| ------------ | ------- | ----------------------------------------------- |
| `format`     | `json`  | Export format: `json`, `csv`, or `soc2`         |
| `startDate`  | --      | ISO date string for range start                 |
| `endDate`    | --      | ISO date string for range end                   |
| `entityType` | --      | Filter by entity type                           |
| `action`     | --      | Filter by action (`create`, `update`, `delete`) |
| `limit`      | `10000` | Max records (capped at 10,000)                  |
| `offset`     | `0`     | Pagination offset                               |

The `csv` format returns the export as a downloadable file with a `Content-Disposition` header.

You can also verify chain integrity through the export endpoint:

```bash theme={null}
POST /api/v1/audit-export
Content-Type: application/json

{
  "action": "verify_integrity",
  "startDate": "2026-01-01T00:00:00Z",
  "endDate": "2026-03-01T00:00:00Z"
}
```

## DSAR (Data Subject Access Requests)

The DSAR endpoint supports GDPR right-of-access and right-to-erasure requests. DSAR processing is asynchronous -- the API accepts the request immediately and processes it in the background via a job queue.

### Submitting a DSAR

```bash theme={null}
POST /api/v1/dsar
Content-Type: application/json

{
  "requestType": "export",
  "subjectId": "cust-12345",
  "subjectType": "customer_id"
}
```

**Headers:** `X-Tenant-Id` or session cookie. Requires `admin` role. Rate limited to 10 requests per minute.

**Parameters:**

| Field         | Required | Description                                      |
| ------------- | -------- | ------------------------------------------------ |
| `requestType` | Yes      | `"export"` (data access) or `"delete"` (erasure) |
| `subjectId`   | Yes      | The customer ID or email to look up              |
| `subjectType` | No       | `"customer_id"` (default) or `"email"`           |

**Response (202 Accepted):**

```json theme={null}
{
  "requestId": "dsar-abc123",
  "status": "queued"
}
```

The request is enqueued for asynchronous processing. The DSAR creation itself is audit-logged.

### Checking DSAR Status

```bash theme={null}
GET /api/v1/dsar?status=completed&limit=50
```

**Query parameters:**

| Parameter | Default | Description                                                     |
| --------- | ------- | --------------------------------------------------------------- |
| `status`  | --      | Filter by status: `queued`, `processing`, `completed`, `failed` |
| `limit`   | `50`    | Max results (capped at 200)                                     |

## PII Masking

Data pipelines include two built-in transforms for protecting sensitive data before it reaches analytics tables or export targets.

### Hash Transform

Replaces field values with a one-way cryptographic hash. Useful for pseudonymization where you need consistent identifiers without exposing the original value.

**Configuration:**

* **Fields to Hash** -- One or more source fields to hash
* **Algorithm** -- `SHA-256` (recommended), `SHA-512`, or legacy MD5

### Mask PII Transform

Applies pattern-based masking that preserves partial information for operational use while hiding sensitive details. Masking patterns are applied automatically based on detected data formats:

| Data Type | Before             | After              |
| --------- | ------------------ | ------------------ |
| SSN       | `123-45-6789`      | `***-**-6789`      |
| Email     | `user@example.com` | `u***@example.com` |
| Phone     | `(555) 123-4567`   | `(***) ***-4567`   |

**Configuration:**

* **Fields to Mask** -- One or more source fields to apply masking to

### When to Use

* **Before loading to analytics** -- Mask PII fields in your ETL pipeline before data lands in reporting tables
* **Before export** -- Hash or mask sensitive fields before sending data to external systems
* **Pseudonymization** -- Use the hash transform to create consistent non-reversible identifiers for analytics

Both transforms are available as pipeline nodes in the visual pipeline editor under the "Transform" category.

## Data Retention

Configurable retention policies control how long different classes of data are kept. Retention configs are per-tenant and per-data-class.

### Retention Config Endpoint

```bash theme={null}
GET /api/v1/admin/retention-configs
```

Returns all retention policies for the current tenant. Requires `admin` role.

### Creating or Updating a Retention Policy

```bash theme={null}
POST /api/v1/admin/retention-configs
Content-Type: application/json

{
  "dataClass": "interactions",
  "retentionDays": 365,
  "legalHold": false
}
```

**Parameters:**

| Field           | Required | Description                                                                                                                                                         |
| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dataClass`     | Yes      | One of: `interactions`, `decisions`, `metrics`, `audit`, `attachments`, `system_health`                                                                             |
| `retentionDays` | Yes      | Number of days to retain (1 to 36,500)                                                                                                                              |
| `legalHold`     | No       | When `true`, prevents automatic purging regardless of retention period. This is a boolean on the real data-class row — there is no separate `legal_hold` dataClass. |

**Data classes:**

| Class           | What It Covers                                                         | Swept by                                                  |
| --------------- | ---------------------------------------------------------------------- | --------------------------------------------------------- |
| `interactions`  | Customer interaction history and response records                      | `GET /api/v1/cron/cleanup`                                |
| `decisions`     | Decision trace records from the recommendation engine                  | `GET /api/v1/cron/cleanup`, `GET /api/v1/cron/dsar-purge` |
| `metrics`       | Behavioral metrics and pipeline execution metrics                      | `GET /api/v1/cron/cleanup`                                |
| `audit`         | Audit log entries (subject to legal hold considerations)               | `GET /api/v1/cron/cleanup`                                |
| `attachments`   | AI conversation file attachments (`AiAttachment` rows + storage blobs) | `GET /api/v1/cron/dsar-purge`                             |
| `system_health` | Non-pinned `SystemHealthAlert` rows                                    | `GET /api/v1/cron/system-health-purge`                    |

The Settings UI's **Legal Hold** switch (Settings > Retention) applies `legalHold: true`/`false` to every class above in one save — a single platform-wide hold for the tenant. Placing a hold on one class only is possible via a direct API call.

Retention policy changes are themselves audit-logged with action `retention_config.upsert` (or `retention_config.legal_hold` when a legal hold is applied).

## Encryption

### Data in Transit

All connections to the KaireonAI platform are over HTTPS. The playground deployment at `playground.kaireonai.com` enforces TLS.

### Data at Rest

* **Connector credentials** -- The `authConfig` field on connector records stores sensitive connection parameters (passwords, API keys, access tokens). These are stored as encrypted JSON in the database.
* **API keys** -- Platform API keys (`krn_` prefix) are validated against hashed values in the database.

### Session Security

Authentication uses JWT-based sessions via NextAuth. Session tokens are HTTP-only cookies with secure flags in production.

## India: DPDPA Compliance

KaireonAI supports compliance with India's **Digital Personal Data Protection Act, 2023** (DPDPA), which governs the processing of digital personal data of Indian residents. Penalties for non-compliance can reach up to INR 250 crore (\~\$30M).

### How KaireonAI Maps to DPDPA Requirements

| DPDPA Requirement                       | KaireonAI Feature                                                                                           | Status       |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------ |
| **Consent management** (Sec 6)          | Contact policies with opt-in/opt-out tracking per channel                                                   | Supported    |
| **Purpose limitation** (Sec 5)          | Decision flow audit trail records why each offer was shown                                                  | Supported    |
| **Data minimization** (Sec 4(2))        | PII masking + hash transforms in pipelines strip unnecessary data before analytics                          | Supported    |
| **Right to erasure** (Sec 12(3))        | GDPR erasure endpoint deletes all customer data across 8+ entity types                                      | Supported    |
| **Right to access** (Sec 11)            | DSAR export endpoint produces complete customer data package                                                | Supported    |
| **Data retention limits** (Sec 8(7))    | Configurable per-class retention policies with automatic purging                                            | Supported    |
| **Data breach notification** (Sec 8(6)) | Audit log integrity verification detects tampering                                                          | Supported    |
| **Grievance redressal** (Sec 8(10))     | DSAR status tracking + audit trail of all requests                                                          | Supported    |
| **Cross-border transfer** (Sec 16)      | Tenant isolation ensures data stays within tenant boundary; deploy in `ap-south-1` for India data residency | Configurable |
| **Children's data** (Sec 9)             | Decisioning gates can enforce age-gating on offers                                                          | Configurable |

### India Data Residency

For deployments requiring data to remain within India (RBI/SEBI regulated entities), deploy KaireonAI to AWS `ap-south-1` (Mumbai) region:

* **Database**: Use RDS PostgreSQL in `ap-south-1` with automated backups within the same region
* **Application**: Deploy via App Runner or ECS in `ap-south-1`
* **No cross-region replication**: Configure single-region to ensure no data leaves India

### TRAI DND Compliance

The **Telecom Regulatory Authority of India** maintains a Do Not Disturb (DND) registry. KaireonAI's suppression engine supports DND compliance:

* **Contact policies** can enforce channel-level suppressions (block SMS/calls to DND-registered numbers)
* **Outcome-based suppression** automatically stops contacting customers who repeatedly opt out
* **Cross-channel caps** prevent exceeding frequency limits across SMS, email, and push channels

### DPDPA Erasure Coverage

The GDPR erasure endpoint (`POST /api/v1/gdpr/erasure`) deletes the following customer data:

| Entity               | What's Deleted                                                   |
| -------------------- | ---------------------------------------------------------------- |
| `interactionHistory` | All impressions, clicks, conversions, dismissals                 |
| `interactionSummary` | Materialized interaction aggregates                              |
| `suppression`        | Active contact suppressions                                      |
| `decisionTrace`      | Decision pipeline execution records                              |
| `attributionResult`  | Revenue attribution records                                      |
| `variantAssignment`  | A/B test experiment assignments                                  |
| `identityLink`       | Cross-device/cross-channel identity links                        |
| `journeyEnrollment`  | Customer journey enrollment records                              |
| `channelDelivery`    | Outbound channel delivery/send records                           |
| `dsarExport`         | Stored DSAR export payloads (the subject's exported data bundle) |
| Dynamic schema rows  | Customer data in tenant-defined schema tables                    |

<Warning>
  Erasure is permanent and cannot be undone. The operation is audit-logged for compliance evidence. Use the DSAR export endpoint to provide the customer with their data before erasure.
</Warning>

## Related

<CardGroup cols={3}>
  <Card title="Authentication" icon="lock" href="/governance-security/authentication">
    User authentication, API keys, and session management
  </Card>

  <Card title="Audit Logs API" icon="list-check" href="/api-reference/audit-logs">
    Full API reference for audit log endpoints
  </Card>

  <Card title="Data Platform" icon="database" href="/data/overview">
    Connectors, schemas, and data pipelines
  </Card>
</CardGroup>
