owen-it/laravel-auditing
Laravel Auditing keeps a history of changes to your Eloquent models using a simple trait. Easily retrieve audited data to track discrepancies, anomalies, and suspect activity, and display detailed model change logs in your Laravel application.
Architecture fit. The package is a thin, trait-based cross-cutting concern that hooks Eloquent's model event lifecycle (created, updated, deleted, restored, retrieved) rather than requiring a repository layer, base-model inheritance, or service wrapping. Integration is opt-in per model via OwenIt\LaravelAuditing\Contracts\Auditable + the Auditable trait, which means we can scope rollout to regulated or high-risk entities (billing records, user roles, permission grants) without touching domain code. Extensibility is via contracts — AuditDriver, UserResolver, IpAddressResolver, UrlResolver, UserAgentResolver, AttributeRedactor, AttributeModifier, AttributeEncoder — so audit sinks and PII masking are substitutable at the container level. That is the right shape for a platform capability, not a library we hard-fork.
Integration feasibility. Low-friction: one Composer dependency, one published config, one published migration, one trait. No external infrastructure required for the default database driver, which is decisive for us versus standing up a CDC pipeline (Debezium/Kafka) or a bespoke observer framework. The version matrix is the main gate: v14.x targets Illuminate 11–13 and PHP ≥ 8.2, so our Laravel/PHP baseline determines whether we're on an actively supported line or an EOL one (13.x and below are explicitly EOL). Custom Audit model support and morph map awareness matter for us because we use morphMap and would inherit broken polymorphic resolution otherwise.
Technical risk. Ranked:
prune() on the database driver and little else. Partitioning, archival, and retention are our problem, and they must be designed before the table crosses ~10^8 rows.Dependents: 0 and a last-release date of 2026-11-02 are both inconsistent with the observed ecosystem and changelog; treat the metadata as unreliable and validate adoption through Packagist download stats and our own peer network before citing it in a business case. Score 64.3 with opportunity 50.5 signals a mature incumbent in a commoditized category — defensible default choice, weak strategic differentiation.Key questions.
audits table in the same database/region as the source data, or does it need to live in a separate compliance store?Stack fit. Laravel 11+ / PHP 8.2+ on v14.x is the only combination I would approve. Anything below means adopting an EOL line with no security backports — that is a hard stop for an audit capability, since the audit trail's evidentiary value depends on the library being maintained. Confirm no Lumen remnants; Lumen support is legacy and not a target.
Migration path. If we are already on v13.x or earlier, treat the v14 upgrade as a separate, pre-approved work item (PHP floor bump, config key changes such as the exclude default and dynamic resolver registration) before enabling auditing on new models. If greenfield, install at v14 and pin to ^14.0 with a renovate/dependabot policy that allows patches automatically and gates minors/majors behind a test pass. Do not hand-roll an observer-based alternative: the resolver/redactor contract set is the part we would otherwise rebuild badly.
Compatibility. Verify: JSON column support on our engine (MySQL 5.7+/8.x, Postgres JSONB), morphMap alignment between audited models and the audits polymorphic columns, custom primary/foreign key config for the User resolver if we use UUIDs, and multi-database setups (audit connection vs. model connection). If we run read replicas, confirm audits write to the primary. If we use soft deletes plus restored, note the v14.0.4 fix around restore events stopping other update listeners — pin at ≥14.0.4.
Sequencing.
auditable_type, auditable_id, event, created_at; consider partitioning key upfront).AttributeRedactor mappings for secrets, tokens, and personal data before the first audited write. Retrofitting redaction leaves unredacted history behind.transitionTo() for workflow timelines) as a product surface after the data layer is trusted.Maintenance. MIT license, no procurement friction, no vendor relationship. Steady state cost is modest: patch upgrades, plus a major upgrade every time Laravel ships one. Budget for a named owner — audit trail semantics are a compliance artifact and need a human accountable for retention and redaction drift when new columns are added to audited models.
Support. Documentation site plus in-repo guide, changelog and release notes with PR-level detail, and a Discord. No commercial SLA. That is acceptable for an internal capability where we can read the source and pin versions, but it means our own runbook — not upstream — is the escalation path. Track upstream issues for our specific drivers; the changelog shows a healthy fix cadence on real production bugs (async logging, reflection/PHP 8.5, restore event handling).
Scaling. The audits table becomes one of the largest in the schema and is read rarely but written constantly. Plan for: partitioning by created_at, archival to cold storage (S3/Parquet) or a dedicated analytics store, prune() on a schedule with a documented retention window, and separate connection/IO budget so audit writes cannot starve transactional workloads. For async mode, size the queue and workers against peak write rate and define a dead-letter path — an audit row that silently vanishes is worse than a slow request.
Failure modes.
Ramp-up. Engineering ramp is near-zero — one trait, one config file, idiomatic Laravel, and the docs cover the common cases. The real ramp is organizational: legal/compliance sign-off on retention, redaction, and access control; security review of the audits table permissions; and admin UX for reading change history. Budget the majority of effort there rather than in integration. Recommend a two-sprint path: sprint 1 for install, redaction policy, and staging measurement; sprint 2 for phase-1 production enablement plus retention job and growth alerting.
How can I help you explore Laravel packages today?