# Audit & Compliance Reporting

Cocoon's backend proxy maintains an immutable audit log of every RPC call, recording the caller identity, the method invoked, and the outcome. This log is the primary tool for compliance officers, auditors, and regulators reviewing chain activity.

## What Is Logged

Every JSON-RPC request that passes through the backend proxy (port 8546) is logged to a SQLite database (`audit.db`). Each log entry captures:

| Field              | Description                                                   |
| ------------------ | ------------------------------------------------------------- |
| `timestamp`        | ISO 8601 timestamp of the request                             |
| `user_id`          | UUID of the authenticated user (from session token)           |
| `ethereum_address` | Ethereum address of the caller                                |
| `role`             | Role of the caller at the time of the call                    |
| `method`           | JSON-RPC method name (e.g. `token_transfer`)                  |
| `params`           | Request parameters (redacted for sensitive fields)            |
| `status`           | `success`, `error`, or `blocked`                              |
| `error_code`       | JSON-RPC error code if the call failed                        |
| `chain_tx_hash`    | Transaction hash if the call produced an on-chain transaction |
| `ip_address`       | Client IP address                                             |

{% hint style="info" %}
Calls in `AUTH_MODE=advisory` where the caller has no valid session are still logged — they appear with `user_id: null` and role `unauthenticated`. This makes it possible to audit calls that bypassed authentication in development mode.
{% endhint %}

### What Is Redacted

To prevent the audit log from becoming a source of credential leakage, certain parameter fields are redacted:

* Private keys (any field named `key`, `privateKey`, `signingKey`)
* Passwords
* Raw UCAN delegation tokens (replaced with their CID)

Amounts, addresses, and method-specific data are never redacted — they are essential for compliance review.

## Accessing the Audit Log

### Via the Admin Dashboard

The audit log is accessible at **<http://localhost:3000/audit>** in the admin dashboard. It provides:

* A searchable, paginated table of all audit entries
* Filter by user, Ethereum address, method, status, and time range
* Inline drill-down to view full request parameters for any entry
* **CSV export** — export filtered results to a spreadsheet for external reporting

The dashboard audit view is role-gated: only users with the `Admin`, `Compliance`, or `Auditor` role can access it. Regulators access a separate, read-only view scoped to their jurisdiction.

### Via the REST API

The backend proxy exposes audit query endpoints directly:

#### `GET /api/audit`

Query the audit log. Supports filtering and pagination.

**Query parameters:**

| Parameter | Type     | Description                                                 |
| --------- | -------- | ----------------------------------------------------------- |
| `address` | string   | Filter by Ethereum address                                  |
| `user_id` | string   | Filter by user UUID                                         |
| `method`  | string   | Filter by RPC method (exact or prefix match, e.g. `token_`) |
| `status`  | string   | `success`, `error`, or `blocked`                            |
| `from`    | ISO 8601 | Start of time range                                         |
| `to`      | ISO 8601 | End of time range                                           |
| `offset`  | integer  | Pagination offset (default: 0)                              |
| `limit`   | integer  | Page size (default: 50, max: 500)                           |

**Example — all blocked transfers in the last 24 hours:**

```bash
curl "http://localhost:8546/api/audit?method=token_transfer&status=blocked&from=2026-04-12T00:00:00Z"
```

**Response:**

```json
{
  "entries": [
    {
      "id": 12345,
      "timestamp": "2026-04-12T14:32:01Z",
      "user_id": "a1b2c3...",
      "ethereum_address": "0x70997970...",
      "role": "Trader",
      "method": "token_transfer",
      "params": { "token": "0xMMFToken...", "to": "0x...", "amount": "2000000000000000000000000" },
      "status": "blocked",
      "error_code": -32001,
      "chain_tx_hash": null,
      "ip_address": "192.168.1.10"
    }
  ],
  "total": 3,
  "offset": 0,
  "limit": 50
}
```

#### `GET /api/audit/{id}`

Retrieve a single audit entry by ID.

#### `GET /api/audit/export`

Export audit entries as CSV. Accepts the same filter parameters as `GET /api/audit`. Returns a downloadable CSV file.

```bash
# Export all audit entries for a specific address
curl "http://localhost:8546/api/audit/export?address=0x70997970..." \
  -o audit_export.csv
```

## Audit Log Storage

The audit log is stored in `audit.db` (SQLite) at the path configured by `AUDIT_DB_PATH` (default: `./data/audit.db`).

{% hint style="warning" %}
The audit log is append-only in practice — entries are never deleted or modified by the system. In production, mount `AUDIT_DB_PATH` on a volume with restricted write access, and consider periodically archiving the database to long-term storage. A high-throughput system can accumulate several gigabytes of audit data per month.
{% endhint %}

For production deployments, back up `audit.db` regularly and retain it per your jurisdiction's data retention requirements. Many financial regulations require audit records to be preserved for 5–7 years.

## Compliance Reporting Workflows

### Regulatory Review (Regulator Role)

Users with the `Regulator` role have read-only access to:

* The audit log (filtered to their jurisdiction's assets)
* Selective disclosure endpoints for investor KYC documents they have been granted access to
* On-chain token compliance state (frozen wallets, compliance rule configurations)

Regulators cannot modify any state — their access is strictly observational.

### Compliance Officer Workflow

Users with the `Compliance` role can:

1. Query the audit log for suspicious patterns (e.g. repeated blocked transfers suggesting authorization issues)
2. Freeze or unfreeze investor wallets via `token_freeze`
3. View and update compliance rules (country allowlists, balance limits) on each token
4. Export audit data for external review

### Auditor Workflow

Users with the `Auditor` role have read-only access to the audit log and all transaction history. They cannot modify chain state or user records. Auditors typically:

1. Export audit data for a reporting period via `GET /api/audit/export`
2. Cross-reference on-chain transactions (visible via block explorer at port 3002) with the audit log
3. Verify compliance module configurations against the token contract state

## Permission-Blocked Request Tracking

When a request is blocked by the `PermissionRegistry` (e.g. a Trader attempts a $2M transfer exceeding their $1M limit), the entry is logged with:

```json
{
  "status": "blocked",
  "error_code": -32001,
  "method": "token_transfer",
  "params": {
    "token": "0x...",
    "to": "0x...",
    "amount": "2000000000000000000000000"
  }
}
```

This creates an automatic audit trail of every permission violation attempt — useful for identifying users who are consistently attempting operations beyond their authorization level.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cocoon.erigon.tech/operators/audit-and-compliance.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
