You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Most of this is built. HttpCachePurger (#232 / PR #235) has RENDERED_HTML_TAG = 'cwa-html', a private collectRenderedHtml(), and propagate() which sends the tag to CACHE_URL alongside resource IRIs. The module emits cwa-html on every cacheable page (cwa-nuxt-module#289). A write to a class in http_cache.purge_rendered_html_classes already drops every cached page.
The only thing missing is a way to ask for that purge when there is no write to hang it on.
Why an endpoint, reversing the earlier decision
#232 deliberately rejected a purge endpoint, on the grounds that site-config purging could ride on an existing resource write, so an endpoint would add surface without adding capability. That reasoning held for site config and does not hold for two cases that have since come up:
A front-end-only deploy. The PWA and the API deploy independently. A new build changes every page's /_nuxt asset hashes while changing no resource IRI, so nothing purges and a shared cache serves HTML pointing at files that no longer exist — a blank page, not merely stale content. The PWA cannot know whether the API pod restarted, and with a CDN or a persistent Souin store it would not matter if it did. Asking is the only reliable answer. (Souin's purge endpoint is http://localhost:2019/souin-api/souin, bound inside the API pod, so nothing outside that container can send the BAN itself — see Test email verify process #70.)
A deliberate manual purge, surfaced as an admin action rather than folklore.
The security objection is also weaker than it looked. An admin can already flush the entire HTML cache by editing any site config parameter — that is precisely what purge_rendered_html_classes does. An admin-gated endpoint therefore grants no new capability; it names something that currently only happens as a side effect. The workaround today is "change the site name and change it back", which is worse than an endpoint in every respect.
Shape
A single operation that purges the cwa-html tag only — not an arbitrary key, not the whole store. That keeps it unable to touch the API's own resource caches, so the worst case is "every page re-renders once", never "the cache is gone".
Needs a public entry point on HttpCachePurger; collectRenderedHtml() is private today and propagate() already does the sending, so the addition is small.
Idempotent, returns promptly, does not wait on the cache.
ROLE_ADMIN (or whatever publishable.permission resolves to — worth deciding which, consistent with the rest of the publication work).
The part that needs actual care
The deploy credential, not the endpoint. An admin session is interactive and already trusted. A CI token that can call this is a long-lived secret, so it should be scoped to this one operation rather than being a reused admin token. Its blast radius is a cache stampede — every cached page dropping at once and the traffic landing on SSR together — which is recoverable but worth not handing out casually.
Worth considering a short coalescing window server-side (repeated purges within N seconds collapse into one), since the call is cheap to make and expensive to serve.
Acceptance criteria
An authenticated operation purges the cwa-html tag and nothing else
It cannot be used to purge arbitrary keys or the whole cache
Unauthenticated and under-privileged callers are refused
Repeated calls are safe, and ideally coalesced
Behat covers: purge fires, permission is enforced, and the tag is the only thing sent
What exists already
Most of this is built.
HttpCachePurger(#232 / PR #235) hasRENDERED_HTML_TAG = 'cwa-html', a privatecollectRenderedHtml(), andpropagate()which sends the tag toCACHE_URLalongside resource IRIs. The module emitscwa-htmlon every cacheable page (cwa-nuxt-module#289). A write to a class inhttp_cache.purge_rendered_html_classesalready drops every cached page.The only thing missing is a way to ask for that purge when there is no write to hang it on.
Why an endpoint, reversing the earlier decision
#232 deliberately rejected a purge endpoint, on the grounds that site-config purging could ride on an existing resource write, so an endpoint would add surface without adding capability. That reasoning held for site config and does not hold for two cases that have since come up:
/_nuxtasset hashes while changing no resource IRI, so nothing purges and a shared cache serves HTML pointing at files that no longer exist — a blank page, not merely stale content. The PWA cannot know whether the API pod restarted, and with a CDN or a persistent Souin store it would not matter if it did. Asking is the only reliable answer. (Souin's purge endpoint ishttp://localhost:2019/souin-api/souin, bound inside the API pod, so nothing outside that container can send the BAN itself — see Test email verify process #70.)The security objection is also weaker than it looked. An admin can already flush the entire HTML cache by editing any site config parameter — that is precisely what
purge_rendered_html_classesdoes. An admin-gated endpoint therefore grants no new capability; it names something that currently only happens as a side effect. The workaround today is "change the site name and change it back", which is worse than an endpoint in every respect.Shape
cwa-htmltag only — not an arbitrary key, not the whole store. That keeps it unable to touch the API's own resource caches, so the worst case is "every page re-renders once", never "the cache is gone".HttpCachePurger;collectRenderedHtml()is private today andpropagate()already does the sending, so the addition is small.ROLE_ADMIN(or whateverpublishable.permissionresolves to — worth deciding which, consistent with the rest of the publication work).The part that needs actual care
The deploy credential, not the endpoint. An admin session is interactive and already trusted. A CI token that can call this is a long-lived secret, so it should be scoped to this one operation rather than being a reused admin token. Its blast radius is a cache stampede — every cached page dropping at once and the traffic landing on SSR together — which is recoverable but worth not handing out casually.
Worth considering a short coalescing window server-side (repeated purges within N seconds collapse into one), since the call is cheap to make and expensive to serve.
Acceptance criteria
cwa-htmltag and nothing elseFront-end button: components-web-app/cwa-nuxt-module#291 · deploy hook: #70