Search by

elvinqulizade / filament-gdpr

Elvin-Qulizade

Filament GDPR - retention & personal data management for Filament v5.

Package info

github.com/Elvin-Qulizade/filament-gdpr

Homepage

Issues

pkg:composer/elvinqulizade/filament-gdpr

Fund package maintenance!

ElvinQulizade

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 1

v1.0.0 2026-09-24 05:30 UTC

This package is auto-updated.

Last update: 2026-09-24 07:59:14 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Data retention & personal data management for Filament v5.

Filament GDPR gives you a retention policy engine and data-subject tooling on top of Eloquent:

  • Retention policies — per model, define a retention period and what happens when it expires (delete or anonymize).
  • Automatic privacy runs — scheduled (or manual) sweeps that anonymize or delete records past their cutoff.
  • Run history — a log of every privacy run with processed/deleted/anonymized counts.
  • Data subject exports — generate a ZIP archive (JSON + readable HTML) of all a subject's records for DSAR responses.
  • A Filament panel — manage policies, trigger runs, view stats, and export a subject's data from the UI.

Installation

You can install the package via composer:

composer require elvinqulizade/filament-gdpr

Important

If you have not set up a custom theme and are using Filament Panels follow the instructions in the Filament Docs first.

After setting up a custom theme add the plugin's views to your theme css file or your app's css file if using the standalone packages.

@source '../../../../vendor/elvinqulizade/filament-gdpr/resources/**/*.blade.php';

Publish and run the migrations:

php artisan vendor:publish --tag="filament-gdpr-migrations"
php artisan migrate

Publish the config file:

php artisan vendor:publish --tag="filament-gdpr-config"

This is the contents of the published config file:

return [

    'user_model' => \App\Models\User::class,
    'user_identifier' => 'email',

    'disk' => 'local',
    'export_prefix' => 'gdpr-exports',

    'delete_mode' => 'soft', // soft | force

    'allow_unique_overwrite' => false,
    'default_strategy' => 'mask',

    'models' => [],

    'model_discovery' => [
        'exclude' => [],
    ],

    'navigation_group' => 'Privacy',

    'schedule' => [
        'enabled' => env('FILAMENT_GDPR_SCHEDULE', true),
        'frequency' => 'daily', // everyMinute | hourly | everyTwoHours | everySixHours | daily | weekly | monthly
    ],

];

Registering the plugin

use ElvinQulizade\Gdpr\GdprPlugin;

->plugins([
    GdprPlugin::make()
        ->navigationGroup('Privacy')
        ->statisticsWidget(true),
])

Usage

Retention policies

Retention policies are stored in the database and managed from the Filament panel (Privacy -> Retention policies) or via the facade:

use ElvinQulizade\Gdpr\Enums\RetentionAction;
use ElvinQulizade\Gdpr\Enums\RetentionPeriodUnit;
use ElvinQulizade\Gdpr\Models\RetentionPolicy;

RetentionPolicy::create([
    'name' => 'Order history',
    'model_class' => \App\Models\Order::class,
    'retention_column' => 'created_at',
    'retention_period' => 24,
    'period_unit' => RetentionPeriodUnit::Months,
    'action' => RetentionAction::Anonymize,
    'anonymize_fields' => ['customer_email' => 'email', 'customer_name' => 'mask'],
    'enabled' => true,
]);

Running the privacy sweep

Manually, or via the scheduler:

php artisan privacy:run
php artisan privacy:run --policy=12 --dry-run

Scheduled runs are enabled by default (config('filament-gdpr.schedule'));

Exporting a data subject's data

php artisan privacy:export user@example.com

Or from the Filament panel (Privacy -> Data subject request). Every export is stored in filament_gdpr_exports and written to the configured disk.

Using the facade

use ElvinQulizade\Gdpr\Facades\Gdpr;

Gdpr::policies();                // enabled policies
Gdpr::run();                     // run the privacy sweep (respects dry-run config)
Gdpr::anonymize($model, []);     // anonymize a single model instance
Gdpr::exporter()->export('user@example.com'); // create an export for a subject

How anonymization works

Configured columns are masked with the chosen strategy:

  • mask — keeps the first 2 characters, masks the rest (jo***); emails keep their domain (j***@example.com).
  • static — replaces the value with the static value configured on the policy.
  • null — sets the column to null.

Primary keys, timestamps, and password-like columns are never touched. Columns covered by a unique index are skipped unless allow_unique_overwrite is enabled.

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.