Consent Docs

Verify the audit log

Recompute the seal of every audit log entry and its link to the one before, to show that no entry was changed, removed or inserted.

How-to2 min readFor project administrators and deployment operators

Verify the log when an auditor, the Board or your own team needs to know that nobody changed it. The check recomputes each entry's seal and its link to the entry before.

How the log is sealed#

Each project's entries form one chain, numbered from 1. Each entry is sealed with a keyed hash, HMAC-SHA256, under the deployment's evidence chain key. The seal covers the entry, its number and the seal before it. The key is kept outside the database, so someone who can only write to the database cannot seal a changed entry again.

Entries written before the chain started carry no seal. The check counts them and says that they cannot be verified.

Run the check#

  1. Open Audit.
  2. Choose Verify the log.
  3. Keep The whole log ticked, or clear it and set First day (UTC) and Last day (UTC).
  4. Choose Verify.

The panel shows Verified with the number of entries checked, or each problem with its entry number.

Problem Meaning
Entry missing The entry with that number is gone.
Does not follow the entry before it Its link does not match the entry before it.
Changed after it was written Its seal no longer matches what it holds.
Sealed with a key this deployment does not hold A key was removed from EVIDENCE_CHAIN_KEYS. Ask the operator.

A range checks the entries written on those days, and their link to the entry before the first of them. The check is itself written to the audit log. Anyone whose role can read the audit log can run it.

Keep the last hash#

A chain cannot show entries removed from its end. The panel shows Last entry checked and its hash: keep a copy. A later check that ends on a lower number, or on another hash for that entry, means entries were removed. The copy of each entry on standard output is a second record.

The endpoint behind the button#

The console calls this endpoint with the signed-in session.

GET https://console.dpconsent.com/consent/api/v1/api/audit-log/customer-user/verify
    ?from=2026-10-10&to=2026-10-31

Send both days or neither. Each is a whole UTC day, and a range holds at most 366 days. Without them the whole chain is checked.

JSON
{
  "verified": false,
  "range": { "from": "2026-10-10", "to": "2026-10-31" },
  "checkedEntries": 1204,
  "firstSequence": 3811,
  "lastSequence": 5014,
  "headHash": "79806e0982c9b5c3fde20068da9bfcb5…",
  "chainStartedOn": "2026-10-09T06:00:00.112406Z",
  "unchainedEntries": 0,
  "problemCount": 1,
  "problems": [
    {
      "sequence": 4120,
      "id": "3f6c1d2e-8b0a-4c5e-9d71-2a4b6c8e0f13",
      "createdOn": "2026-10-14T09:12:40.381722Z",
      "problem": "HASH_MISMATCH"
    }
  ],
  "summary": "1 problem found in 1204 chained entries."
}

problem is MISSING_ENTRY, LINK_BROKEN, HASH_MISMATCH or UNKNOWN_KEY. At most 50 problems are listed; problemCount counts them all. A range that is not valid is refused with 400 and INVALID_DATE_RANGE or DATE_RANGE_TOO_LONG.

↑↓ to move, Enter to open