rcsofttech / audit-trail-bundle
Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.
Package info
github.com/rcsofttech85/AuditTrailBundle
Type:symfony-bundle
pkg:composer/rcsofttech/audit-trail-bundle
Fund package maintenance!
Requires
- php: ^8.4
- ext-mbstring: *
- doctrine/doctrine-bundle: ^3.1
- doctrine/orm: ^3.6
- symfony/expression-language: ^7.4|^8.0
- symfony/framework-bundle: ^7.4|^8.0
- symfony/security-bundle: ^7.4|^8.0
- symfony/uid: ^7.4|^8.0
- symfony/validator: ^7.4|^8.0
- symfony/var-exporter: ^7.4|^8.0
- symfony/yaml: ^7.4|^8.0
Requires (Dev)
- dama/doctrine-test-bundle: ^8.6
- easycorp/easyadmin-bundle: ^5.0
- friendsofphp/php-cs-fixer: ^3.60
- infection/infection: ^0.32.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.0
- phpstan/phpstan-doctrine: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpstan/phpstan-symfony: *
- phpunit/phpunit: ^13.1
- spaze/phpstan-disallowed-calls: ^4.7
- symfony/http-client: ^7.4|^8.0
- symfony/messenger: ^7.4|^8.0
- symfony/phpunit-bridge: ^7.4|^8.0
Suggests
- easycorp/easyadmin-bundle: Required to use the provided AuditLogCrudController for a built-in dashboard.
- symfony/http-client: Required to enable the HTTP audit transport.
- symfony/messenger: Required to enable the queue transport and async database transport.
- dev-main
- v3.3.0
- v3.2.1
- v3.2.0
- v3.1.0
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v2.3.2
- v2.3.1
- v2.3.0
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.0
- v2.0.2
- v2.0.1
- v2.0.0
- v1.10.0
- v1.9.6
- v1.9.5
- v1.9.4
- v1.9.3
- v1.9.2
- v1.9.1
- v1.9.0
- v1.8.0
- v1.7.5
- v1.7.4
- v1.7.3
- v1.7.2
- v1.7.1
- v1.7.0
- v1.6.1
- v1.6.0
- v1.5.1
- v1.5.0
- v1.4.0
- v1.3.0
- v1.2.0
- v1.0.1
- v1.0.0
- dev-remove-hard-dependencies
This package is auto-updated.
Last update: 2026-04-23 15:34:13 UTC
README
High-performance audit trail bundle for Symfony.
AuditTrailBundle is a modern, lightweight bundle that automatically tracks and stores Doctrine ORM entity changes. Built for performance and compliance, it uses a Split-Phase Architecture by default, while still allowing stricter in-transaction delivery when your compliance requirements demand it.
Why AuditTrailBundle?
Most audit bundles capture changes synchronously, which can significantly slow down your application's write performance. AuditTrailBundle solves this by separating Capture, Delivery, and phase-appropriate Persistence work.
Split-Phase Architecture
Application Doctrine ORM AuditTrailBundle Queue / Storage
| | | |
| flush() | | |
|----------------->| | |
| | onFlush | |
| |------------------->| |
| | | Compute Diffs |
| | | Persist ORM-safe |
| | | audit rows when |
| | | allowed in-UoW |
| |<-------------------| |
| | | |
| | Execute SQL | |
| | (Transaction) | |
| | | |
| | postFlush | |
| |------------------->| |
| | | Dispatch Audit |
| | | Persist deferred |
| | | database audits via |
| | | direct writer |
| | |-------------------->|
| flush() returns | | |
|<-----------------| | |
| Async Save
- Flexible delivery: Audit capture happens during the flush. By default, dispatch is deferred until the
postFlushboundary, and some transports can also be offloaded to Messenger workers. - Doctrine-safe phase handling: The bundle does not call
flush()from inside DoctrinepostFlush. In-transaction ORM-safe writes stay inonFlush; deferred database writes use a direct writer path. - Data Integrity: Cryptographic signing helps detect tampering with persisted logs and transport payloads.
- Developer First: Simple PHP 8 attributes, zero boilerplate.
Key Features
- High Performance: Deferred-by-default audits using a Split-Phase Architecture (capture in
onFlush, dispatch afterpostFlushin the default mode). - Multiple Transports: Doctrine (Database), HTTP (ELK/Splunk), and Queue (RabbitMQ/Redis/Messenger).
- Deep Collection Tracking: Tracks Many-to-Many and One-to-Many changes with precision.
- Sensitive Data Masking: Native support for
#[SensitiveParameter]and custom#[Sensitive]attributes. - Safe Revert Support: Easily roll back entities to any point in history.
- Access Auditing: Track sensitive entity read operations (GET requests) with built-in request-level deduplication and optional cross-request cooldowns.
- Conditional Auditing: Skip logs based on runtime conditions or Expressions.
- Rich Context: Automatically tracks IP, User Agent, impersonation context, and custom metadata.
- AI-Ready Extension Hooks: Optional AI processors can add namespaced summaries, anomaly flags, or structured insights before audit signing and transport dispatch.
- Web Profiler Integration: Real-time audit log visibility in the Symfony debug toolbar and profiler panel.
Admin UI
Native integration with EasyAdmin provides a built-in dashboard for browsing and reviewing audit logs.
Security & Compliance
Track not just what changed, but who did it and where they were.
- Sensitive Data Masking: Native support for
#[SensitiveParameter]and custom#[Sensitive]attributes. - HMAC Signatures: Audit logs can be signed so tampering can be detected during verification.
- Integrity Verification: Command-line tools to audit your audit logs.
Documentation
| Topic | Description |
|---|---|
| Installation & Setup | Getting started guide. |
| Configuration | Full configuration reference (enabled, transports, integrity, access auditing, collection serialization). |
| Upgrade v3 | Migration checklist for upgrading custom and standard integrations to 3.0. |
| Advanced Usage | Attributes, Conditional Auditing, Impersonation, Custom Context. |
| Transports | Doctrine, HTTP, and Queue (Messenger) transport details. |
| Audit Reader | Querying audit logs programmatically. |
| Revert & Recovery | Point-in-time restoration of entities. |
| Security & Integrity | Data masking, cryptographic signing, and verification. |
| CLI Commands | Console commands for listing, purging, and exporting logs. |
| Integrations | EasyAdmin and Symfony Profiler support. |
| Serialization | Cross-platform JSON format. |
| Failure & Transaction Safety | Recommended settings for defer_transport_until_commit, fallback, and transport errors. |
Quick Start
1. Installation
composer require rcsofttech/audit-trail-bundle
Transport-specific packages are optional:
- Database transport in synchronous mode: no extra package required
- Async database transport or queue transport:
composer require symfony/messenger - HTTP transport:
composer require symfony/http-client - EasyAdmin dashboard:
composer require easycorp/easyadmin-bundle
2. Database Setup (Doctrine Transport)
If you are using the Doctrine Transport (default), update your database schema:
php bin/console make:migration php bin/console doctrine:migrations:migrate
3. Basic Usage
Add the #[Auditable] attribute to any Doctrine entity you want to track.
<?php declare(strict_types=1); use Doctrine\ORM\Mapping as ORM; use Rcsofttech\AuditTrailBundle\Attribute\Auditable; #[ORM\Entity] #[Auditable(ignoredProperties: ['internalCode'])] class Product { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] public private(set) ?int $id = null; #[ORM\Column] public private(set) string $name; }
The default transport stores audit logs in the database. If you enable integrity signing, make sure audit_trail.integrity.secret is configured.
If you enable a transport without its supporting package installed, the bundle fails fast during container build with a clear LogicException.
4. Requirements
- PHP: 8.4+
- Symfony: 7.4+ or 8.0+
- Doctrine ORM: 3.6+
5. Operational Defaults
If you are choosing settings for a production rollout:
- Use
defer_transport_until_commit: truefor HTTP or queue-first setups where application write latency matters most. - HTTP and queue transports remain deferred-phase transports; setting
defer_transport_until_commit: falsedoes not move them into Doctrine'sonFlushtransaction window. - Use synchronous database transport with
fail_on_transport_error: truewhen compliance requires the write and audit to succeed or fail together. - Keep
fallback_to_database: truewhen you want external transport failures to still leave a local audit trail. - Configure a PSR-6
cache_poolif you rely on cross-request access-audit cooldowns.
Feature dependency notes:
database.async: truerequiressymfony/messengerand a Messenger transport namedaudit_trail_databasequeue.enabled: truerequiressymfony/messengerhttp.enabled: truerequiressymfony/http-client- EasyAdmin integration is registered only when
EasyAdminBundleis enabled
Operational notes:
- Audit query limits must be positive integers. The fluent
AuditReader/AuditQueryAPI and repository layer now reject0or negative limits instead of silently accepting them. - Cursor pagination uses audit-log UUIDs. Invalid cursors are rejected.
- EasyAdmin transaction drill-down accepts only one cursor at a time:
afterIdorbeforeId, never both. - CLI audit IP attribution is intentionally conservative. In console contexts the bundle now prefers explicit environment-derived values such as
AUDIT_TRAIL_CLI_IP,SSH_CLIENT, orSSH_CONNECTION; if no valid IP is available, it recordsnullinstead of guessing from hostname resolution. - When an entity changes scalar fields and Doctrine collections in the same flush, the bundle now records one merged
updateaudit instead of splitting that flush into redundant update entries. - EasyAdmin revert previews now handle UUID-backed relations and to-many collections safely, and restored collection values are shown in a readable format instead of raw Doctrine object dumps.
- Delete-driven collection audits are most reliable with bidirectional Doctrine associations. Unidirectional mappings can leave the bundle without enough reverse-relation context to infer an owner-side collection update when a related entity is deleted.
Community & Support
- Bugs & Features: Please use the GitHub Issue Tracker.
- Contributing: Check out our Contributing Guide.
License
MIT License.

