Audit Logging

ProvenanceOne records every significant action in an immutable audit log. Each event carries a HMAC-SHA256 message authentication code (mac field) computed at write time, providing cryptographic tamper evidence. Events span 45+ types across 11 domains, are classified by risk level, and are retained for 7 years via a platform database TTL. The audit log cannot be cleared, truncated, or modified by any role or API key.


What customers need to know

  • Every audit event has a mac field: a HMAC-SHA256 digest over the canonical event body. Any post-write alteration to the event produces a MAC mismatch.
  • Events are retained for 7 years. Deletion before TTL expiry is not possible by any role.
  • 45+ event types cover runs, workflows, agents, secrets, connections, approvals, auth, bus messaging, DLP gateway, and workspace/member management.
  • Every event records actor kind (user, agent, system, integration), so you can attribute actions to human users, automated agents, or platform subsystems.
  • The PersonID field on events is erasable under GDPR on request. The event record itself is preserved.
  • Access to the audit log requires editor or admin role, or the audit:read API key scope. viewer role cannot read the audit log.

Tamper-evidence

Every audit event record contains a mac field. The MAC is computed server-side at write time as a HMAC-SHA256 digest over the canonical serialisation of the event body. It is stored alongside the event in platform database.

To verify an event has not been modified after creation:

  1. Retrieve the event: GET /audit/{eventId}
  2. Recompute the HMAC-SHA256 over the canonical event body using the same platform key management key
  3. Compare the computed value to the stored mac field

A mismatch indicates the record has been altered since it was written.

Needs product confirmation: Exact canonical serialisation format used for MAC computation; whether a verification utility or SDK method is provided; whether the platform key management key used for MAC is customer-managed (CMK) or platform-managed.

This control provides evidence of log integrity — it does not encrypt the event record. Event fields are readable by anyone with audit:read access.


Retention

Every audit event has a platform database TTL field set to 7 years (2,557 days) from the event's occurredAt timestamp. Records past TTL are automatically expired from platform database. There is no mechanism for early deletion by any role, API key, or admin action.

Note: platform database TTL deletion is asynchronous. Records past their TTL timestamp may persist for up to 48 hours before platform database processes the expiry. Expired records continue to be excluded from API query results during this window.

Needs product confirmation: Whether 7 years is a hard minimum floor for all workspaces, or whether the workspace dataRetentionDays setting can reduce audit retention below 7 years. The workspace retention field is confirmed to exist; whether it governs audit events is unconfirmed.


Risk classification

Each event is assigned one of four risk levels at write time. Risk level cannot be modified after creation.

Risk levelDescriptionExample events
lowRoutine operational eventsrun.started, workflow.draft_saved, connection.listed, agent.listed
mediumConfiguration changes, data access that is expected but should be trackedagent.updated, secret.rotated, member.invited, approval.granted
highSensitive operations with direct security or data implicationssecret.accessed, authz.denied, connection.accessed, auth.failed, approval.sla_breach
criticalHighest-impact operations with workspace-wide or compliance implicationsmember.erased, (gateway policy changes may emit at critical depending on configuration)

Use risk level filters in audit digest configuration and API queries to prioritise security-relevant events. A digest configured for high and critical only surfaces actionable security events without noise from routine operations.


Actor kinds

Every audit event records the kind of actor that caused it.

Actor kindDescription
userA human user authenticated via platform JWT
agentAn AI agent step executing within a workflow run
systemA platform subsystem (e.g. TTL expiry handler, scheduled task)
integrationAn API key-authenticated external integration

This field is essential for distinguishing human actions from agent actions in a mixed-actor environment. When investigating unexpected behaviour, filter by actorKind=agent to isolate agent-driven events.


Full event taxonomy

Events are grouped by domain. Risk level annotated where higher than low.

Run events (5)

EventRiskDescription
run.startedlowWorkflow run initiated
run.canceledmediumRun cancelled before completion
run.completedlowRun finished successfully
run.failedmediumRun terminated with error
run.deletedmediumRun record deleted

Workflow events (3)

EventRiskDescription
workflow.editedmediumWorkflow definition modified
workflow.publishedmediumWorkflow version published
workflow.draft_savedlowWorkflow draft saved

Agent events (5)

EventRiskDescription
agent.updatedmediumAgent configuration changed
agent.memory_setmediumAgent persistent memory key written
agent.memory_deletedmediumAgent persistent memory key deleted
agent.listedlowAgent list enumerated
agent.readlowAgent detail read

Approval events (6)

EventRiskDescription
approval.grantedmediumApproval step approved
approval.rejectedmediumApproval step rejected
approval.reassignedmediumApproval step reassigned
approval.sla_breachhighApproval SLA exceeded without action
grant.approvedmediumDelegated grant created
grant.deniedmediumDelegated grant refused

Secret events (5)

EventRiskDescription
secret.createdlowNew secret created
secret.updatedmediumSecret metadata updated
secret.rotatedmediumSecret value rotated
secret.accessedhighRaw secret value revealed via POST /secrets/{id}/reveal
secret.listedlowSecrets enumerated (SOC2 evidence)

Connection events (4)

EventRiskDescription
connection.updatedmediumConnection configuration changed
connection.accessedhighConnection credential used by execution engine or test endpoint
connection.listedlowConnections enumerated (SOC2 evidence)
connection.readlowConnection detail read

Workspace and member events (11)

EventRiskDescription
workspace.updatedmediumWorkspace settings changed
workspace.createdlowNew workspace created
workspace.environment_updatedmediumWorkspace environment configuration changed
workspace.notification_updatedlowNotification settings updated
member.invitedlowNew member invited
member.updatedmediumMember role or group changed
member.removedmediumMember removed from workspace
member.erasedcriticalGDPR erasure executed for a member
api_key.createdmediumAPI key issued
api_key.revokedmediumAPI key revoked
api_key.listedlowAPI keys enumerated (SOC2 evidence)

Auth events (4)

EventRiskDescription
user.loginlowSuccessful user login
user.workspace_switchedlowUser switched active workspace
auth.failedhighAuthentication failure (wrong credentials, expired token)
authz.deniedhighAPI call refused due to insufficient role or scope

Bus events (10)

EventRiskDescription
bus.message_publishedlowMessage published to the Bus
bus.message_deliveredlowMessage delivered to a subscriber
bus.message_fanoutlowMessage fanned out to multiple subscribers
bus.message_delivery_failedmediumMessage delivery failed
bus.cycle_blockedhighRouting loop detected and blocked
bus.subscription_createdlowNew Bus subscription created
bus.subscription_updatedlowBus subscription updated
bus.subscription_deletedmediumBus subscription deleted
bus.api_key_createdmediumBus-scoped API key created
bus.api_key_revokedmediumBus-scoped API key revoked

Gateway and DLP events (4)

EventRiskDescription
gateway_policy.createdmediumMCP Gateway policy created
gateway_policy.updatedmediumMCP Gateway policy updated
gateway_policy.deletedmediumMCP Gateway policy deleted
policy.violationmediumTool call blocked or redacted by gateway policy

Datastore events (4)

EventRiskDescription
datastore.createdlowNew datastore created
datastore.updatedmediumDatastore configuration updated
datastore.deletedmediumDatastore deleted
datastore.object_deletedmediumObject deleted from a datastore

How to investigate an agent action

The following is a step-by-step procedure for reconstructing what an agent did during a workflow run.

Step 1: Locate the run

Navigate to Runs in the workspace, or query:

GET /runs?workflowId={workflowId}&limit=20

Identify the runId of the run you want to investigate.

Step 2: Retrieve the run's audit trail

Query all audit events associated with the run:

curl "https://api.provenanceone.ai/audit?runId={runId}" \
  -H "x-api-key: YOUR_AUDIT_READ_KEY"

This returns all events with runId matching the run, in chronological order. Look for run.started, any run.failed or authz.denied events, and policy.violation events.

Step 3: Identify the agent steps

Filter the run's events to actorKind=agent:

GET /audit?runId={runId}&actorKind=agent

These events show what the agent initiated: tool calls, memory writes, connection accesses.

Step 4: Check tool calls

For each connection.accessed event in the run, the connectionRef field identifies which connection was used. For policy.violation events, the policyMatched field identifies which gateway policy triggered.

Step 5: Verify event integrity

For any event where integrity is material to the investigation, retrieve the event and verify its MAC:

  1. GET /audit/{eventId} — retrieve the event including the mac field
  2. Recompute the HMAC-SHA256 over the canonical event body using the platform key management key
  3. A match confirms the event has not been altered since it was written

Step 6: Cross-reference approval events

If the run included approval steps, query:

GET /audit?runId={runId}&eventType=approval.granted,approval.rejected

The actorId and actorName fields identify who approved or rejected each step.


Audit digest

The audit digest sends scheduled email summaries of audit events to configured recipients. It is available to admin role in Settings → Audit Digest.

FieldTypeDescription
enabledbooleanWhether the digest is active
frequencyenumdaily, weekly, or monthly
dayOfWeekinteger0 (Sunday) to 6 (Saturday) — weekly only
dayOfMonthinteger1 to 28 — monthly only
hourUTCintegerDelivery hour (0–23)
includeRiskLevelsarrayWhich risk levels to include
recipientsarrayEmail addresses to receive the digest

Digest emails are sent via the platform email service. For security monitoring, configure includeRiskLevels to ["high", "critical"] to receive only events warranting immediate review.


GDPR considerations

PersonID field

Every audit event includes a PersonID field that links the acting user to a data subject identity. Under a GDPR erasure request, POST /workspace/members/{userId}/erase (admin only) nulls the PersonID field across all historical audit events for that user.

The audit event record itself is not deleted. The event type, timestamps, actorId, resource references, and MAC field are all preserved. Only the PersonID identifier is replaced with a tombstone value.

This design maintains audit trail integrity (event records are not destroyed) while satisfying the right to erasure for the personal data field specifically.

The erasure itself produces a member.erased event at risk level critical, logged with the admin actor who initiated the erasure.

Data in event fields

Audit events may contain data from the operations they record (e.g. objectName, reason, extra fields). The scope of GDPR erasure is limited to the PersonID field. Whether additional personal data in event payload fields is in scope for erasure requires confirmation.

Needs product confirmation: Full scope of personal data erasure in audit events beyond the PersonID field; whether extra or other free-form fields may contain personal data that requires separate erasure procedures.


Querying the audit log

# All high and critical events in the last 7 days
curl "https://api.provenanceone.ai/audit?risk=high,critical&from=2026-04-24T00:00:00Z" \
  -H "x-api-key: YOUR_AUDIT_READ_KEY"

# All events for a specific run
curl "https://api.provenanceone.ai/audit?runId=run_abc123" \
  -H "x-api-key: YOUR_AUDIT_READ_KEY"

# All secret access events
curl "https://api.provenanceone.ai/audit?eventType=secret.accessed" \
  -H "x-api-key: YOUR_AUDIT_READ_KEY"

# All auth failures in the last 24 hours
curl "https://api.provenanceone.ai/audit?eventType=auth.failed&from=2026-05-07T00:00:00Z" \
  -H "x-api-key: YOUR_AUDIT_READ_KEY"

Available query parameters: eventType, actorId, actorKind, risk, from, to, workflowId, runId.


Admin controls

ControlLocationRole required
Read audit eventsAudit log page / GET /auditeditor, admin, or audit:read scope
Configure audit digestSettings → Audit Digestadmin
Verify event MACVia APIadmin or audit:read scope
Perform GDPR PersonID erasureSettings → Members → Eraseadmin

Security implications

  1. The audit log cannot be suppressed: there is no mechanism for any role or API key to prevent events from being written, or to delete existing events before TTL expiry. This includes the admin role.
  2. MAC verification is the primary integrity control: the mac field on each event enables post-hoc verification that individual records have not been altered. Without periodic MAC verification, tamper-evidence exists only as a theoretical check.
  3. Agent actions are attributed: actorKind=agent events identify the specific agent and run that caused an action. This is material for incident investigation in multi-agent deployments.
  4. GDPR erasure preserves event records: audit events survive erasure; only PersonID is nulled. This means the actions of erased users remain in the audit record — consider this when responding to data subject access requests.
  5. platform database TTL has up to 48-hour lag: do not rely on same-day deletion of expired records. The effective retention is 7 years plus up to 48 hours.

Limitations and open questions

  • No real-time streaming export: there is no confirmed webhook, Kinesis stream, or event bus integration for real-time audit event forwarding to a SIEM. Events must be pulled via GET /audit.
  • No bulk export endpoint: there is no one-click export of all audit events. Programmatic access via GET /audit with pagination is the confirmed retrieval mechanism.
  • platform database TTL delivery lag: as noted, expired records may persist up to 48 hours past their TTL timestamp.
  • MAC canonical format unconfirmed: the exact serialisation used for MAC computation is not publicly documented. Verification requires platform-provided tooling or documentation.
  • Audit retention floor: whether dataRetentionDays can reduce audit retention below 7 years is unconfirmed. The 7-year TTL is set on every event at write time; the interaction with workspace-level retention settings is unclear.
  • GDPR erasure scope in event payloads: erasure is confirmed for the PersonID field. Personal data in other event fields (e.g. objectName, extra) is not confirmed to be in scope.

FAQ

Can audit logs be deleted or modified?

No. Audit events cannot be deleted or modified by any role, API key, or admin action. The 7-year TTL is set at write time and cannot be shortened. Every event carries a HMAC-SHA256 MAC field that would produce a mismatch if the record were altered.

What does the MAC field prove?

The `mac` field is a HMAC-SHA256 digest computed over the canonical event body at the time the event is written. If the event is retrieved later and the MAC recomputed over the same body, a match proves the record has not changed since it was created. A mismatch indicates alteration. This is a tamper-evidence control — it does not encrypt the event.

How do I find all actions taken by a specific agent?

Query `GET /audit?actorKind=agent&actorId={agentId}`. This returns all events where the specified agent was the actor. To narrow to a specific run, add `&runId={runId}`. You can also filter by event type or risk level.

What is logged when a GDPR erasure is performed?

The `member.erased` event is logged at risk level `critical`. It records the admin actor who performed the erasure, the target user ID, and the timestamp. The PersonID field on the erased user's historical events is replaced with a tombstone. The audit event records themselves are not deleted.

Can I forward audit logs to my SIEM in real time?

There is no confirmed real-time streaming integration (webhook, Kinesis, or event bus) for the audit log. Events are retrievable via `GET /audit` with pagination and filter parameters. For scheduled summaries, the audit digest delivers email reports at configurable intervals. Contact the ProvenanceOne team to discuss SIEM integration requirements.

Which role can read the audit log?

`editor` and `admin` roles can read the audit log in the UI and via the API. `viewer` role cannot access the audit log. Programmatic access requires the `audit:read` API key scope, regardless of the role that issued the key.