Releases: RomaLytar/yammi-audit-log
Release list
v2.2.0
DX, completeness and observability.
- Testing API: AuditLog::fake() with recording assertions
- Capture completeness: fail-open audit failures are now visible (Stats banner + nav badge)
- OTel bridge: incoming W3C traceparent captured as trace_id, with an "Open distributed trace" link to your APM
- Token/client attribution (Sanctum/Passport)
- HasAuditTrail trait for per-model access
- Legal holds: exempt a subject from retention
- Postman export of the read API
v2.1.0
Span-based causation tree.
- Every change records the span of its unit of work and the span that caused it (span_id / parent_span_id), propagated across the queue.
- The change chain is now drawn as a top-down, collapsible, pannable causation tree.
v2.0.2
Documentation release on top of v2.0.1.
- Restructured the README to lead with the provenance value (actor, origin, correlation) and trimmed it from 376 to about 240 lines.
- Added a table of contents, a provenance-chain diagram, a production-incident example, a zero-model-setup section and a short Yammi vs Spatie comparison.
- Moved the deep feature documentation into docs/ (provenance, governance, forensics, operations, compliance, analytics-and-dashboard, configuration) and linked it.
- Renamed Enterprise to Advanced features and fixed the fail-open wording.
No code or behavior changes since v2.0.0.
v2.0.1
v2.0.0
Application-level provenance and change history for queue-heavy, distributed Laravel apps. Every change is recorded with the real actor, the origin that survives the queue, and a correlation chain back to the one action that caused it — with a verifiable, tamper-evident history on top.
Provenance (the core)
- Multi-level actor attribution: user / job / command / scheduler / system, resolved by an extensible provider chain.
- Origin that survives the queue: a job dispatched by a user keeps that user, serialized into the payload across real workers — proven by a database-worker test.
- Correlation id + cross-model trace: one id per request / command / job cascade, drawn as a ladder indented by job-nesting depth.
- Impersonation-aware: "Jane Doe (impersonated by Support Admin)" — login-as is attributed to both, not just the victim.
- Foreign-key label snapshots ("John Doe", not
user_id: 5), captured at event time and surviving row deletion.
Forensics and compliance
- Time machine: reconstruct the exact state a record had at any past date, read-only.
- Tamper evidence: SHA-256 hash chain +
audit-log:verify; pruning keeps a chain anchor so verification stays strict. - Signed integrity digests (CloudTrail-style): detect deletion of a whole signed segment or the entire table.
- GDPR subject reports in one command (
audit-log:subject-report, NDJSON / HTML). - Recursive secret redaction (passwords, tokens, api keys, including nested JSON) before values reach the database.
- Access logging (who viewed a record) and change reason (
withReason, covered by the hash chain).
Operations
- Anomaly detection: change burst, mass delete, off-hours, cascade weight (write-amplification), plus detection-as-code custom rules; alerts to Slack, signed webhook or mail, on demand or on a cron.
- SIEM streaming to Splunk / Datadog / Elastic / generic HTTP — off the request path, queued, fail-soft.
- Native multi-tenancy: tenant stamped at capture (survives the queue), every read auto-scoped.
- Retention with archive-before-delete to any disk (S3 included), and an optional dedicated database connection with a
transfer-datacommand.
Governance
AuditPolicyper model:ignore()noisy fields, capturewhen()a condition holds,sample()a fraction of high-churn models.- Sampling decided per correlation, so one record's history within a unit of work is kept or dropped together — never left with holes.
event_versionschema contract on every record (and in the API / SIEM payloads) so consumers can branch on the layout.- Fluent query DSL (
AuditLog::query()->field('status')->from('pending')->to('paid')->get()) over the same filter path as the array API.
Analytics and performance
- Indexed changed-keys table: field-level searches seek an index instead of scanning the JSON of every row;
audit-log:backfill-changed-keyscovers existing rows (chunked, resumable). - Correlation analytics: "Top cascades" ranks the heaviest root actions (writes / models / depth), each linking to its trace.
- Change hotspots: most-changed models and most-changed fields, scoped to the current filters.
- Deliberate write path: one record insert plus one batched changed-key insert; capture is fail-open and never blocks the host.
Dashboard and developer experience
- Optional dashboard (
audit-log:ui enable): filters, value-transition search, statistics with heatmap, pagination, anomalies, trace, time machine — vendored assets, no CDN. - In-app documentation page covering every feature, plus a live facade Playground.
- Facades for everything the dashboard shows, and an opt-in JSON API for your own admin panels.
Non-goals (permanent boundaries)
No event sourcing or state replay, no backpressure engine, no in-package search engine, no distributed observability platform, no query profiler. Each would force the audit log to become a source of truth or a real-time system, breaking the invariant that makes it safe to install: capture is fail-closed, off your write path, additive, and never changes your data.
Requirements
PHP 8.1 / 8.2 / 8.3, Laravel 9–13. CI: Pint, PHPStan level 8, the unit suite across the PHP matrix, and a 90%+ line-coverage gate.
v1.0.0
First stable release.
- Automatic capture of Eloquent create / update / delete / restore with field-level diffs and recursive secret redaction
- Actor attribution (user / job / command / scheduler / system) with queue-surviving origin and impersonation awareness
- Correlation tracing across request -> job -> job cascades with a trace UI
- Time machine, record view, noise diagnostics, statistics with a 30-day heatmap
- Optional hash-chain integrity with audit-log:verify
- GDPR tooling: retention (default 180 days), archive to NDJSON, subject access reports, CSV/JSON export
- Anomaly detection (change bursts, mass deletes, off-hours) with Slack / signed webhook / mail alerts
- Native multi-tenancy via a TenantResolver contract
- Optional dashboard (audit-log:ui enable), facades for every screen, opt-in JSON API, settings UI with built-in docs
- PHP 8.1-8.3, Laravel 9-13