zappzarapp / audit-logger
GDPR-compliant audit logging with injectable encryption, configurable storage, and tamper-proof checksums
Package info
github.com/marcstraube/zappzarapp-php-audit-logger
pkg:composer/zappzarapp/audit-logger
Requires
- php: ^8.4
- ext-pdo: *
Requires (Dev)
- captainhook/captainhook: *
- captainhook/plugin-composer: ^5.3
- cyclonedx/cyclonedx-php-composer: ^6.1
- deptrac/deptrac: ^4.5
- ekino/phpstan-banned-code: ^3.0
- friendsofphp/php-cs-fixer: ^3.91
- infection/infection: *
- mikey179/vfsstream: ^1.6
- phpmd/phpmd: ^2.15
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^13.0
- rector/rector: ^2.3
- roave/security-advisories: dev-latest
- vimeo/psalm: ^6.14
Suggests
- ext-openssl: For AppEncryption (AES-256-GCM application-level encryption)
- dev-master
- v1.1.0
- v1.0.0
- dev-dependabot/github_actions/actions/create-github-app-token-3
- dev-dependabot/composer/dev-dependencies-c4aa8c5f87
- dev-release-please--branches--master--components--zappzarapp/audit-logger
- dev-feat/schema-type-validation
- dev-feat/file-size-limits
- dev-refactor/srp-extract-services
- dev-refactor/extract-result-mapper
- dev-fix/internal-improvements
- dev-ci/dependabot-auto-merge-and-security-label
This package is auto-updated.
Last update: 2026-04-21 00:35:13 UTC
README
GDPR-compliant audit logging for PHP with injectable encryption, configurable storage, and tamper-proof checksums.
Features
- GDPR compliant - Supports Art. 15, 17, 30, 32, 33
- Injectable encryption - AppEncryption (AES-256-GCM) or DatabaseEncryption
- Tamper-proof - HMAC-SHA-256 checksums with
verify()method - Configurable - Custom table name, optional file logging
- Null Object -
NullAuditLoggerfor environments without audit requirements - Zero dependencies - Only requires
ext-pdo(stdlib) - Both PostgreSQL and MariaDB - Migration SQL included
Installation
composer require zappzarapp/audit-logger
Quick Start
use Zappzarapp\AuditLogger\AuditLogger; use Zappzarapp\AuditLogger\AuditLogEntry; $auditLogger = new AuditLogger( pdo: $pdo, encryptionKey: $_ENV['ENCRYPTION_KEY'], ); // Log a data access event $auditLogger->log(new AuditLogEntry( action: 'user.view', entityType: 'user', entityId: 123, userId: $currentUserId, ipAddress: $request->getClientIp(), userAgent: $request->getUserAgent(), )); // Log authentication $auditLogger->logAuth( action: 'login.success', userId: $userId, ipAddress: $request->getClientIp(), userAgent: $request->getUserAgent(), ); // Log admin action $auditLogger->logAdmin( action: 'role.granted', adminUserId: $adminId, entityType: 'user', entityId: $targetUserId, data: ['role' => 'moderator'], ); // Query logs $logs = $auditLogger->getLogsForEntity('user', 123); $userLogs = $auditLogger->getLogsForUser($userId); // Verify integrity foreach ($logs as $log) { if (!$auditLogger->verify($log)) { // Tampered entry detected! } }
Configuration
use Zappzarapp\AuditLogger\AuditLogger; use Zappzarapp\AuditLogger\Encryption\AppEncryption; use Zappzarapp\AuditLogger\Encryption\DatabaseEncryption; // Full configuration $auditLogger = new AuditLogger( pdo: $pdo, encryptionKey: $_ENV['ENCRYPTION_KEY'], encryption: new AppEncryption(), // default (AES-256-GCM in PHP) tableName: 'audit_logs', // default table name logFilePath: '/var/log/audit.log', // optional file logging (null = disabled) ); // Using database-level encryption (for existing encrypt_text() setups) $auditLogger = new AuditLogger( pdo: $pdo, encryptionKey: $_ENV['ENCRYPTION_KEY'], encryption: new DatabaseEncryption(), ); // Disable audit logging (Null Object pattern) $auditLogger = new NullAuditLogger();
Note: File logging (
logFilePath) does not include log rotation. Configure external rotation (e.g.logrotate) to prevent unbounded file growth.Example
/etc/logrotate.d/audit-logger:/var/log/audit.log { daily rotate 90 compress delaycompress missingok notifempty copytruncate }
Note: The library does not set query timeouts on the injected PDO connection. Configure timeouts at the connection level to prevent indefinite blocking:
// PostgreSQL $pdo->exec('SET statement_timeout = 5000'); // 5 seconds // MariaDB / MySQL $pdo = new PDO($dsn, $user, $pass, [ PDO::ATTR_TIMEOUT => 5, ]);
Database Setup
Apply the migration for your database:
- PostgreSQL:
migrations/postgresql/audit_logs.sql - MariaDB:
migrations/mariadb/audit_logs.sql
Documentation
- GDPR Compliance - GDPR articles covered, purge/retention guidance
- Database Encryption - Migration from DB-level encryption
Development
make install # Install dependencies make test # Run tests make analyse # PHPStan static analysis make cs-check # Code style check make check # All quality checks make check-full # Including mutation testing
License
MIT