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

# Audit Log

> Track every change and authentication event in your organization for compliance and security.

## Overview

The audit log records every mutation and authentication event in your organization — who did what, when, and what changed. This is essential for compliance, debugging, and security reviews.

<Info>
  The audit log is available on **Team** plans and above.
</Info>

## Viewing the Audit Log

### Via Dashboard

Navigate to **Settings > Audit Log** to see a filterable timeline of all activity. You can filter by:

* **Resource type**: Incidents, services, status pages, monitors, access tokens, SSO providers, and more
* **Actor type**: Users, API keys, or system actions
* **Date range**: Filter to a specific time period

Click any row with a chevron indicator to expand and see the field-level diff or event metadata. Authentication events (SSO logins, password attempts, token operations) include metadata such as the provider type, email, IP address, and failure reason.

### Via API

```bash theme={null}
curl "https://kodostatus.com/api/v1/audit-log?resource_type=incident&limit=20" \
  -H "X-API-Key: your_api_key"
```

Requires the `audit_log:read` scope.

#### Query Parameters

| Parameter       | Type     | Description                                                               |
| --------------- | -------- | ------------------------------------------------------------------------- |
| `resource_type` | string   | Filter by resource type (e.g., `incident`, `status_page`, `access_token`) |
| `resource_id`   | string   | Filter by specific resource ID                                            |
| `actor_type`    | string   | Filter by `user`, `api_key`, or `system`                                  |
| `action`        | string   | Filter by action (e.g., `sso.login_success`, `incident.created`)          |
| `from`          | ISO date | Start of date range                                                       |
| `to`            | ISO date | End of date range                                                         |
| `limit`         | integer  | Results per page (max 200, default 50)                                    |
| `offset`        | integer  | Pagination offset                                                         |

#### Response

```json theme={null}
{
  "entries": [
    {
      "id": "uuid",
      "actor_type": "user",
      "actor_id": "jane@company.com",
      "actor_label": null,
      "action": "sso.login_success",
      "resource_type": "status_page",
      "resource_id": "uuid",
      "changes": null,
      "metadata": {
        "provider": "okta",
        "email": "jane@company.com",
        "role": "full"
      },
      "created_at": "2026-02-22T10:30:00Z"
    }
  ],
  "total": 142,
  "limit": 50,
  "offset": 0
}
```

## Tracked Actions

### Resource Management

| Action                         | Description                       |
| ------------------------------ | --------------------------------- |
| `incident.created`             | Incident created                  |
| `incident.updated`             | Incident fields modified          |
| `incident.deleted`             | Incident deleted                  |
| `incident.published`           | Incident published to status page |
| `service.created`              | Service created                   |
| `service.updated`              | Service fields modified           |
| `service.deleted`              | Service deleted                   |
| `status_page.created`          | Status page created               |
| `status_page.updated`          | Status page modified              |
| `status_page.deleted`          | Status page deleted               |
| `status_page.design_published` | Design published                  |
| `monitor.created`              | Monitor created                   |
| `monitor.updated`              | Monitor modified                  |
| `monitor.deleted`              | Monitor deleted                   |
| `maintenance.created`          | Maintenance window created        |
| `maintenance.updated`          | Maintenance window modified       |
| `maintenance.deleted`          | Maintenance window deleted        |
| `notification_channel.created` | Notification channel created      |
| `notification_channel.updated` | Notification channel modified     |
| `notification_channel.deleted` | Notification channel deleted      |
| `webhook.created`              | Webhook created                   |
| `webhook.updated`              | Webhook modified                  |
| `webhook.deleted`              | Webhook deleted                   |
| `config.updated`               | Organization config modified      |
| `api_key.created`              | API key created                   |
| `api_key.updated`              | API key modified                  |
| `api_key.deleted`              | API key deleted                   |
| `workflow.triggered`           | Workflow manually triggered       |

### Authentication Events

These events are logged when users interact with protected status pages.

| Action                              | Description                | Metadata                                     |
| ----------------------------------- | -------------------------- | -------------------------------------------- |
| `sso.login_success`                 | User authenticated via SSO | `provider`, `email`, `role`                  |
| `sso.login_failed`                  | SSO authentication failed  | `reason`, `provider`, `email` (if available) |
| `status_page.password_auth_success` | Correct password entered   | `ip`                                         |
| `status_page.password_auth_failed`  | Wrong password entered     | `ip`                                         |
| `access_token.created`              | Access token created       | `name`, `access_role`, `status_page_id`      |
| `access_token.revoked`              | Access token revoked       | `status_page_id`                             |

<Tip>
  To monitor for suspicious activity, filter the audit log by `sso.login_failed` or `status_page.password_auth_failed` actions. Repeated failures from the same IP may indicate a brute-force attempt.
</Tip>

### SSO Failure Reasons

When an SSO login fails, the `reason` field in the metadata explains why:

| Reason                     | Description                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `jwks_verification_failed` | The ID token's signature could not be verified against the provider's JWKS endpoint. The token may have been tampered with. |
| `no_email`                 | The ID token and userinfo endpoint did not contain an email address.                                                        |
| `domain_not_allowed`       | The user's email domain is not in the allowed domains list for this status page.                                            |

## Change Tracking

For update operations, the audit log captures field-level diffs:

```json theme={null}
{
  "changes": {
    "status": { "old": "investigating", "new": "resolved" },
    "severity": { "old": "major", "new": "minor" }
  }
}
```

This makes it easy to see exactly what changed and who changed it.

For authentication events, the `metadata` field contains contextual information instead of a diff:

```json theme={null}
{
  "metadata": {
    "provider": "okta",
    "email": "jane@company.com",
    "role": "full"
  }
}
```

## Retention

Audit log entries are retained for:

| Plan           | Retention |
| -------------- | --------- |
| **Team**       | 90 days   |
| **Enterprise** | 1 year    |

## Streaming to a SIEM

For long-term retention, correlation, or compliance evidence, forward every audit event to your SIEM (Splunk HEC, Datadog Logs, Sumo, or any HMAC-verifying webhook collector).

Configure sinks under **Settings → Audit Log → SIEM delivery sinks**. Each sink delivers one POST per audit event, with exponential-backoff retries (up to 5 attempts over \~14 hours) before the event is marked dead.

### Payload

```json theme={null}
{
  "event": "audit_log.created",
  "organization_id": "uuid",
  "delivered_at": "2026-04-22T10:30:00Z",
  "audit_log": {
    "id": "uuid",
    "action": "sso.login_success",
    "actor_type": "user",
    "actor_id": "jane@company.com",
    "actor_label": null,
    "resource_type": "status_page",
    "resource_id": "uuid",
    "changes": null,
    "metadata": { "provider": "okta", "email": "jane@company.com", "role": "full" },
    "created_at": "2026-04-22T10:30:00Z"
  }
}
```

### Signing

If you set a signing secret on the sink, each request includes an `X-Kodo-Signature` header:

```
X-Kodo-Signature: sha256=<hex hmac of the raw request body>
```

Verify it on the receiving end:

```js theme={null}
const sig = req.headers['x-kodo-signature']; // "sha256=abc123..."
const expected = 'sha256=' + crypto
  .createHmac('sha256', process.env.KODO_SINK_SECRET)
  .update(rawBody)
  .digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
  return res.status(401).end();
}
```

Signing secrets are stored encrypted at rest (AES-256-GCM).

### Custom headers

Collectors that authenticate via headers (Splunk HEC's `Authorization: Splunk <token>`, Datadog's `DD-API-KEY`) can be configured via the **Custom headers** field when creating a sink. Values are sent on every delivery.
