Skip to content

GET /audit

Query audit entries

Requires the audit:read scope. Who sees what follows the audit trail's own rule rather than the ordinary role matrix: an OWNER, an ADMIN or an AUDITOR reads the whole trail of their own tenant, and everybody else reads their own events - transparency towards the employee rather than a lesser administrator's view. A request that names somebody else's actor_id without the right to the whole trail is refused, and the refusal is itself an entry. Filtering by period, action, actor, target, and outcome; cursor pagination.

A read that succeeds is not itself recorded. A trail that grew by being read would bury what it is for - the second page would contain the reading of the first - and reading is not among the events that must be recorded. What is recorded is the refusal, and the export.

Query parameters

NameTypeRequiredDescription
fromstring (date-time) optional
tostring (date-time) optional
actionstring optionalA prefix filter, e.g.
actor_idstring (uuid) optional
target_typestring optionalThe kind of object the entry is about, e.g.
target_idstring (uuid) optionalOne object's whole history, whatever was done to it
outcomestring
  • SUCCESS
  • DENIED
  • FAILED
optional
cursorstring optional
limitinteger
  • default: 50
  • maximum: 500
optional

Responses

  • 200 The matches
  • 403 An error per RFC 9457 Problem
Example bash
curl -X GET "$HUBTASK_URL/audit" \  -H "Authorization: Bearer $HUBTASK_TOKEN"

POST /audit:verify

Verify the integrity of the audit chain

Checks the hash chain and the absence of gaps over a period. Requires the audit:read scope and the right to the whole trail: a chain checked over one actor's entries would be a chain with every other entry missing, and would answer "broken" for a trail that is intact.

A clean check records nothing. A break is recorded as a critical entry of its own, because an auditor reading the trail months later has to be able to see that somebody noticed, and when.

Request body application/json

NameTypeRequiredDescription
fromstring (date-time) required
tostring (date-time) required
anchorsboolean
  • default: false
optionalAlso read the last anchor back from the workspace's anchoring target and compare the chain end it holds with the chain at that sequence.

Responses

  • 200 The verification result
  • 403 An error per RFC 9457 Problem
Example bash
curl -X POST "$HUBTASK_URL/audit:verify" \  -H "Authorization: Bearer $HUBTASK_TOKEN" \  -H "Content-Type: application/json" \  -d '{  "from": "2026-09-16T10:00:00Z",  "to": "2026-09-16T10:00:00Z",  "anchors": false}'

PUT /audit/anchoring

Name where the audit chain's end is anchored, or switch anchoring off

External anchoring: once a day a job reads this workspace's chain end - the last sequence number and its hash - and writes it as hubtask-anchor-<tenant>-<YYYYMMDD>.json to the backup target named here, recording the row audit_anchor with the target as its destination and the object's digest as its receipt. :verify with anchors: true reads the last copy back and compares it. A null target switches anchoring off; the anchors already written stay. Needs STRUCTURE at the workspace - a workspace administrator - and is audited with the target before and after. The target is one of the workspace's own backup targets, so what is recommended for a tenant's target (object lock, a retention no shorter than the audit period) applies to it; an anchor is a few hundred bytes, so the lock can be long.

Request body application/json — AuditAnchoringConfiguration

NameTypeRequiredDescription
target_idstring (uuid), or null requiredThe workspace's backup target the daily anchor is written to; null switches anchoring off.

Responses

Example bash
curl -X PUT "$HUBTASK_URL/audit/anchoring" \  -H "Authorization: Bearer $HUBTASK_TOKEN" \  -H "Content-Type: application/json" \  -d '{  "target_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c"}'

POST /audit:export

Export the audit trail over a period

Requires the audit:export scope and the right to the whole trail. The archive is written to a backup target - JSON Lines or CSV, with a checksum manifest and the period it covers - because an export over four hundred days is not something a request can hold; this answers a JobRef and the work happens in the background.

The export produces an audit entry of its own. A copy of the evidence leaving the installation is itself an event an auditor asks about, and it is the first audit.* action the system records about itself.

Request body application/json — AuditExport

NameTypeRequiredDescription
fromstring (date-time) required
tostring (date-time) required
formatAuditExportFormat
  • JSONL
  • CSV
optionalJSON Lines keeps the entry as it is - the nested actor, target, context and changes - and is what a second system reads.
target_idstring (uuid) requiredThe backup target the archive is written to.

Responses

Example bash
curl -X POST "$HUBTASK_URL/audit:export" \  -H "Authorization: Bearer $HUBTASK_TOKEN" \  -H "Content-Type: application/json" \  -d '{  "from": "2026-09-16T10:00:00Z",  "to": "2026-09-16T10:00:00Z",  "format": "JSONL",  "target_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c"}'