polysource/audit

Polysource — audit log for non-Doctrine actions: AuditEntry VO, fan-out logger interface, browsable AuditLogResource, GDPR Art. 30 CSV export, retention command.

Maintainers

Package info

github.com/polysource/audit

Homepage

Issues

Type:symfony-bundle

pkg:composer/polysource/audit

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

v0.1.1 2026-05-10 21:00 UTC

This package is auto-updated.

Last update: 2026-05-10 21:02:02 UTC


README

GDPR Art. 30 / HIPAA audit trail for Polysource admin actions.

Part of the Polysource monorepo. MIT-licensed.

When to use

You're running a regulated workload (healthcare, finance, B2B SaaS) and need a write-only, queryable log of every admin action: who did what, when, from where, with what outcome.

What it ships

  • AuditEntry VO + AuditOutcome enum + AuditActorInterface (SymfonySecurityAuditActor default impl).
  • AuditLoggerInterface (write-only) with fan-out via AggregateAuditLogger.
  • DoctrineAuditLogger + Doctrine entity (polysource_audit_log table with 3 indexes for Art. 30 queries).
  • ActionAuditSubscriber — bridges ActionAboutToExecuteEvent / ActionExecutedEvent (dispatched by polysource/symfony-bundle) to the logger. UUID v7 per entry, IP/UA/RequestID in context, trace truncated to 8KB.
  • EasyAdminAuditSubscriber — optional bridge that audits EA CRUD edits (Edit / New / Delete on Doctrine entities). Auto-wired when easycorp/easyadmin-bundle is installed (gated on class_exists); inert otherwise.
  • AuditLogResource — browsable admin resource with 5 standard filters (time range, actor, outcome, action name, resource).
  • ExportAuditCsvAction — GDPR Art. 30 export with 12 locked columns (RFC 4180), gated on POLYSOURCE_AUDIT_EXPORT.
  • polysource:audit:purge --before — retention command with cutoff exclusive, --dry-run, exit codes.

See ADR-020.

Install

composer require polysource/audit

polysource/audit declares doctrine/orm and doctrine/dbal as hard runtime dependencies. The bundled persistence layer (DoctrineAuditLogger, AuditEntryRecord, AuditLogDataSource, PurgeAuditCommand, ExportAuditCsvAction) imports Doctrine at compile time, so installing this package without Doctrine would fatal at autoload. If your host already runs Doctrine for any other reason — most Symfony apps do — the cost is zero. If you need the contracts without Doctrine, depend on polysource/core directly and ship a custom AuditLoggerInterface implementation; only the storage layer is Doctrine-coupled.

Register the bundle:

return [
    Polysource\Audit\PolysourceAuditBundle::class => ['all' => true],
];

Run the migration to create polysource_audit_log.

Extend it

AuditLoggerInterface is 1 method (log(AuditEntry $entry)). To pipe events to Splunk, Datadog, OpenSearch, or any SIEM:

#[AutoconfigureTag('polysource.audit_logger')]
final class SplunkAuditLogger implements AuditLoggerInterface
{
    public function log(AuditEntry $entry): void
    {
        $this->splunk->send([
            'time' => $entry->occurredAt->format(\DateTimeInterface::ATOM),
            'event' => $entry->actionName,
            'actor' => $entry->actorId,
            'outcome' => $entry->outcome->value,
        ]);
    }
}

The AggregateAuditLogger fan-outs across every tagged logger with try/catch isolation — Splunk timing out doesn't break the Doctrine write. See extensibility map.

Documentation