scify/laravel-cookie-guard
Laravel Cookie Guard is a configurable cookie consent package for Laravel. It adds a GDPR-friendly banner, lets visitors accept or reject cookie categories, remembers their choices, and helps load scripts conditionally through simple Blade helpers and middleware.
Architecture fit. Laravel-native package: service provider, config file, Blade components, published views/assets/translations, and a single POST /guard-settings/save route. It fits server-rendered Laravel monoliths (Blade, Livewire, Inertia, Turbo) well and does not fit headless/API-only or non-Laravel front ends. The critical architectural property is that it is designed to be forked at install time: views, assets, and translations are published into our repo. Upstream fixes reach us only when we re-publish or hand-merge, so the package's correctness is partly a function of our publishing discipline, not just the vendor's.
Integration feasibility. The Composer bump is trivial; the real work is the four documented upgrade steps. Estimated 3–6 dev hours plus QA, plus a privacy/legal review that is not optional here. Feasible within a normal sprint.
Technical risk: medium. v5.1.0 is labelled minor, but several changes are behaviorally breaking for existing deployments:
POST /guard-settings/save ran without middleware since the first release, so the CSRF token the JS sent was never validated. It is now inside the web group. Any first-party code posting to that route breaks until it sends a token. Separately, this is a years-old CSRF-exempt write endpoint in production — worth a line in the security register and a log review, not just a version bump.cookie_lifetime. It was hardcoded to 30 days; config said 365; the banner text claimed a year. Consent that quietly expired monthly will now persist up to a year. That is a compliance-relevant change requiring privacy sign-off, not a code-review sign-off.enabled config key and the se → sv locale move both break callers despite the "no breaking changes" framing. SemVer discipline is loose; treat minor releases as needing a changelog read.web implies session start on that endpoint — check route caching and any stateless/API consumer assumptions.Assessment: upgrade recommended — it fixes a real CSRF hole and several correctness bugs — but it is not a drop-in patch. Gate it on a staging verification of the erasure behavior and the CSRF path.
Key questions.
data-* attributes?enabled key, the se locale, or the removed cookies_consent_selection cookie?cookie_lifetime change alter our documented consent renewal period?Secure cookie flagging correct behind our load balancer (TrustProxies / X-Forwarded-Proto)?/guard-settings/save be rate-limited at the edge given it is now a session-bearing endpoint?Stack fit. Native to our Laravel version range; the notes reference Laravel 13-specific CSRF behavior alongside older releases, so confirm our version's expectation (token required vs. same-origin accepted) before testing. No new runtime dependencies; the JS still ships as a published bundle.
Migration path (in order).
composer require / update to v5.1.0 in a branch; do not deploy assets yet./guard-settings/save, cookies_consent_selection, cookieConsent, enabled config reads, locale se.php artisan vendor:publish --tag="cookies-consent-public" --force. Diff before committing — --force overwrites local customizations.data-cookie-lifetime, data-cookie-categories, data-required-categories, data-csrf-token). Skipping this silently disables erasure and pins 365-day consent.lang/vendor/cookies_consent/{locale}/messages.php; delete the old lang/vendor/scify/laravel-cookie-guard/ directory.X-XSRF-TOKEN or X-CSRF-TOKEN) to any first-party POST to the save route.required categories match the legal classification.Compatibility and sequencing. Ship to staging first with a real browser matrix; the changed surfaces are JS-driven. Test explicitly: use_separate_page mode (Accept all / Reject optional previously stored nothing), hash-navigation to #consent-settings, keyboard activation of the floating button, and banner behavior on a forced 422/500 from the save endpoint. Run the erasure test on a subdomain to confirm parent-domain deletion does not remove cookies we need. Sequence the privacy review before production, in parallel with staging QA. Rollback is a Composer pin plus asset revert — keep both in the same commit for a clean revert.
Maintenance. Low code footprint, but real fork-maintenance: published views and translations are ours to reconcile on every release. Budget a recurring ~2–4 hours per release for diff-and-merge. Watch two deprecations clocking toward v6: the legacy translation directory (read with a log warning until v6) and the removal of the pre-v3 cookieConsent erasure handler — neither is a problem today, both are calendar items.
Support. Single-maintainer open-source project on GitHub, MIT licensed. No commercial support path; escalation is upstream issues and patches. The release shows healthy signals — external code review, contributor PRs, test count up from 45→60 Pest and 22→51 JS with 100% JS line coverage — which raises confidence in the JS correctness fixes specifically, since that is where the bugs were.
Scaling. Stateless: consent lives in a first-party cookie, so no database or cache tier and no horizontal-scaling constraint. The one per-user cost is a single POST on consent decisions; negligible, but it is now a session-bearing write endpoint, so add edge rate limiting and alerting on 4xx/5xx spikes as a proxy for broken clients.
Failure modes.
data-* attributes are present in rendered HTML in a smoke test.Secure.Ramp-up. Low for a mid-level Laravel developer: one to two hours to read the package, a half-day to run the upgrade safely. The non-obvious skill is not PHP — it is reading the cookie inventory and the erasure semantics correctly, which is a privacy-engineering task. Assign a named owner for the cookie-list review; do not let it fall to whoever runs composer update.
How can I help you explore Laravel packages today?