---
title: Audit module
description: Tamper-evident audit logging for every administrative action with before/after diffs.
section: Modules
order: 1
updatedAt: 2026-04-27
slug: modules/audit
---
# Audit module

The audit module records every administrative action with a hash-chained log entry — a single mutation cannot be silently rewritten without breaking the chain.

## What it captures

- Actor (user ID + email)
- Action verb (e.g. `project.create`, `secret.rotate`)
- Resource type and id
- Before/after diff of the resource
- HTTP method, path, status code, duration
- IP and User-Agent
- Optional metadata (auth method, scopes)

## How to send events

The TypeScript audit plugin instruments your framework middleware automatically. From any other language, POST a `type: "audit"` event to `/api/ingest`. See [Wire protocol](/docs/reference/wire-protocol#audit) for the schema.

## Hash chain

Every audit entry stores `prev_hash = hash(prev_entry || row_payload)`. The portal exposes `cui admin verify-chain` to re-walk and verify the chain. Tampering with a row breaks every subsequent hash.

## Reads

| Endpoint                                 | Returns                                |
| ---------------------------------------- | -------------------------------------- |
| `GET /api/modules/audit/events`          | Paginated list of recent audit events  |
| `GET /api/modules/audit/events/{id}`     | A single event with full payload       |
| `GET /api/modules/audit/verify`          | Chain-integrity report                 |