netipar/laravel-consent
A Laravel package for managing user consent and privacy preferences. Track opt-ins and opt-outs, store consent records, and integrate GDPR-friendly consent flows into your application with simple, configurable APIs.
Baseline: No prior assessment exists; this evaluates v0.1.0 as a first release. The 0.x version number is material — treat the public API as unstable until a 1.0 is announced.
Architecture fit: The package is a server-authoritative consent layer for Laravel. PHP owns the truth (categories, texts, policy URL, cookie inventory) and projects it into the browser via clientConfig(); the JS side is a framework-free core (@netipar/consent-core) with thin Alpine and Vue 3 adapters. That split is the right shape — it avoids the common failure mode where PHP and JS each hold their own copy of the category list and drift. Reading the raw Cookie header instead of Laravel's cookie abstraction is a deliberate and defensible choice: it survives middleware ordering, Livewire partial requests, and long-lived workers, and it lets a decision be parsed even if cookie encryption is later enabled. It is slightly against the grain of the framework, so confirm it doesn't sidestep any signing/encryption expectation the team relies on.
Integration feasibility: Low-to-moderate. Composer install, publish config/lang/migration, drop <x-consent::banner> into the layout, wrap third-party scripts in type="text/plain" blocks. No external CMP vendor, no network dependency, no SaaS contract — the strategic upside is removing a third-party consent script from the critical path and from the data-processing surface. The cost is that the team now owns the CMP: texts, cookie inventory, and legal review become first-party responsibilities.
Technical risk:
version in config invalidates every stored decision, re-prompts all users, and triggers cookie deletion. Correct for compliance, dangerous as an incidental deploy artifact._ga_*-style prefixes across host and parent domains. It cannot delete cookies the host cannot see or set under unrelated domains. "Complete withdrawal" is a claim to validate against the actual cookie inventory, not a guarantee.consent update plus a late config. That is the compliance-safe mode, but it will undercount conversions versus advanced mode; the marketing/growth owner must accept that trade before adoption.POST /consent/log route under web middleware (CSRF-bearing), throttling, event_id idempotency, HMAC-truncated IPs, and retention pruning. This is the piece most likely to be scrutinized in a DPIA and most likely to page someone at 2am.Key questions:
429, CSRF, network)?<noscript> or server-rendered fallback, or does the banner simply never appear?netipar/cookie-consent 1.x upgrade guide handle existing stored decisions — re-prompt or carry forward?Stack fit: Best fit is a Blade-rendered Laravel app, optionally with Alpine or Livewire. Inertia/Vue 3 is supported via createConsentPlugin() and the renderless ConsentBanner, but that path is younger and less exercised than the Blade route. The package assumes it can render a banner into the page shell and can gate scripts by rewriting type attributes; SPAs that inject scripts dynamically after hydration need explicit handling in the Vue adapter.
Migration path: Two distinct migrations. (a) From nothing — greenfield adoption. (b) From netipar/cookie-consent 1.x — the notes promise an upgrade guide, and the __cookie_consent cookie contract is explicitly shared with netipar/laravel-office-leads, which suggests a family of interop packages. Confirm during evaluation whether existing 1.x decisions are honored or whether the version field forces a one-time global re-prompt; that difference decides whether the cutover is a quiet deploy or a visible, support-ticket-generating event.
Compatibility checks before committing:
domain/path/SameSite config for every hostname you serve, including parent-domain deletion targets.wire:navigate behavior (adapter claims awareness) and any Turbo/HTMX navigation you use.Sequencing:
cookies table with provider, translatable purpose, and ISO 8601 lifetime is the artifact legal will actually read.policy_url, retention days, and the log's IP-hashing scheme. Do this before enabling logging anywhere real.consent update / late config in the tag assistant.Maintenance: You are adopting a product surface, not a library. Three ongoing chores: (1) tracking upstream releases across four packages and keeping them aligned; (2) keeping the cookie inventory current as vendors rename and add cookies — this decays silently and is the most common way consent tooling becomes inaccurate; (3) owning translations beyond the five shipped locales. The bundled consent-development Boost skill and bilingual docs lower the onboarding cost but don't remove the ownership.
Support: Expect three ticket classes — "why am I seeing the banner again" (version bump or stale cookie), "the banner didn't appear" (JS blocked, CSP, or layout not including the component), and DPO/data-subject requests against Consent::history(). The last one means whoever operates the site needs a documented answer for how long consent records live and how to retrieve them. Retention pruning is a scheduled job you must actually schedule; the prunable model does nothing on its own.
Scaling: The banner itself is cheap — one config read per request, and clientConfig() should be cached if your config resolution is non-trivial. The log endpoint is the scaling concern: one synchronous insert per consent event, throttled, on a route that must respond during page interaction. On high-traffic sites with consent-version churn, a global re-prompt produces a synchronized write spike — precisely when you least want one. Confirm the throttle limits, and decide in advance whether logging is mandatory (compliance posture) or best-effort. Plan for the case where the log table grows faster than retention can prune it.
Failure modes to design around:
429, CSRF expiry, DB unavailability) — consent:log-failed fires, but the user's consent decision may still be recorded client-side. Decide whether that divergence is acceptable; a DPO may not think so.Ramp-up: Low for a Blade-only team — the Blade directives, facade, and component cover the common cases and the docs are bilingual. Medium for Inertia/Vue 3, where the renderless component and plugin need real frontend work. Add design and accessibility QA time regardless of stack: the component is intentionally unstyled, and it claims a "shared accessibility contract" that should be verified against WCAG 2.2 AA rather than taken on faith. Budget a half-day of legal/privacy review and a half-day of tag-manager validation as non-engineering prerequisites — they are the actual schedule risk, not the install.
How can I help you explore Laravel packages today?