cadish v0.2.2
Clustering hardening + a Cadish Edge batch + cache-isolation/redirect security fixes. Every change is fail-closed and costs nothing when unused — a non-clustered, non-edge cadish on the request/response fast path is byte-for-byte unchanged. Go↔JS edge conformance is kept in lockstep (IR contract v6 → v9, additive fields only).
Highlights
Clustering — "one sharded cache", store-once restored
Surfaced by exercising a real 3-node cluster on staging (the in-process tests passed, but the binary behind a shared client hostname fetched every object from origin twice):
- Objects are cached once per region again. A non-owner reverse-proxying to the owning peer dropped the original client
Hostand client IP, so the owner keyed a proxied request differently from a direct one — storing each object twice and doubling origin load. cadish now forwards the clientHost+ resolved client IP on the peer hop (and overwrites any client-forgedX-Forwarded-For, closing a peer-hop spoof). [D103] - Correct client IP for owner-side ACL / rate-limit / geo decisions on proxied requests (same root cause). [D103]
read_through: apassgoes straight to origin (no peer hop), and writes (POST/PUT/…) reach origin intact instead of being sharded to a peer. [D102]- Self-dial guard is health-aware — a brief owner health flap can no longer route an object back to the local node and stall the coalescer.
All clustering changes are gated by the cluster { } block. A new 3-node single-location deployment guide is in deploy/README.md.
Cadish Edge — cache a workload it previously couldn't
On a high-cardinality media workload, cadish edge build went from 22 forced-pass directives (one forced-pass on a selecting directive fail-opens the whole site → the edge caches nothing) down to a small residual that correctly delegates to the server behind:
all(AND-composite) andquery NAME VALUEmatchers are now edge-native (were server-only → site-wide pass). A sub-term it can't honor still fails closed.query_present NAME+— per-name non-empty-value modifier (Varnish=[^&]+parity).redirect … no_store— marks a personalized redirect uncacheable.+cache_agedeliver special and{device}/{geo*}/{query.NAME}template tokens — reproduces the original worker'sX-CF-Cache-Age/X-CF-Vary-*debug headers, cache-safe by construction (a class token forwarded to origin renders empty unless the selectedcache_keyrecipe varies on that class).cadish edge deploy -origin passthrough— fetch-through mode for a multi-host origin in the same CF zone (fixes the canonicalizing-origin redirect loop).- Edge worker-route exclusions —
edge { bypass_passes }(auto-derived) andedge { bypass PATTERN… }(operator-declared): paths the edge only ever passes are projected as CF routes that run no worker. Plus anX-Cadish-Edgeresponse marker (its absence = served directly by origin). cadish edge deploy -allow-public-values— acknowledge non-secret literal cookie/header values past the deploy safety gate (does not relax the forced-pass gate).
Security
cache_credentialed: cross-user cache leak on a no-signal response — fixed (fail-closed). A credentialed in-scope response carrying no per-response signal, yet made cacheable by a co-existingcache_ttl default ttl N, was stored under the shared credential-free key — serving one user's private body to the next. The response phase now refuses unconditionally without the signal. Server and edge (both had the identical fail-open; present since 0.2.1).- Open redirect via a
$Ncapture in aredirecttarget authority — fixed. A request-sourced token in the Location authority (e.g.GET /index.php@evil.example.com/) could drive an off-origin redirect. A new runtime post-expansion authority assertion (server + edge, byte-identical) re-expands with request-sourced inputs neutralized and suppresses the redirect if the authority differs — also normalizing away embedded/trailing C0 control bytes before the check. - Admin
/api/config: absolute-path disclosure in diagnostic messages — fixed (message now scrubbed, not just position).
Full detail in CHANGELOG.md. Signed binaries + SBOMs are attached below; the multi-arch image is at ghcr.io/cadi-sh/cadish:0.2.2, and the Helm chart at oci://ghcr.io/cadi-sh/charts/cadish --version 0.2.2.