Laravel Packages

Verifiable Audit Logging with Laravel Chronicle

Published
Verifiable Audit Logging with Laravel Chronicle image

Audit logs are only useful if you can trust them. A database table full of activity records is easy to query, but it's equally easy to quietly edit or delete a row — and there's nothing in a typical Laravel audit package to tell you that happened.

Laravel Chronicle by Vasileios Ntoufoudis approaches this differently. Rather than just writing rows to a table, it builds a cryptographic hash chain across every entry using SHA-256. Each new record incorporates a hash of the previous one, so the entire ledger is interconnected. Alter or remove any entry, and the chain breaks and Chronicle will tell you.

Getting Started

composer require laravel-chronicle/core
php artisan chronicle:install

Writing to the Ledger

Use the record() method on the Chronicle facade to write a new entry into the ledger:

use Chronicle\Facades\Chronicle;
 
Chronicle::record()
->actor($reviewer)
->action('application.approved')
->subject($application)
->metadata(['from' => 'pending', 'to' => 'approved'])
->tags(['applications', 'workflow'])
->commit();

Every entry needs an actor, an action, and a subject. The metadata and tags fields let you attach whatever context makes sense for your domain.

Querying Entries

Chronicle provides scopes for the most common lookups — by actor, subject, action, or tag:

use Chronicle\Entry\Entry;
 
Entry::forActor($reviewer);
Entry::forSubject($application);
Entry::action('application.approved');
Entry::withTag('workflow');

For larger ledgers, Chronicle supports streaming entries one at a time using a database cursor, so memory usage stays constant no matter how many entries there are. cursorPaginateLedger() handles paginated browsing without loading the whole table.

Proving the Ledger Hasn't Changed

Beyond the hash chain, Chronicle also lets you anchor the ledger's state at a point in time with a signed checkpoint. At minimum, a checkpoint stores the current chain head, the signing algorithm, a cryptographic signature, and a timestamp. If someone later claims the log was clean at a given date, you have a verifiable snapshot to back that up.

For situations where the audit data needs to leave your system entirely — handing off to an external auditor, or storing a copy offsite — Chronicle can export the ledger as a signed, self-contained dataset:

php artisan chronicle:export

The export produces three files — entries.ndjson, manifest.json, and signature.json — which can be verified independently by anyone with the package using the following artisan command:

php artisan chronicle:verify-export

Chronicle is a good fit for applications that require reliable audit trails — compliance workflows, financial records, security logging, or forensic analysis. You can find the source and full documentation on GitHub.

Yannick Lyn Fatt photo

Staff Writer at Laravel News and Full stack web developer.

Sponsored

serpapi logo
SerpApi

The Web Search API for Your LLM and AI Applications

Visit SerpApi

The latest

View all →
Volker Dusch on the PHP RCE Vulnerabilities and Disclosure image

Volker Dusch on the PHP RCE Vulnerabilities and Disclosure

Read article
Decide with Jev: Turn AI Answers into Decisions with PHP Rules image

Decide with Jev: Turn AI Answers into Decisions with PHP Rules

Read article
Skuul: Open-Source School Management Built on Laravel image

Skuul: Open-Source School Management Built on Laravel

Read article
Laravel Read Replicas: Prevent Stale Reads After a Write image

Laravel Read Replicas: Prevent Stale Reads After a Write

Read article
Screenshot: Capture Images and PDFs with PHP and Laravel image

Screenshot: Capture Images and PDFs with PHP and Laravel

Read article
Reset Sticky Database Connections Between Laravel Queue Jobs image

Reset Sticky Database Connections Between Laravel Queue Jobs

Read article