Type to search pages and rules.

Browse pages

Audit Trail

An audit trail proves who attempted what inside data one party owns while another party acts in it, including attempts the system refused. This page states what the trail stores for each attempt, which attempts it covers, where the producer runs, how the store resists tampering, and how a reviewer reads the trail. A team whose system acts in another party's data selects this extension and keeps one trail that proves accountability instead of reconstructing the answer from logs and domain events (facts the system recorded as completed).

Markdown45 provisions

Stack: any

Layer: application

Activation#

Activation scope: project.

Applicable specification kinds: None.

The consumer enables audit when a person or a machine acts inside data that another party owns and a later reviewer has to establish who is accountable. A regulatory obligation, a customer contract, payment scope, and platform-side support access each meet this condition.

Audit obligations maps each provision on this page to the external obligation it satisfies.

Baseline Relationship#

This extension replaces litespec/quality/security#record-security-audit-events. The baseline states the required record fields for one security audit event. This extension owns the producer, the transaction boundary, the selection policy, the store, and the read path.

This extension switches on no optional record type.

Diagnostic logs and domain events already exist in every system, but neither answers who is accountable. An audited system keeps three records with different producers, readers, and retention. Conflating them removes evidence.

RecordHoldsRead by
Diagnostic logWhat the software didEngineers during an incident
Domain event streamWhat became trueThe system itself
Audit trailWho is accountable for an attemptReviewers, customers, regulators

A domain event cannot substitute for an audit record. A domain event carries domain identity rather than use-case identity, and one event type can come from more than one use case. A domain event carries only the fields the domain needs, so an actor the domain ignores is absent. A refused attempt changes no state and raises no event, even though refusal is the case a reviewer asks about.

Standards#

Record the Audit Adoption Decision#

ruleruleguidance
litespec/ext/audit#record-the-audit-adoption-decision
Statement

An audit adoption decision MUST record its audited categories, threshold, access model, integrity method, and records entry.

Applies toartifact: record:decision

Why

Which actions to audit, how long to keep them, and how to protect them are policy choices, so the project declares them once in the adoption decision. A reviewer reads the declared policy before reading the implementation instead of reconstructing it from the code, which would give two reviewers two different policies.

Checka reviewer answers

Reviewed forWhich adoption decisions lack categories, threshold, access model, integrity method, or records entry? Look at the adoption decision behind the audited Commands.

Marked guidance: a reviewer answers this question.

Declare Audit Selection on Every Command#

ruleruleguidance
litespec/ext/audit#declare-audit-selection-on-every-command
Statement

Every command use case MUST declare its audit position in its audit field, or declare an exemption with its justification.

Applies toartifact: record:use-case

Why

An audit selection that lives only in code is invisible: a reader cannot tell an unaudited command from an audited one whose call is missing. The audit field states the reason of required, optional, or none with its target, or the exemption with its justification, so each omission becomes a visible statement. Commands are audited by default with reason none. litespec/core/use-cases#state-the-audit-position-of-every-command states the field, and review reads the selection instead of hunting for missing calls.

Example

A storefront browse command declares an exemption because a public catalog read is not a sensitive action.

Checka reviewer answers

Reviewed forWhich command use cases lack an audit position or an exemption with its justification in their audit field? Look at the use case pages.

Marked guidance: a reviewer answers this question.

Audit Async Work at Request Time#

ruleruleguidance
litespec/ext/audit#audit-async-work-at-request-time
Statement

Work that runs after its request MUST write its audit record at request time.

Applies toartifact: command-handler

Why

The actor, the origin, and the grant exist when the request arrives; the later run carries worker identity under system auth, which says nothing about who asked. Writing the record at request time ties the attempt to the caller who made it. A record written when the background run starts would attribute every scheduled and deferred act to the worker instead of the requester.

Checka reviewer answers

Reviewed forWhich deferred runs write their audit record at run time instead of request time? Look at the audit rows beside the requesting calls.

Marked guidance: a reviewer answers this question.

Cover the Required Audit Categories#

ruleruleguidance
litespec/ext/audit#cover-the-required-audit-categories
Statement

An audit selection MUST include authentication, authorization denial, grant change, monetary action, tenant configuration, personal-data read, bulk export, and background-process change.

Applies toartifact: record:decision

Why

Each listed category answers a question a security review, a customer, or a supervisory authority asks after an incident: who signed in, who was refused, who changed a grant, who moved money, and the rest. A trail that omits a category has no answer when that question arrives. The list fixes the floor so no project discovers the gap during its first review.

Checka reviewer answers

Reviewed forWhich required categories have no selection entry? Look at the declared selection beside the eight listed categories.

Marked guidance: a reviewer answers this question.

Exclude Indiscriminate Auditing#

ruleruleguidance
litespec/ext/audit#exclude-indiscriminate-auditing
Statement

A project MUST NOT audit every Command without a recorded selection.

Applies toartifact: record:use-case

Why

A trail that records every Command buries the sensitive action inside routine traffic, and the reviewer who has to read it stops reading. Volume then defeats the review the trail exists to support. A recorded selection keeps the trail small enough to read.

Checka reviewer answers

Reviewed forWhich audited categories lack a recorded selection reason? Look at the declared selection.

Marked guidance: a reviewer answers this question.

Emit Audit Records at the Mediation Boundary#

ruleruleguidance
litespec/ext/audit#emit-audit-records-at-the-mediation-boundary
Statement

An audit producer MUST run in the mediation pipeline stages that dispatch the Command.

Applies toartifact: any

Why

Only the pipeline stages that dispatch the Command observe the whole attempt, including attempts the handler never reaches. An audit call inside the handler misses every attempt that throws before it and every refusal the pipeline makes. The pipeline is therefore the one place that records all three outcomes.

Example

A pre-handler opens the audit scope, a post-handler closes it as succeeded, and an error handler closes it as denied or failed.

Checka reviewer answers

Reviewed forWhich audit writes run inside handlers instead of the mediation pipeline? Look at the producer stages and the handler code.

Marked guidance: a reviewer answers this question.

Restrict Handler Contribution to Determined Values#

ruleruleguidance
litespec/ext/audit#restrict-handler-contribution-to-determined-values
Statement

A handler MUST contribute only the audit values that the handler alone determines.

Applies toartifact: command-handler

Why

The declaration beside the message already fixes the audit target and the reason value the message carries, as litespec/backend/application#declare-audit-values-beside-the-message requires, so the pipeline records both on every outcome, including a denial. Only the handler knows the values it learns while running, such as a generated target identity or a reason value composed from loaded state. Letting the handler write the rest invites a second copy of each field that drifts from the first.

Example

A create handler contributes the identity it generated. It contributes no actor, action code, timestamp, or value the message already carries.

Checka reviewer answers

Reviewed forWhich handler contributions repeat the declared target or reason value, the actor, action code, or timestamp? Look at the handler audit calls.

Marked guidance: a reviewer answers this question.

Exclude Derived Audit Trails#

ruleruleguidance
litespec/ext/audit#exclude-derived-audit-trails
Statement

An audit trail MUST NOT be derived from domain events, database triggers, or change data capture.

Applies toartifact: any

Why

Domain events, triggers, and change data capture describe committed state change. They carry no refused attempt, no use-case identity, and no request origin, which are the fields a reviewer reads. A trail derived from them answers what changed and never who attempted it.

Checka reviewer answers

Reviewed forWhich trail writes derive from events, triggers, or capture? Look at the producer source.

Marked guidance: a reviewer answers this question.

Record the Required Audit Fields#

ruleruleguidance
litespec/ext/audit#record-the-required-audit-fields
Statement

An audit record MUST contain actor, action, target, outcome, business time, record time, and tenant, fixed where the tenancy extension is absent.

Applies toartifact: any

Why

Actor, action, target, outcome, the two times, and the tenant together answer who attempted what, against whose data, with what result, and when. Business time states when the action happened and record time states when the evidence was written, so a delayed write stays visible as a delay. A record missing any of them leaves the accountability question half answered.

Checka reviewer answers

Reviewed forWhich records lack actor, action, target, outcome, business time, record time, or tenant? Look at the stored audit rows.

Marked guidance: a reviewer answers this question.

State the Action as Use-Case Identity#

ruleruleguidance
litespec/ext/audit#state-the-action-as-use-case-identity
Statement

An audit action MUST use the identity of the use case that the actor invoked.

Applies toartifact: any

Why

A reviewer who reads an action value opens the specification of that use case to learn the intended behavior. A separate action vocabulary needs a mapping to those specifications, and the mapping drifts as both sides change. Reusing the use-case identity keeps record and specification joined with no mapping to maintain.

Example

catalog.add-product names both the use case and the audited action.

Checka reviewer answers

Reviewed forWhich action values name something other than the invoked use case? Look at the action column beside the use case pages.

Marked guidance: a reviewer answers this question.

Record the Refusal Code on an Unsuccessful Attempt#

ruleruleguidance
litespec/ext/audit#record-the-refusal-code-on-an-unsuccessful-attempt
Statement

An audit record with a denied or failed outcome MUST carry the refusal code that the attempt produced.

Applies toartifact: any

Why

A refused permission and an exhausted precondition need different responses, but both look like failure without a code. The refusal code tells the reviewer which one the attempt produced. It also lets trend queries count one kind of refusal across the whole trail.

Checka reviewer answers

Reviewed forWhich denied or failed records lack the refusal code? Look at the unsuccessful audit rows.

Marked guidance: a reviewer answers this question.

Version the Audit Record Shape#

ruleruleguidance
litespec/ext/audit#version-the-audit-record-shape
Statement

An audit record MUST carry an explicit schema version.

Applies toartifact: any

Why

A retained record outlives several shapes of the application that wrote it. An explicit version lets a later reader parse each record in the shape it was written in. Without it, every shape change forces a rewrite of retained evidence.

Checka reviewer answers

Reviewed forWhich records lack an explicit schema version? Look at the stored audit rows.

Marked guidance: a reviewer answers this question.

Use a Closed Actor Set#

ruleruleguidance
litespec/ext/audit#use-a-closed-actor-set
Statement

An audit actor MUST be one of person, company, provider, system, or guest.

Applies toartifact: any

Why

An absent actor collapses three answers into one: a scheduled process acted, a device acted, or no one recorded the actor, and only the third is a defect. The five kinds separate them: a device maps to the person whose account authorized it, with the device as the client description, and a named process maps to system. A free-text actor would let each writer spell the same actor differently and break every actor filter.

Example

A warehouse handheld records the person actor whose account authorized it. The origin record names the device.

Checka reviewer answers

Reviewed forWhich actor values fall outside the five actor kinds? Look at the actor column, with devices and processes mapped.

Marked guidance: a reviewer answers this question.

Record Delegated Administrative Access#

ruleruleguidance
litespec/ext/audit#record-delegated-administrative-access
Statement

An action that an actor takes under an administrative or support grant MUST record that the grant was used.

Applies toartifact: any

Why

Support staff act inside customer data under a grant, and without a marker their actions read exactly like customer actions. The marker makes a no-silent-access commitment demonstrable: every supplier-side action says so on its own record. A reviewer who cannot separate the two cannot verify the commitment.

Checka reviewer answers

Reviewed forWhich support-grant actions lack the grant marker? Look at the records of actions under administrative grants.

Marked guidance: a reviewer answers this question.

Record Every Attempt Outcome#

ruleruleguidance
litespec/ext/audit#record-every-attempt-outcome
Statement

An audit record MUST carry an outcome of succeeded, denied, or failed.

Applies toartifact: any

Why

A trail of successes is a change history, not evidence. The refused attempt carries the security signal, and the failed attempt carries the operating signal. Three outcomes keep both signals in the same trail as the successes they qualify.

Example

succeeded names a committed change, denied names a refused authorization, and failed names a permitted attempt that did not complete.

Checka reviewer answers

Reviewed forWhich records lack a succeeded, denied, or failed outcome? Look at the outcome column.

Marked guidance: a reviewer answers this question.

Record Refused Authorization#

ruleruleguidance
litespec/ext/audit#record-refused-authorization
Statement

An authorization decision that refuses an audited action MUST produce an audit record.

Applies toartifact: any

Why

Repeated refusal is the first indicator of a compromised or probing account, and no other record holds it: nothing changed, so nothing else was written. Each refusal therefore writes its own record. A trail without refusals shows an attacker who never failed.

Checka reviewer answers

Reviewed forWhich refused authorizations produced no denied record? Look at the refusal paths beside the trail.

Marked guidance: a reviewer answers this question.

Record Failed Audited Attempts#

ruleruleguidance
litespec/ext/audit#record-failed-audited-attempts
Statement

An audited action that the actor was permitted to take and that did not complete MUST produce an audit record.

Applies toartifact: any

Why

A permitted attempt that throws is neither a success nor a refusal, and without a record it vanishes entirely. Writing it separates an operating defect from an access problem: failures cluster around broken behavior, denials cluster around missing permission. Support reads that split before it reads the logs.

Checka reviewer answers

Reviewed forWhich permitted attempts that threw produced no failed record? Look at the error paths beside the trail.

Marked guidance: a reviewer answers this question.

Record the Request Origin#

ruleruleguidance
litespec/ext/audit#record-the-request-origin
Statement

An audit record produced from an inbound request MUST carry the request origin address, the client description, and the request identifier.

Applies toartifact: any

Why

Two records naming one account state nothing about location. The same account acting from two countries within one minute states that the account is compromised, but only when each record carries origin, client, and request identifier. The request identifier further joins the record to the exact request in the diagnostic log.

Checka reviewer answers

Reviewed forWhich request-produced records lack origin, client, or request identifier? Look at the inbound-request audit rows.

Marked guidance: a reviewer answers this question.

Record the Operation Trace Identity#

ruleruleguidance
litespec/ext/audit#record-the-operation-trace-identity
Statement

An audit record MUST carry the trace identifier of the operation that produced it.

Applies toartifact: any

Why

The audit record states what was attempted, and the diagnostic log states what the software did while attempting it. The trace identifier joins the two, so an investigation moves from evidence to detail in one step. Without it, the investigation stops at the audit record and reconstructs the rest by time.

Checka reviewer answers

Reviewed forWhich records lack the trace identifier of their operation? Look at the stored audit rows.

Marked guidance: a reviewer answers this question.

Exclude Secrets and Payment Data#

ruleruleguidance
litespec/ext/audit#exclude-secrets-and-payment-data
Statement

An audit record MUST NOT contain a credential, token, session identifier, encryption key, or payment instrument value.

Applies toartifact: any

Why

The trail is retained, widely readable, and append-only, which is the worst combination for a secret: retention extends the exposure and append-only removes the repair. A credential or payment value written once stays readable for the whole retention period. Secrets and payment values therefore travel in the systems built to hold them, never in the trail.

Checka reviewer answers

Reviewed forWhich records contain a credential, token, session identifier, key, or payment value? Look at the stored audit rows.

Marked guidance: a reviewer answers this question.

Exclude Personal Data Beyond Actor Identity#

ruleruleguidance
litespec/ext/audit#exclude-personal-data-beyond-actor-identity
Statement

An audit record MUST NOT contain personal data other than the pseudonymous identifier of the actor and the target.

Applies toartifact: any

Why

A record holding a name, an address, or a message body turns retention into an erasure conflict: the law asks for deletion and the trail asks for keeping. Pseudonymous identifiers keep the record meaningful while the mapping lives, and erasable once the mapping goes. The record then survives erasure instead of fighting it.

A pseudonymous identifier is still personal data where the party holding it can reverse it. That is the position the EDPB states. The identifier is therefore safe inside the tenant that owns the mapping. It is a disclosure when it leaves that tenant.

Example

An audit export crossing a tenant boundary replaces each identifier with one derived for that export. The receiving party then cannot join the records back to a subject.

Checka reviewer answers

Reviewed forWhich records contain personal data beyond pseudonymous actor and target identifiers? Look at the stored audit rows.

Marked guidance: a reviewer answers this question.

Exclude State Snapshots#

ruleruleguidance
litespec/ext/audit#exclude-state-snapshots
Statement

An audit record MUST NOT contain a copy of the state before or after the audited change.

Applies toartifact: any

Why

The domain event stream already holds each change under its own retention. Copying before and after state into the trail duplicates that storage and widens every record with data the reviewer did not ask for. The trail adds the actor and the reason value, which nothing else holds, and leaves the change itself to the stream.

Checka reviewer answers

Reviewed forWhich records contain before or after state copies? Look at the stored audit rows.

Marked guidance: a reviewer answers this question.

Commit a Success Record with Its Business Change#

ruleruleguidance
litespec/ext/audit#commit-a-success-record-with-its-business-change
Statement

An audit record with a succeeded outcome MUST commit in the same database transaction as the change it describes.

Applies toartifact: any

Why

One transaction makes the action and its evidence inseparable: the change commits with its record or neither commits. Separate writes admit both an unrecorded action and a record of a rolled-back action. Either one leaves the trail disagreeing with the data it describes.

Checka reviewer answers

Reviewed forWhich succeeded records commit outside their business transaction? Look at the success write path.

Marked guidance: a reviewer answers this question.

Write an Unsuccessful Record Outside the Failed Transaction#

ruleruleguidance
litespec/ext/audit#write-an-unsuccessful-record-outside-the-failed-transaction
Statement

An audit record with a denied or failed outcome MUST be written on a connection that the failing transaction does not roll back.

Applies toartifact: any

Why

A denied or failed attempt ends with its transaction rolling back, which would take a record written inside it. The record therefore travels on a connection the rollback does not touch. The evidence of a refusal outlives the refusal itself.

Checka reviewer answers

Reviewed forWhich denied or failed records roll back with their transaction? Look at the unsuccessful write path.

Marked guidance: a reviewer answers this question.

Stage the Audit Write Before the Business Commit#

ruleruleguidance
litespec/ext/audit#stage-the-audit-write-before-the-business-commit
Statement

An audit producer that stages a success record MUST run before the pipeline stage that commits the business transaction.

Applies toartifact: any

Why

A success record staged after the commit reaches a transaction that is already closed, so the write has nowhere to land. The producer therefore runs before the pipeline stage that commits. Pipeline priority states that order explicitly instead of leaving it to registration order.

Checka reviewer answers

Reviewed forWhich audit stages run after the business commit stage? Look at the pipeline stage order.

Marked guidance: a reviewer answers this question.

Publish Unsuccessful Write Failures#

ruleruleguidance
litespec/ext/audit#publish-unsuccessful-write-failures
Statement

An audit deployment MUST publish the write failure count of its unsuccessful-outcome path.

Applies toartifact: any

Why

The separate connection for unsuccessful records accepts a rare lost record when the process dies between the refusal and the write. Continuous loss is a defect, not bad luck, and only a published count separates the two. The deployment publishes that count so monitoring tells rarity from breakage.

Checka reviewer answers

Reviewed forWhich deployments publish no write failure count for the unsuccessful path? Look at the published metrics.

Marked guidance: a reviewer answers this question.

Scope Every Record to Its Tenant#

ruleruleguidance
litespec/ext/audit#scope-every-record-to-its-tenant
Statement

An audit record describing an action inside tenant-owned data MUST carry the identity of that tenant.

Applies toartifact: any

Why

The tenant is the filter for every read of the trail: each customer reads its own records and no one else's. A record without a tenant identity serves an internal reviewer and no customer. Scoping every record at write time keeps that filter exact.

Checka reviewer answers

Reviewed forWhich records on tenant-owned data lack the tenant identity? Look at the tenant column.

Marked guidance: a reviewer answers this question.

Enforce Append-Only Through Storage Privilege#

ruleruleguidance
litespec/ext/audit#enforce-append-only-through-storage-privilege
Statement

An audit store MUST refuse update and delete through the privileges granted to the writing account.

Applies toartifact: any

Why

An audit store that relies on absent code paths stays append-only until someone writes the missing path. Revoked privileges refuse update and delete no matter what the code attempts. A reviewer verifies a privilege in the database instead of auditing every line for a missing write.

Example

The application account holds INSERT and SELECT on the audit table. It holds neither UPDATE nor DELETE.

Checka reviewer answers

Reviewed forWhich writing accounts hold update or delete on the audit store? Look at the granted store privileges.

Marked guidance: a reviewer answers this question.

Provide Tamper Evidence#

ruleruleguidance
litespec/ext/audit#provide-tamper-evidence
Statement

An audit store MUST chain each record to its predecessor with a SHA-256 hash over a canonical serialization of both.

Applies toartifact: any

Why

The hash chain detects an edit and a removal, because a changed or missing record breaks every value after it. Detection is the obligation: it lets a reviewer prove the trail is intact. Prevention at a higher cost is not required.

The algorithm is named because two implementations that each choose their own cannot verify each other. A verifier written later cannot recompute a chain whose algorithm no one recorded. Canonical serialization is named for the same reason. A hash over a serialization that reorders fields verifies nothing.

Example

The chain value is SHA-256(previousHash || canonical(record)), where canonical sorts object members and uses one fixed encoding for every timestamp and number.

Checka reviewer answers

Reviewed forWhich records lack the chained SHA-256 hash over the canonical serialization? Look at the stored chain values.

Marked guidance: a reviewer answers this question.

Anchor the Audit Chain Outside Its Own Store#

ruleadviceguidance
litespec/ext/audit#anchor-the-audit-chain-outside-its-own-store
Statement

An audit store SHOULD publish a periodic checkpoint of its chain head to a destination that the store's own operators cannot rewrite.

DeviationA store whose recorded threat model excludes its own operators publishes no checkpoint.

Applies toartifact: job

Why

A chain proves that records agree with each other, but anyone holding the store can recompute the whole chain and keep it agreeing. A checkpoint held somewhere the operators cannot rewrite fixes the chain as it stood at that moment. A later recomputation disagrees with the checkpoint, which exposes it.

Example

The checkpoint is the chain head and its record count, published at a stated interval. A separate append-only destination, a timestamping authority, and a transparency log each qualify.

Checka reviewer answers

Reviewed forWhich stores publish no checkpoint outside operator reach? Look at the checkpoint destination and the threat model.

Marked guidance: a reviewer answers this question.

Verify the Integrity Chain on a Schedule#

ruleruleguidance
litespec/ext/audit#verify-the-integrity-chain-on-a-schedule
Statement

An audit deployment MUST verify its integrity chain on a recurring schedule and raise an alert on a break.

Applies toartifact: job

Why

Tamper evidence nobody checks proves nothing: a break sits in the store until someone looks. Scheduled verification turns the chain into a standing claim the deployment re-proves on each run. The alert carries the break to an operator instead of waiting for the next review.

Checka reviewer answers

Reviewed forWhich deployments run no scheduled chain verification with an alert? Look at the integrity job and its alerts.

Marked guidance: a reviewer answers this question.

Add a Correcting Record#

ruleruleguidance
litespec/ext/audit#add-a-correcting-record
Statement

A correction to the trail MUST be a new record that references the earlier one.

Applies toartifact: command-handler

Why

An edited history carries no evidential value, because the reviewer cannot tell a correction from a cover-up. A new record that references the earlier one keeps both visible: the mistake and its fix. The trail then shows its own repairs instead of hiding them.

Checka reviewer answers

Reviewed forWhich corrections edit history instead of adding a referencing record? Look at the correction records.

Marked guidance: a reviewer answers this question.

Retain Each Category for Its Declared Period#

ruleruleguidance
litespec/ext/audit#retain-each-category-for-its-declared-period
Statement

An audit deployment MUST delete a record after the retention period declared for its category.

Applies toartifact: job

Why

Each category declares its retention in the adoption decision, and the deployment deletes records when that period ends. Deletion on schedule keeps retention defensible: kept data has a declared reason and nothing kept lacks one. An indefinite period is the hardest retention to defend and the easiest to correct at design time.

Checka reviewer answers

Reviewed forWhich records outlive the declared retention of their category? Look at the stored rows beside the adoption decision.

Marked guidance: a reviewer answers this question.

Remove the Identity Mapping on Erasure#

ruleruleguidance
litespec/ext/audit#remove-the-identity-mapping-on-erasure
Statement

An erasure request MUST remove the mapping from actor identifier to person and retain every audit record.

Applies toartifact: command-handler

Why

Erasure asks that the person stop being identifiable, while accountability asks that the record stay. Removing the mapping from identifier to person satisfies both: the record keeps its evidential value and no longer points at anyone. This works only because the record holds no other personal data.

Checka reviewer answers

Reviewed forWhich erasures leave the actor mapping or delete audit records? Look at the erasure handling and the retained rows.

Marked guidance: a reviewer answers this question.

Give the Trail a Read Path#

ruleruleguidance
litespec/ext/audit#give-the-trail-a-read-path
Statement

An audited system MUST provide a trail read as a use case with its access grant, filtered by tenant, actor, action, target, and outcome.

Applies toartifact: query-handler

Why

A trail no use case reads is storage, not a control. The read path is a use case with its own access grant: the actor holds a role at a role scope, the role allows the permission, and the grant permits the read. Tenant, actor, action, target, and outcome filters keep each reader inside the records they may see.

Checka reviewer answers

Reviewed forWhich trail reads lack an access grant or a declared filter? Look at the trail read use case.

Marked guidance: a reviewer answers this question.

Audit Reads of the Trail#

ruleruleguidance
litespec/ext/audit#audit-reads-of-the-trail
Statement

A read of the audit trail MUST itself produce an audit record.

Applies toartifact: query-handler

Why

Reading the evidence is itself a sensitive action: the trail shows who did what across the whole product. A read that writes no record leaves the reviewer outside the trail. Recording each read puts the reviewer inside the same accountability as everyone else.

Checka reviewer answers

Reviewed forWhich completed trail reads produced no audit record? Look at the trail read path.

Marked guidance: a reviewer answers this question.

Record Personal-Data Reads#

ruleruleguidance
litespec/ext/audit#record-personal-data-reads
Statement

A query returning personal data across a boundary MUST produce an audit record, defining the account boundary in the adoption decision where tenancy is absent.

Applies toartifact: query-handler

Why

A read changes no state and therefore leaves no other trace, so a disclosure without a record cannot be investigated. The audit record on a cross-boundary personal-data query states who read whose data and when. Where tenancy is absent, the adoption decision defines the account boundary the rule watches.

Checka reviewer answers

Reviewed forWhich cross-boundary personal-data queries produced no record? Look at the query paths beside the trail.

Marked guidance: a reviewer answers this question.

Record a Bulk Read Inside Its Own Boundary#

ruleruleguidance
litespec/ext/audit#record-a-bulk-read-inside-its-own-boundary
Statement

A query returning personal data for more subjects than its declared threshold MUST produce an audit record, inside one tenant or account boundary as well.

Applies toartifact: query-handler

Why

The cross-boundary rule catches a disclosure to the wrong party, but it misses an export of every record a party may read one at a time, which is the shape a copied dataset has. A query above the declared threshold therefore writes a record even inside one boundary. Article 30 of the GDPR asks what categories of data were processed and by whom, and an unrecorded bulk read answers neither.

Example

A project records the threshold in the adoption decision. A list endpoint whose page size can exceed it audits the read with the subject count rather than the subjects.

Checka reviewer answers

Reviewed forWhich above-threshold queries produced no record with the subject count? Look at the bulk query paths.

Marked guidance: a reviewer answers this question.

Record Bulk Export#

ruleruleguidance
litespec/ext/audit#record-bulk-export
Statement

An export that returns a set of records to a caller MUST produce an audit record naming the requested scope.

Applies toartifact: query-handler

Why

Bulk extraction is the highest-consequence read in most products: one call moves a dataset across the boundary. Naming the requested scope states what left the system. Without it, the project learns the shape of a leak from the party that received it.

Checka reviewer answers

Reviewed forWhich exports produced no record naming the requested scope? Look at the export paths.

Marked guidance: a reviewer answers this question.

Reject an Undeclared Command#

ruleruleguidance
litespec/ext/audit#reject-an-undeclared-command
Statement

An automated check MUST fail when a Command declares neither an audit position nor an exemption, with a composition refusal at startup satisfying this rule.

Applies toartifact: any

Why

The next Command is written by someone who did not read this page. Only an automated gate catches it: the build or startup fails while the declaration is missing. A selection that depends on every author remembering is a selection with holes.

Checka reviewer answers

Reviewed forWhich Commands build or start with no audit position or exemption? Look at the build or startup gate.

Marked guidance: a reviewer answers this question.

Conventions#

Keep Audit Infrastructure in One Location#

conventiondefaultguidance
litespec/ext/audit#keep-audit-infrastructure-in-one-location
Default

Keep the audit record, its store, the producer, and the integrity job under Infrastructure/Auditing/.

ReplacementA consumer records an audit-layout convention naming where its audit parts live.

Applies toartifact: any

Why

The record, the store, the producer, and the integrity job form one evidence mechanism. One Infrastructure location keeps that mechanism reviewable as a whole instead of scattered across the codebase.

Checka reviewer answers

Reviewed forWhich audit parts live outside the documented location or the recorded local convention? Look under Infrastructure/Auditing/.

Marked guidance: a reviewer answers this question.

Declare Audit Selection Beside the Command#

conventiondefaultguidance
litespec/ext/audit#declare-audit-selection-beside-the-command
Default

Declare the action, target kind, category, and reason selector as an attribute on the Command type, beside the use-case audit field.

ReplacementA consumer records a selection-declaration convention naming where each Command declares its audit selection.

Applies toartifact: command-handler

Why

The declaration stays with the code it describes, so a review reads both at once. The use-case page carries the audit position or exemption, and the attribute carries the action, target kind, and category the producer writes. The reason selector names the message field that carries the reason value, so the pipeline reads the declared reason without handler help. A selection kept in a separate file drifts from the Commands it names.

Checka reviewer answers

Reviewed forWhich Commands lack the declaration attribute with its action, target kind, category, and reason selector, or the recorded local convention? Look at the Command types.

Marked guidance: a reviewer answers this question.

Use a Fixed Category Vocabulary#

conventiondefaultguidance
litespec/ext/audit#use-a-fixed-category-vocabulary
Default

Classify each audited action as authentication, authorization-denial, grant-change, monetary-action, tenant-configuration, personal-data-read, bulk-export, or background-process-change.

ReplacementA consumer records a category convention naming the audit categories it uses.

Applies toartifact: command-handler

Why

The category drives retention and the review query. A free-text value defeats both, because each writer spells the same category differently.

Checka reviewer answers

Reviewed forWhich category values fall outside the eight-value vocabulary or the recorded local convention? Look at the declared selection.

Marked guidance: a reviewer answers this question.

Store the Trail Beside the Business Data#

conventiondefaultguidance
litespec/ext/audit#store-the-trail-beside-the-business-data
Default

Store audit records in the business database, under a separate account holding INSERT and SELECT privileges.

ReplacementA consumer records a trail-store convention naming where its audit records live.

Applies toartifact: any

Why

One database provides the atomic success write the transaction rules depend on. A separate account holding only INSERT and SELECT provides the append-only guarantee.

Checka reviewer answers

Reviewed forWhich trails live outside the business database or the recorded local convention? Look at the audit store and its privileges.

Marked guidance: a reviewer answers this question.

Publish a Copy to the Security Platform#

conventiondefaultguidance
litespec/ext/audit#publish-a-copy-to-the-security-platform
Default

Publish a copy of each record to an external security platform through the outbox, and keep the local store authoritative.

ReplacementA consumer records a copy-delivery convention naming how audit copies leave the local store.

Applies toartifact: any

Why

Delivery is at-least-once, while evidence needs one durable source. The local store stays authoritative for accountability and the published copy serves detection, so a lost copy never corrupts the evidence.

Checka reviewer answers

Reviewed forWhich published copies leave the local store non-authoritative, or bypass the recorded local convention? Look at the delivery path.

Marked guidance: a reviewer answers this question.

Dependencies#

Packages: None.

Related extensions: tenancy for tenant resolution, outbox for copy delivery.

Guides: Build an audit trail.