minkovdev/laragdpr

GDPR Cookie consent and cookie manager for Laravel

Maintainers

Package info

github.com/minkovdev/laragdpr

Homepage

pkg:composer/minkovdev/laragdpr

Transparency log

Fund package maintenance!

Buy Me A Coffee

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0-RC.1 2026-07-13 01:56 UTC

This package is auto-updated.

Last update: 2026-07-13 02:03:54 UTC


README

Latest Version on Packagist Total Downloads GitHub Stars Laravel Support PHP Version License

A comprehensive Laravel package for GDPR-compliant cookie consent and cookie management. This package provides a configurable consent banner, granular per-category cookie preferences, database-backed cookie definitions, and dynamic, risk-analyzed script injection — all rendered through your choice of Blade (Alpine.js), Livewire, or React.

The package is auto-discovered by Laravel, so no manual service provider registration is required.

Key Features

Consent Management

  • GDPR-compliant consent — records consent with a pseudonymized identity, IP address, user agent, timestamp, and the active cookie-policy version.
  • Tamper-proof consent cookie — the consent payload is HMAC-signed with your app key, so it cannot be forged or altered client-side (independent of Laravel's cookie encryption; supports APP_PREVIOUS_KEYS rotation).
  • Immutable audit trail — deletion of consent/choice records is blocked by default, preserving a complete history for regulators (configurable).
  • Flexible banner placement — fixed banner at the top or bottom of the page, with an optional close button for incidental browsing, and configurable privacy/cookie policy links.
  • Consent versioning — bump the policy version to automatically re-prompt every visitor.
  • Works for everyone — identifies both authenticated users and anonymous visitors without linking personal data.

Granular Cookie Preferences & Dynamic Injection

  • Cookie categories — Essential, Analytics, Advertisement, Marketing, Social, and Other (extensible via the database).
  • Dynamic script injection — cookie scripts are injected into <head>, <body>, or the footer based on the user's saved choices, without a full page reload.
  • Script risk analysis — every injected script is scanned for dangerous patterns (eval, Function constructor, document.write, …) and filtered according to a configurable risk threshold.
  • User control — a floating preferences icon and a full settings modal let visitors change or withdraw consent at any time.

Technical Features

  • Three rendering modesblade (default, Alpine.js), livewire, or react.
  • Security by default — security headers and rate limiting are applied to the package's own routes.
  • Data retention & cleanup — configurable retention periods with a cleanup command for GDPR compliance.
  • Observability — a health check endpoint and optional package logging / admin notifications.
  • Multi-language ready — all UI strings ship as translatable language files.

Requirements

Requirement Version
PHP ^8.2, ^8.3, or ^8.4
Laravel ^10.0, ^11.0, ^12.0, ^13.0
Livewire ^3.0 or ^4.0 (only if you use the livewire rendering mode)

Quick Start

1. Install

composer require minkovdev/laragdpr

Migrations are loaded automatically — there is no need to publish or run vendor migrations manually. The database tables are created on php artisan migrate.

2. Publish the configuration (recommended)

php artisan vendor:publish --tag=laragdpr-config

3. Run migrations

php artisan migrate

4. Add the directives to your layout

The package works with Blade directives placed in your main layout (resources/views/layouts/app.blade.php or similar):

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="csrf-token" content="{{ csrf_token() }}" />

    {{-- Package styles --}}
    @laraGdprStyles

    {{-- Cookie scripts for the <head> (e.g. Google Analytics) --}}
    @laraGDPRHeaderCookies
</head>
<body>
    {{-- Cookie scripts for the <body> (e.g. Facebook Pixel) --}}
    @laraGDPRBodyCookies

    {{ $slot ?? '' }}

    {{-- Cookie scripts for the footer (e.g. X pixel) --}}
    @laraGDPRFooterCookies

    {{-- Consent banner + settings modal + preferences icon --}}
    @laraGdprContent

    {{-- Package scripts --}}
    @laraGdprScripts
</body>
</html>

That's it — visitors will now see a consent banner and cookie scripts will be injected according to their choices.

Rendering modes: The example above uses the default blade mode. For Livewire or React modes the same directives are used, but the @laraGdprContent directive renders the appropriate component and the script set differs. See doc/RENDERING_MODES.md.

5. (Optional) Publish assets and views

# Front-end assets (CSS/JS) for styling customization
php artisan vendor:publish --tag=laragdpr-assets

# Blade views for deeper customization
php artisan vendor:publish --tag=laragdpr-views

Before You Go Live

Decisions and caveats every production integration must consciously handle — each links to the full explanation.

  1. Plan for APP_KEY rotation. Consent cookies are HMAC-signed and visitor identities are hashed with your app key. Rotating it without APP_PREVIOUS_KEYS invalidates every consent cookie and identity hash — all visitors are re-prompted and lose their saved choices. Rotate the Laravel-recommended way. → Application key rotation
  2. Open the health endpoint deliberately. GET /laragdpr/health answers 403 outside the local environment until you either redefine the viewLaraGdprHealth gate (e.g. for admins) or set LARAGDPR_HEALTH_SECRET for external uptime monitors — choosing the header or query transport via LARAGDPR_HEALTH_SECRET_VIA. → Health check access
  3. Decide how erasure requests meet the immutable audit trail. With the default immutable_consents / immutable_choices, calling delete() on consent/choice records throws. If your compliance workflow hard-deletes individual records, plan to disable the flag or delete via a mass query deliberately. → Immutable records
  4. Keep expose_exception_messages off in production. It appends raw exception messages (queries, class names, configuration) to visitor-facing JSON responses and to the health endpoint's per-check detail. Debugging aid only. → expose_exception_messages
  5. Protect the pages that embed the banner from framing. The package's security headers cover only its own routes — clickjacking protection for the pages rendering @laraGdprContent (an invisible-iframe overlay tricking visitors into clicking Accept All) is your application's X-Frame-Options / frame-ancestors responsibility. → Security headers
  6. Treat cookie-management access as privileged. Script risk analysis is a pattern-based heuristic, not a sandbox — obfuscated JavaScript can bypass it. Whoever can author cookie script content can effectively run JavaScript on your pages. → Script risk analysis
  7. Bump COOKIE_POLICY_VERSION when your policy or scripts change. A version bump re-prompts every visitor, keeping recorded consent aligned with what they actually agreed to. Forgetting it means consent records reference an outdated policy. → Consent versioning

Configuration

All configuration lives in config/laragdpr.php (after publishing) under the laragdpr key, and is overridable with LARAGDPR_* environment variables. Highlights:

Config key Env variable Default
require_consent LARAGDPR_REQUIRE_CONSENT true
cookie_policy_version COOKIE_POLICY_VERSION '1.0.0'
rendering_mode LARAGDPR_RENDERING_MODE 'blade'
banner.position LARAGDPR_CONSENT_BANNER_POSITION 'bottom'
banner.show_close_button LARAGDPR_BANNER_SHOW_CLOSE true
banner.text.privacy_policy_link LARAGDPR_CONSENT_BANNER_TEXT_PRIVACY_POLICY_LINK 'privacy-policy'
banner.text.cookie_policy_link LARAGDPR_CONSENT_BANNER_TEXT_COOKIE_POLICY_LINK 'cookie-policy'
use_sweetalert LARAGDPR_USE_SWEETALERT true
disable_notifications LARAGDPR_DISABLE_NOTIFICATIONS false
retention.consent_records LARAGDPR_CONSENT_RETENTION_DAYS 365
retention.choice_records LARAGDPR_CHOICE_RETENTION_DAYS 365
preferences.show_icon LARAGDPR_PREFERENCES_SHOW_ICON true
preferences.icon_position LARAGDPR_PREFERENCES_ICON_POSITION 'right'
consent_cookie.name LARAGDPR_COOKIE_CONSENT_NAME 'laragdpr_cookie_consent'
consent_cookie.lifetime_days LARAGDPR_COOKIE_CONSENT_LIFETIME_DAYS 30
security.security_headers_enabled LARAGDPR_SECURITY_HEADERS_ENABLED true
script_risk_threshold LARAGDPR_SCRIPT_RISK_THRESHOLD 'low'
rate_limiting_enabled LARAGDPR_RATE_LIMITING_ENABLED true
health_check_enabled LARAGDPR_HEALTH_CHECK_ENABLED true
health_check_secret LARAGDPR_HEALTH_SECRET null
health_check_secret_via LARAGDPR_HEALTH_SECRET_VIA 'header'
expose_exception_messages LARAGDPR_EXPOSE_EXCEPTION_MESSAGES false
immutable_consents / immutable_choices true

See doc/CONFIGURATION.md for the complete reference.

Cookie & Consent Management

Cookie definitions and categories are stored in the database (seeded automatically). The package injects the matching scripts only after the visitor has granted consent for the relevant category, and only when the script passes the configured risk analysis.

Data Retention & Cleanup

To stay GDPR-compliant, old consent and choice records can be purged automatically:

# Preview what would be deleted
php artisan laragdpr:cleanup-data --dry-run

# Delete records older than the configured retention period
php artisan laragdpr:cleanup-data

# Delete records older than a specific number of days
php artisan laragdpr:cleanup-data --days=180

Schedule it in routes/console.php (Laravel 11+) or app/Console/Kernel.php:

use Illuminate\Support\Facades\Schedule;

Schedule::command('laragdpr:cleanup-data')->weekly()->sundays()->at('02:00');

Security & Compliance

  • HMAC-signed consent cookie — the consent payload is signed with your app key and verified on every read; tampered or hand-crafted payloads are rejected. Key rotation is supported via APP_PREVIOUS_KEYS.
  • Immutable consent records — deletion of consent/choice records is blocked by default to preserve the audit trail (immutable_consents / immutable_choices).
  • Security headers are added to the package's own routes (X-Content-Type-Options, Referrer-Policy, Permissions-Policy, frame/cross-origin policies) and can be disabled or customized.
  • Rate limiting protects the consent/choice endpoints.
  • Script risk analysis blocks risky admin-authored scripts above a configurable threshold.
  • Data integrity validation can throw or log when inconsistent data is detected, with optional administrator email notifications.
  • No internal error disclosure — visitors see only a generic, translated error message; raw exception messages are logged, not sent (opt-in for debugging via expose_exception_messages).
  • Consent versioning lets you re-prompt users when your policy changes.
  • Health check endpoint for monitoring — access-controlled via the viewLaraGdprHealth gate (local-only by default) or a shared secret for external uptime monitors.

See doc/SECURITY_AND_COMPLIANCE.md.

Documentation

Detailed documentation lives in the doc/ folder:

Document Contents
doc/README.md Documentation index
doc/INSTALLATION.md Detailed installation & quick start for all three rendering modes
doc/CONFIGURATION.md Full configuration & environment-variable reference
doc/RENDERING_MODES.md Blade directives, Livewire components, React, preferences icon
doc/COOKIE_MANAGEMENT.md Database schema, models, categories, script injection, risk levels
doc/API_REFERENCE.md Services, routes, events, commands, models, enums, helpers
doc/SECURITY_AND_COMPLIANCE.md Signed consent cookie, security headers, rate limiting, integrity, immutable records, versioning, retention, health

Contributing

Contributions are welcome! Please open a Pull Request. See CONTRIBUTING.md for guidelines.

Support

📄 License & Fair Use Disclaimer

Please read the LICENSE.md file.

🚀 Looking for more features? (Dual Licensing)

We are actively developing a PRO version with advanced enterprise features, extended support, and premium components. If you love this package and want to unlock its full potential, stay tuned or visit our official website: https://laragdpr.com.