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

# Audit log

> Every privileged write is logged with actor and action. Reads are not audited.

The audit log is a customer-visible append-only record of every privileged action on your workspace. It's the trust boundary on top of MCP keys and BYOK credentials: if something modified your blocks, decrypted your data-source credentials, or ran your scheduled agent, it left a row.

## What gets logged

Writes only. Reads are intentionally *not* audited — the read trust boundary is the MCP-key auth check, not per-row logging.

Logged actions include:

* **Connector credential decrypts** — every time a refresh, test-connection, or schema introspection decrypts a data-source credential, with the calling actor.
* **BYOK key decrypts** — each time the scheduled runner or schedule-preview pulls a plaintext Anthropic / OpenAI key out of envelope encryption.
* **MCP write tool calls** — `blocks.update`, `blocks.setWidgetData`, `blocks.publish`, `blocks.delete`, the placement writes, `dataSources.add` / `delete` / `editRefreshPolicy`, `schedule.set` / `pause` / `resume` / `delete` / `runNow`, `byokKeys.add` / `delete`.
* **Schedule previews** — the streaming `schedule.preview` MCP tool stamps an audit row with `targetId` set to the BYOK key id it used.
* **Member invites and role changes** — workspace admin actions on `workspaceMembers` and `workspaceInvites`.

Things that are deliberately *not* logged:

* MCP read tools (`blocks.list`, `canvases.get`, `auditLog.recent`, `workspace.get`, etc.).
* BYOK key list (`byokKeys.list`) — listing metadata doesn't decrypt anything.
* Web UI navigation and public canvas views.

## Row shape

Each row carries:

* `workspaceId` — the workspace the action targeted.
* `actor` — *who*, in a structured string:
  * `"user:<authUserId>"` — a human acting through the web UI.
  * `"mcp:<apiKeyId>"` — an MCP call authenticated by a `cb_live_*` key.
  * `"system:scheduledRunner"` — the Trigger.dev runner decrypting credentials for a scheduled agent run.
  * `"system:schedulePreview"` — the streaming preview tool's ephemeral decrypt path.
  * `"system:byok"` — generic BYOK substrate operations.
* `action` — *what*, as a dotted verb:
  * `"mcp.<toolName>"` for every MCP write (`mcp.blocks.publish`, `mcp.schedule.set`, etc.).
  * `"byok.decrypt"` for BYOK plaintext reads.
  * `"datasource.decrypt"` for connector credential reads.
  * `"member.invite"`, `"member.role"` for workspace membership changes.
* `targetId` — the resource id this action acted on (block id, schedule id, BYOK key id, data source id, etc.). Nullable for actions without a single target.
* `createdAt` — ISO timestamp.
* `metadata` — optional structured detail (e.g. the error message on a failed decrypt).

## How to query

<Tabs>
  <Tab title="MCP read tool">
    Any coding agent connected to the workspace can call:

    ```jsonc theme={null}
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "auditLog.recent",
        "arguments": { "limit": 50 }
      }
    }
    ```

    `limit` defaults to 50 and caps at 200. Returns rows newest-first. See the [MCP tool reference](/mcp/tool-reference) for the full schema.
  </Tab>

  <Tab title="CLI">
    Coming with B4 — `chatblocks audit recent --limit=50 [--json]` will wrap `auditLog.recent`. For now use the CLI's MCP proxy and call the tool directly, or hit the MCP endpoint from your script.
  </Tab>

  <Tab title="Web UI">
    A read-only dashboard surface under `/settings` is on the roadmap; v1.4 ships the data path (MCP read tool + Convex internalQuery) without the UI. Until that lands, use the MCP tool from your coding agent or via the CLI.
  </Tab>
</Tabs>

## Retention

Audit rows are retained indefinitely in v1. There's no automatic pruning. A future retention policy (e.g. 90 days on Free, 365 days on Builder, indefinite on Enterprise) is on the roadmap but not committed; if you need a guarantee, [email me](mailto:me@kevinfang.tech) or [DM me on X](https://x.com/sofangtastic).

<Tip>
  When you're debugging "why did this block change," start with `auditLog.recent` filtered to that block's id (client-side filter on the `targetId` field). The actor will tell you whether it was you in the web UI, an MCP key, or the scheduled runner — and the `action` tells you which tool ran.
</Tip>

## What's next

<CardGroup cols={2}>
  <Card title="MCP tool reference" icon="terminal" href="/mcp/tool-reference">
    The full schema for `auditLog.recent` and every other MCP tool.
  </Card>

  <Card title="BYOK keys" icon="key" href="/connecting-data/byok-keys">
    How BYOK envelope encryption works, what gets logged on decrypt, and how the runner uses them.
  </Card>
</CardGroup>
