jeffersongoncalves/laravel-page-cache
Laravel Page Cache adds simple full-page HTTP caching to Laravel apps, storing rendered responses and serving them quickly to reduce database load and speed up page delivery. Includes middleware and cache-clearing helpers.
Architecture fit. This release positions the package as a full-page cache middleware operating in Laravel's HTTP kernel response path. The change is narrowly scoped: when a response is written to cache, the CSP nonce that Vite::cspNonce() produced during rendering is persisted alongside the cached payload and re-applied to the nonce store on a cache HIT, so that a downstream middleware (laravel-security-headers 2.1+) can build a Content-Security-Policy header whose nonce-… source expression matches the inline <script>/<style> tags already baked into the cached HTML. Architecturally this is the correct place to solve the problem — the alternative (rewriting cached HTML on every HIT to swap nonces) is more expensive and more fragile. The design implicitly requires an ordered middleware chain: cache middleware writes the nonce into a request-scoped store, security-headers middleware reads it later in the stack. That ordering is a soft contract, not an enforced one, and is the main architectural coupling introduced.
Integration feasibility. Low-friction for the majority of installs. The blast radius is explicitly bounded: applications without a CSP nonce are unaffected, so the upgrade is a no-op for them. For applications that do use nonces and cache pages, the release converts a currently broken combination (cached markup with a stale nonce plus a freshly generated header nonce → inline scripts blocked) into a working one — this is a bug fix with security-header implications, not a feature expansion. Integration cost is therefore concentrated in a small subset of installs, but for those it is a correctness fix that likely cannot be deferred, since the failure mode is silent (CSP violations in the browser console, degraded but not obviously broken pages).
Technical risk. Three areas warrant scrutiny:
laravel-security-headers 2.1+; the version constraint and middleware ordering must both hold. A partial upgrade yields the old, broken behaviour with no error.Key questions. What Laravel and PHP versions are supported, and is there a documented middleware priority/ordering requirement? Is the nonce persisted in the cache payload itself or in a side channel, and does that survive multi-node cache backends (Redis, Memcached, database)? What is the nonce's entropy source, and is it regenerated on cache refresh? Does the package document interaction with CDN/edge caching? Is there a config switch to disable nonce persistence for installs that terminate CSP at the edge? What is the cache TTL default, and does it bound nonce lifetime?
Stack fit. Assumes a standard Laravel HTTP kernel with middleware-based caching and Vite for asset bundling — a mainstream configuration. The package sits alongside laravel-security-headers rather than replacing any part of it, so it does not contend for ownership of the response header surface. No new infrastructure is implied: the nonce travels with the cache entry the package already writes.
Migration path. Presumably a Composer constraint bump with no schema migrations and no configuration changes required for the unaffected majority. For affected applications the practical migration is: upgrade this package, confirm laravel-security-headers is at 2.1 or above, verify middleware order, then purge the page cache — pre-existing cache entries were written without a stored nonce and will continue to serve mismatched headers until evicted. That cache purge is the single operational step most likely to be forgotten.
Compatibility. Two compatibility axes matter. First, the laravel-security-headers floor of 2.1: applications pinned below it get no benefit and should be upgraded in the same change window. Second, the caching backend — the persistence mechanism must work identically for file, Redis, and database cache stores, and the assessment should confirm the package's test matrix covers each. CDN and reverse-proxy configurations are a third axis and are almost certainly outside the package's control, so they become a documentation and runbook concern rather than a compatibility claim.
Sequencing. Recommended order: (1) inventory which applications actually use a CSP nonce and page caching — this is the affected set, likely small; (2) upgrade laravel-security-headers to 2.1+ first, since that release is additive for non-caching apps; (3) upgrade this package to 1.3.0; (4) confirm middleware ordering in the kernel or via $middlewarePriority; (5) flush the page cache; (6) validate in a staging environment with CSP reporting enabled. Steps 1–2 can proceed independently of this release, which reduces the critical path.
Maintenance. Ongoing cost is low but not zero. The security posture of cached pages now depends on a nonce lifecycle that spans two packages and a cache TTL, so the team owns a cross-package invariant. Any future change to CSP policy, nonce generation, or cache key structure must consider the interaction. Document the invariant in the runbook: changing CSP configuration requires a full page-cache purge.
Support. Expect a small volume of CSP-violation reports if the upgrade is deployed without a cache flush, or if a CDN regenerates headers. These present as "inline script blocked" in browser consoles and are easy to misattribute to the frontend build. Support triage should include a check of whether the served page came from cache and whether header and markup nonces match — a one-line assertion worth adding to smoke tests.
Scaling. Negligible overhead: one short string stored per cache entry, restored on read. No additional round trips, no per-request crypto beyond what rendering already performs. Under multi-node deployments the nonce must be stored in the shared cache backend, not in process memory — worth verifying, since an in-memory store would produce node-dependent mismatches that are painful to reproduce. Cache hit ratio is unaffected. Nonce lifetime becomes coupled to cache TTL, which is the correct knob to expose.
Failure modes. (a) Cached entry without a stored nonce (pre-upgrade entries) → mismatch until eviction. (b) Header regenerated at the edge → mismatch, silent. (c) Middleware order inverted → the security-headers middleware reads an empty nonce store and emits a header without the nonce, or with a fresh one. (d) Cache backend that does not persist the side-channel value → intermittent, node-dependent failures. (e) Predictable nonce derivation → weakened CSP guarantee, undetectable at runtime. Failure mode (b) is the most operationally dangerous because it is invisible to the origin and only manifests in end-user browsers.
Ramp-up. Near-zero for the general case — the release is explicitly a no-op without a CSP nonce. For teams in the affected set, ramp-up is roughly half a day: understand the ordering contract, run a staging validation with CSP report-only mode, and update the runbook. The conceptual lift is understanding why a cached page needs a stable nonce and why that trades away per-response uniqueness; that framing should be included in the release communication rather than left to the reader.
Recommendation. Adopt. This is a scoped correctness fix that unblocks a previously unsafe combination (page caching + nonce-based CSP), with no impact on installs that do not use nonces. Gate rollout on the version-pair check, the cache purge, and a staging validation with CSP reporting enabled. Follow up on the entropy-source and multi-node-persistence questions before enabling in a high-traffic, CDN-fronted environment.
How can I help you explore Laravel packages today?