{
  "slug": "modules/audit",
  "title": "Audit module",
  "description": "Tamper-evident audit logging for every administrative action with before/after diffs.",
  "url": "https://cuitty.com/docs/modules/audit",
  "markdown_url": "https://cuitty.com/docs/modules/audit.md",
  "json_url": "https://cuitty.com/docs/modules/audit.json",
  "frontmatter": {
    "title": "Audit module",
    "description": "Tamper-evident audit logging for every administrative action with before/after diffs.",
    "order": 1,
    "section": "Modules",
    "updatedAt": "2026-04-27"
  },
  "headings": [
    {
      "depth": 1,
      "slug": "audit-module",
      "text": "Audit module"
    },
    {
      "depth": 2,
      "slug": "what-it-captures",
      "text": "What it captures"
    },
    {
      "depth": 2,
      "slug": "how-to-send-events",
      "text": "How to send events"
    },
    {
      "depth": 2,
      "slug": "hash-chain",
      "text": "Hash chain"
    },
    {
      "depth": 2,
      "slug": "reads",
      "text": "Reads"
    }
  ],
  "body_markdown": "# Audit module\n\nThe audit module records every administrative action with a hash-chained log entry — a single mutation cannot be silently rewritten without breaking the chain.\n\n## What it captures\n\n- Actor (user ID + email)\n- Action verb (e.g. `project.create`, `secret.rotate`)\n- Resource type and id\n- Before/after diff of the resource\n- HTTP method, path, status code, duration\n- IP and User-Agent\n- Optional metadata (auth method, scopes)\n\n## How to send events\n\nThe 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.\n\n## Hash chain\n\nEvery 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.\n\n## Reads\n\n| Endpoint                                 | Returns                                |\n| ---------------------------------------- | -------------------------------------- |\n| `GET /api/modules/audit/events`          | Paginated list of recent audit events  |\n| `GET /api/modules/audit/events/{id}`     | A single event with full payload       |\n| `GET /api/modules/audit/verify`          | Chain-integrity report                 |",
  "body_html": "<h1 id=\"audit-module\">Audit module</h1>\n<p>The audit module records every administrative action with a hash-chained log entry — a single mutation cannot be silently rewritten without breaking the chain.</p>\n<h2 id=\"what-it-captures\">What it captures</h2>\n<ul>\n<li>Actor (user ID + email)</li>\n<li>Action verb (e.g. <code>project.create</code>, <code>secret.rotate</code>)</li>\n<li>Resource type and id</li>\n<li>Before/after diff of the resource</li>\n<li>HTTP method, path, status code, duration</li>\n<li>IP and User-Agent</li>\n<li>Optional metadata (auth method, scopes)</li>\n</ul>\n<h2 id=\"how-to-send-events\">How to send events</h2>\n<p>The TypeScript audit plugin instruments your framework middleware automatically. From any other language, POST a <code>type: \"audit\"</code> event to <code>/api/ingest</code>. See <a href=\"/docs/reference/wire-protocol#audit\">Wire protocol</a> for the schema.</p>\n<h2 id=\"hash-chain\">Hash chain</h2>\n<p>Every audit entry stores <code>prev_hash = hash(prev_entry || row_payload)</code>. The portal exposes <code>cui admin verify-chain</code> to re-walk and verify the chain. Tampering with a row breaks every subsequent hash.</p>\n<h2 id=\"reads\">Reads</h2>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Endpoint</th><th>Returns</th></tr></thead><tbody><tr><td><code>GET /api/modules/audit/events</code></td><td>Paginated list of recent audit events</td></tr><tr><td><code>GET /api/modules/audit/events/{id}</code></td><td>A single event with full payload</td></tr><tr><td><code>GET /api/modules/audit/verify</code></td><td>Chain-integrity report</td></tr></tbody></table>",
  "links_out": [
    "/docs/reference/wire-protocol#audit"
  ]
}