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.

Maintainers

Package info

github.com/rcsofttech85/AuditTrailBundle

Type:symfony-bundle

pkg:composer/rcsofttech/audit-trail-bundle

Fund package maintenance!

rcsofttech85

Statistics

Installs: 3 573

Dependents: 0

Suggesters: 0

Stars: 105

Open Issues: 1

v3.3.0 2026-04-23 15:28 UTC

README

CI Version Downloads License Codacy Badge Codacy Badge Mutation Testing

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 postFlush boundary, and some transports can also be offloaded to Messenger workers.
  • Doctrine-safe phase handling: The bundle does not call flush() from inside Doctrine postFlush. In-transaction ORM-safe writes stay in onFlush; 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 after postFlush in 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.

EasyAdmin Integration Showcase

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.

Integrity Check CLI

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: true for HTTP or queue-first setups where application write latency matters most.
  • HTTP and queue transports remain deferred-phase transports; setting defer_transport_until_commit: false does not move them into Doctrine's onFlush transaction window.
  • Use synchronous database transport with fail_on_transport_error: true when compliance requires the write and audit to succeed or fail together.
  • Keep fallback_to_database: true when you want external transport failures to still leave a local audit trail.
  • Configure a PSR-6 cache_pool if you rely on cross-request access-audit cooldowns.

Feature dependency notes:

  • database.async: true requires symfony/messenger and a Messenger transport named audit_trail_database
  • queue.enabled: true requires symfony/messenger
  • http.enabled: true requires symfony/http-client
  • EasyAdmin integration is registered only when EasyAdminBundle is enabled

Operational notes:

  • Audit query limits must be positive integers. The fluent AuditReader/AuditQuery API and repository layer now reject 0 or 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: afterId or beforeId, 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, or SSH_CONNECTION; if no valid IP is available, it records null instead of guessing from hostname resolution.
  • When an entity changes scalar fields and Doctrine collections in the same flush, the bundle now records one merged update audit 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

License

MIT License.