Skip to main content
Version: 1.0.8

Audit Journal

The audit journal is the append-only, tamper-evident record of security-relevant actions. It is the answer to "who changed that, and when".

Two design decisions​

It lives outside QUBIQ​

The journal is written to an external SQL database — PostgreSQL, MySQL or SQL Server — deliberately never the app's own database.

The reason is straightforward: a system that stores its own audit trail can rewrite its own history. Putting the journal in a database QUBIQ merely writes to, under separate administration, removes that possibility.

It is hash-chained​

Each record carries the hash of its predecessor. Altering or removing any row breaks every subsequent link, so tampering is detectable even by someone with write access to the database.

The chain starts from a genesis anchor, so a fresh journal begins cleanly and its integrity can be verified from the first record onward.

Configuration​

ActionWherePermission
Configure the storage connectionSettings → Audit LogManage Audit
Read the journalSettings → Audit Log → Open Audit LogView Audit Log
Verify the chainVerify integrity, in the Audit LogView Audit Log

Manage Audit is super-admin only by default; View Audit Log is available to admins. Being able to read the journal and being able to reconfigure where it goes are deliberately different levels of trust.

Set this up before go-live. Until a storage connection is configured, the interface shows a "configure audit storage" hint rather than an error — events are buffered, but you are not yet retaining them anywhere durable.

Reading the journal Changed in 1.0.7​

The Audit Log lists the newest events first. Narrow it with the search box (actor, entity, outcome), Origin and Category; choose 50, 100, 250 or 500 rows per page, and page with the arrows — the double arrow jumps back to the newest events.

Filters search the whole journal. Before 1.0.7 they were applied only to the page already loaded, so narrowing by origin, category or text looked inside the current hundred rows and a record two pages back simply was not found — a dangerous answer from the one place people go to establish what happened. The narrowing is now done by the audit service, across everything stored.

The pager also says where you are. The footer shows the row range (rows 101–200) and end of journal when there is nothing older, so a greyed Next reads as the end rather than as a broken button. Changing page or filter returns the list to its first row, and a page that fails to load says so with Try again, instead of leaving the previous page on screen while the counter moved on.

Durability​

Events are published to a durable stream the instant they are emitted, before any database write is attempted. The audit service drains that stream into the external store.

ConditionBehaviour
Storage unavailableEvents stay buffered on the stream; retried
Duplicate deliveryRecognised by event ID and treated as success — the journal is idempotent
Malformed eventDropped as permanently bad, rather than wedging the stream

The consequence: a database outage delays the journal, it does not lose it.

Watch the buffer. New in 1.0.8 That stream is a store-and-forward buffer in all but name, and the one an auditor most needs to see backing up. It appears in Settings → Store & Forward as Audit Journal, with the same fill, age, drain rate and time-to-full readout as the other buffers, and raises the same pressure and full alarms. Unlike them it can never be paused or purged — purging it would destroy audit records, so the actions are refused on the server, not merely hidden. → Store & Forward

What is recorded​

CategoryExamples
AuthenticationLogin success and failure, logout, lockout
User administrationCreate, edit, role change, activate, deactivate, delete
Permission changesRole-to-permission matrix edits
Connection changesCreate, edit, delete, credential changes
Namespace changesTag and binding changes
Alarm operationsAcknowledge, shelve, suppress, restore
ConfigurationSystem settings, audit settings, historian designation
BackupExport and restore
Privileged operationsHistorian ownership claims, service control
AI actionsAssistant proposals, approvals and rejections

Each record carries the actor, the action, the target, the timestamp, the client IP and enough before/after detail to reconstruct the change.

Behind a proxy, set TRUSTED_PROXIES

Otherwise every record shows the proxy's address instead of the operator's.

Verifying integrity​

Verify integrity in the Audit Log (needs View Audit Log) walks the chain and reports any break — or Chain intact with the number of rows checked. Run it:

  • On a schedule, as a control
  • Before relying on the journal in an investigation
  • After any database maintenance that touched the audit tables

A break tells you the record set has been altered since it was written. It does not tell you by whom — that is what your database's own controls are for.

Attribution and AI​

Actions originating from the AI assistant are recorded with both identities: the assistant as the origin, and the human whose proposal it acted on as the actor. An AI-initiated change is never anonymous.

→ AI assistant

Compliance alignment​

The journal is designed against IEC 62443-3-3:

RequirementHow it is met
SR 2.8 — auditable events and record fieldsCategories above, with actor, target, timestamp, source
SR 2.10 — no loss of audit dataDurable stream buffering before storage
SR 2.11 — authoritative timestampsServer-assigned, not client-supplied
SR 2.12 — non-repudiationPer-actor attribution plus the hash chain

Sector regulations (FDA 21 CFR Part 11, GxP, and similar) generally require the same properties: attributable, contemporaneous, and protected from alteration.

Operating the journal​

Choose the storage database deliberately. Ideally on a different host, under different administration from QUBIQ. That separation is the control.

Retain according to your policy, not by default. Industrial audit retention is often measured in years; the journal grows steadily and predictably.

Back it up separately. It is not part of a QUBIQ configuration backup — deliberately, so that restoring a configuration cannot overwrite the audit history.

Read it periodically. A journal nobody looks at until an incident is a journal whose gaps you discover at the worst moment.

Journal versus execution logs​

Audit journalExecution / system logs
RecordsSecurity-relevant actionsPipeline runs, diagnostics
StorageExternal SQLInternal
Tamper-evidentYesNo
Clearable from the interfaceNoYes, with Clear Execution Logs / Clear System Logs
PurposeAccountabilityTroubleshooting

That execution logs can be cleared and the audit journal cannot is the distinction. Clearing logs is itself an audited action.

Next​

→ Administration