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
| Action | Where | Permission |
|---|---|---|
| Configure the storage connection | Settings → Audit | Manage the audit journal |
| Read the journal | The Audit tab | View the audit journal |
| Verify the chain | The Audit tab | View the audit journal |
Manage the audit journal is super-admin only by default; View the audit journal 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.
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.
| Condition | Behaviour |
|---|---|
| Storage unavailable | Events stay buffered on the stream; retried |
| Duplicate delivery | Recognised by event ID and treated as success — the journal is idempotent |
| Malformed event | Dropped as permanently bad, rather than wedging the stream |
The consequence: a database outage delays the journal, it does not lose it.
What is recorded
| Category | Examples |
|---|---|
| Authentication | Login success and failure, logout, lockout |
| User administration | Create, edit, role change, activate, deactivate, delete |
| Permission changes | Role-to-permission matrix edits |
| Connection changes | Create, edit, delete, credential changes |
| Namespace changes | Tag and binding changes |
| Alarm operations | Acknowledge, shelve, suppress, restore |
| Configuration | System settings, audit settings, historian designation |
| Backup | Export and restore |
| Privileged operations | Historian ownership claims, service control |
| AI actions | Assistant 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.
TRUSTED_PROXIESOtherwise every record shows the proxy's address instead of the operator's.
Verifying integrity
Verify chain in Settings → Audit (needs View the audit journal) walks the chain and reports any break. 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.
Compliance alignment
The journal is designed against IEC 62443-3-3:
| Requirement | How it is met |
|---|---|
| SR 2.8 — auditable events and record fields | Categories above, with actor, target, timestamp, source |
| SR 2.10 — no loss of audit data | Durable stream buffering before storage |
| SR 2.11 — authoritative timestamps | Server-assigned, not client-supplied |
| SR 2.12 — non-repudiation | Per-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 journal | Execution / system logs | |
|---|---|---|
| Records | Security-relevant actions | Pipeline runs, diagnostics |
| Storage | External SQL | Internal |
| Tamper-evident | Yes | No |
| Clearable from the interface | No | Yes, with Clear execution logs / Clear system logs |
| Purpose | Accountability | Troubleshooting |
That execution logs can be cleared and the audit journal cannot is the distinction. Clearing logs is itself an audited action.