Cache Invalidation#
cloud-vinyl supports three invalidation mechanisms, all broadcast to every pod in the cluster.
PURGE (object-level)#
A standard HTTP PURGE request removes a single cached object by URL.
Varnish must have return(purge) in vcl_recv for the PURGE method (generated automatically).
Soft purge (default, spec.invalidation.purge.soft: true) marks objects as stale instead
of removing them. Subsequent requests revalidate in the background (stale-while-revalidate).
This prevents cache stampedes on busy endpoints.
Send a purge via the operator proxy:
PURGE http://<operator-svc>:8090/path/to/resource
BAN (expression-based)#
Bans invalidate sets of objects matching a VCL expression. Two routes are available — they differ in where the expression is validated and in how the ACL is enforced.
Via the operator invalidation proxy (default, always available)#
The proxy listens on port 8090 of the operator Service, validates the expression (only obj.http.* LHS; no wildcard-only), and forwards it to every pod via vinyl-agent POST /ban → varnishadm ban <expr>:
POST http://<operator-svc>:8090/ban
Content-Type: application/json
{"expression": "obj.http.X-Cache-Tag ~ \"product-42\""}
Equivalent as native BAN HTTP method with the X-Ban-Expression header:
BAN http://<operator-svc>:8090/
X-Ban-Expression: obj.http.X-Cache-Tag ~ "product-42"
No opt-in needed. Proxy-side ACL enforcement is currently advisory (see “ACLs” below).
Directly to Varnish (BAN method on the traffic port)#
From v0.4.2, VinylCache can expose a BAN handler directly in VCL, bypassing the operator proxy:
spec:
invalidation:
ban:
enabled: true
allowedSources:
- "10.0.0.0/8"
The generator then emits a vinyl_ban_allowed ACL (localhost + operator pod IP + allowedSources) plus a vcl_recv BAN handler that calls std.ban(req.http.X-Vinyl-Ban):
BAN http://<cache-traffic-svc>:8080/
X-Vinyl-Ban: obj.http.x-url ~ "^/news/"
On malformed expressions the handler returns 400 Invalid ban expression: <std.ban_error()> rather than silently succeeding. When the header is missing, 400 Missing X-Vinyl-Ban header. Unauthorised source → 403 Forbidden.
Use obj.http.x-url / obj.http.x-host instead of req.* so the ban lurker can compact bans (req.* bans accumulate O(n*m)). The operator emits beresp.http.x-url / beresp.http.x-host on every cached object when ban.enabled: true is set (or xkey is enabled).
Xkey (surrogate-key)#
Xkey (also called surrogate keys or cache tags) allows grouping objects under arbitrary string keys.
When the cached response includes an Xkey: key1 key2 header, all objects with that key can be
purged with a single request.
POST http://<operator-svc>:8090/purge/xkey
Content-Type: application/json
{"keys": ["product-42", "category-home"]}
The operator issues one PURGE with X-Xkey-Purge: <key> per key to every pod.
Xkey requires the vmod_xkey Varnish module. Enable it in the spec:
spec:
invalidation:
xkey:
softPurge: true # default
ACLs#
There are two layers of access control, enforced at different points:
Proxy-side (
spec.invalidation.purge.allowedSources,spec.invalidation.ban.allowedSources): the operator’s invalidation proxy checks the source CIDR before forwarding to pods. By default all sources are allowed — scope tightly in production.Varnish-side (new in v0.4.2): the generated VCL contains
vinyl_purge_allowed(always) andvinyl_ban_allowed(whenban.enabled: true). Both include127.0.0.1and the operator pod IP automatically;allowedSourcesCIDRs from the spec are appended. This is the ACL enforced invcl_recvagainst the BAN/PURGE method coming directly to the traffic port.
In the common deployment — clients send PURGE/BAN to the proxy, the proxy forwards to Varnish — the operator’s pod IP is the only source Varnish ever sees, so the Varnish-side ACL is effectively a safety net. When direct-to-Varnish traffic is enabled, both layers apply.