# Audit Trail Integrity and Accepted Link Breaks
URL: https://docs.autociso.io/product/admin/audit-trail-integrity/
Description: How the Audit Trail proves nothing was changed, why some older tenants show an accepted link break, and what evidence to ask for as an auditor.

The Audit Trail is hash-chained. Every entry stores a fingerprint (a hash) of its own content and of the entry before it, so the entries form a chain. A verification run reports entries whose hashes do not match the chain.

## Actions are past-tense verbs

Every entry in the Audit Trail has one action, written as a past-tense verb such as Created, Updated, Removed or Accepted. The **Subject Type** column tells you which kind of record the action applied to, so "Updated" on a supplier template and "Updated" on an employee are told apart by the subject, not by a longer action name. All writers now record new entries this way.

The same verb is shown everywhere you read the trail: the **Action** column and filter on the [Audit Trail](https://docs.autociso.io/console/settings/audit-trail/) page, the CSV and PDF exports, the [Evidence Log](https://docs.autociso.io/console/ciso-reports/evidence-log/), the API and AI tools. Entries recorded before this change keep their original stored code (for example `supplier.template.updated`), and they are displayed under the verb too (Updated). An action without a translated label is shown as its verb.

- **Filtering finds old entries too.** Pick a verb in the **Action** filter, or send `filter[action][eq]=updated`, to get every entry with that action, including older entries stored under a longer code. An older code is still accepted as a filter value.
- **In the API,** the verb is returned in `action.code` (for example `"updated"`) on every read path and in the filter options. `action.group` is unchanged.
- **The raw export keeps the stored codes.** The full audit trail export (a `.jsonl.gz` file) is a forensic copy of what is stored, so it contains the original codes exactly as written. Use it when you need to re-check hashes yourself.
- **The hash chain is unaffected.** Stored entries are not rewritten, so the verification result stays the same.
- **AI payload logging is separate.** Changes to the `ai_payload_logging` setting are recorded in a separate system audit log, not in this Audit Trail, and are not covered by this change.

## What you see on the Audit Trail page

The [Audit Trail](https://docs.autociso.io/console/settings/audit-trail/) page is open to [Owners and Managers](https://docs.autociso.io/getting-started/roles-and-permissions/). Each row has a status icon next to its sequence number (Seq #):

| Icon | Status | Meaning |
|------|--------|---------|
| Green check | Verified | The entry and its link to the previous entry check out. |
| Yellow warning triangle | Unverified | The entry or its link does not check out and nobody has accepted it. |
| Blue info circle | Accepted | The link to the previous entry is broken, but the break is a known, approved historic one. |

Hover over the icon of an accepted row to see the tooltip **Link break accepted (&lt;reference&gt;)**, where the reference is the ticket or incident ID recorded when the break was approved. If the status cannot be determined, the tooltip reads "Verification status could not be determined" and a **Retry** option appears.

## Why an older chain can contain link breaks

Earlier versions of the audit writer could let two entries written at the same moment both claim the same entry as their predecessor. The chain then forked: the second entry's link points to an entry that is not the one directly before it. Nothing was lost or altered. The entries and their own hashes are intact; only the link between two neighbours disagrees.

The current writer no longer works this way, so new breaks of this kind cannot appear.

## What an accepted break means

An accepted break is a historic break that the platform's System Owners reviewed and approved through an audited administrator procedure.

- **It is recorded in the chain itself.** The approval is an entry in your Audit Trail (action `accepted`, subject type `audit_chain`), so it is covered by the same hash chain as everything else.
- **It is pinned to exact hashes.** The approval names the specific entry and the hashes involved. If either the entry or the approval is edited, the exception stops matching and the break is reported again.
- **It only applies below the boundary.** The boundary is the point at which the current writer took over. The verify result reports it as `effectiveBoundarySeq`.
- **No stored entry is rewritten.** Accepting a break adds an approval record. It never edits or re-links an existing entry.

## Breaks above the boundary can never be excused

At or above the boundary, no approval is accepted. A link break, hash mismatch, duplicate sequence number or unexplained gap there makes the verification result invalid, always. The same is true below the boundary for a content change (hash mismatch), a duplicate sequence number or an unreadable entry: only a plain historic link break can be accepted.

## What to ask for as evidence

Ask the tenant owner for:

1. **The verification result.** In the API this is `GET /api/v1/audit-trail/verify` (see [Audit Trail Verify API](https://docs.autociso.io/api/reference/audit-trail/verify/)). Check `valid`, `scanComplete`, `breakCount` and `acceptedBreaks`.
2. **The activation entry**, action `activated` on subject type `audit_chain`. It marks when the current writer started for the tenant and anchors the boundary.
3. **The acceptance entry**, action `accepted` on subject type `audit_chain`. It lists the approved breaks, the reference for each, and who approved them.

Both entries appear in the Audit Trail as "Chain protocol activated" and "Chain exception accepted". They are never archived or purged.

## Running the check with an API token

An [API token](https://docs.autociso.io/developers/api-tokens/) with the `audit_log:verify` scope can run the integrity check, for example from a nightly job that alerts you when the chain stops verifying. Only an Owner can create such a token, and it needs a plan that includes the Audit Trail. The call is `GET /api/v1/audit-trail/verify`; the fields and errors are on the [Verify the audit trail hash chain](https://docs.autociso.io/api/reference/audit-trail/verify/) page.

- **Results can be up to 60 seconds old.** For tokens the result is cached for 60 seconds per organisation. Read `verifiedAt` to see when the scan finished.
- **The token response is shorter.** It leaves out approver identities, hashes and the free-text reference of an accepted break. Ask your Owner for the acceptance entry (action `accepted`, subject type `audit_chain`) in the Audit Trail if you need those as evidence.
- **No query parameters.** The check takes none; a request that sends one is refused with `400 VALIDATION_FAILED`.
