fc-distribution: restrict public IngressRoute to GET+HEAD only

Live verification 2026-04-24 caught POST /blobs on dist.flowercore.io
returning 201 Created with the blob persisted — admin write operations
reachable on the public surface. Controller-level strict entitlement
was on, but that gates reads; writes weren't blocked at all.

Fix: add Method(GET) || Method(HEAD) to the Host match on the public
IngressRoute. POST/PUT/PATCH/DELETE now miss every route for
dist.flowercore.io and Traefik returns 404 before the pod sees the
request. Edge-level defense-in-depth on top of the controller's
strict-mode entitlement check.

The internal IngressRoute for dist.iamworkin.lan stays unrestricted —
admin POST /blobs + POST /manifests flows keep working from the lab.
This commit is contained in:
Andrew Stoltz
2026-04-23 20:12:25 -05:00
parent c3cc404beb
commit 436185818d

View File

@@ -331,7 +331,12 @@ spec:
entryPoints: entryPoints:
- websecure - websecure
routes: routes:
- match: Host(`dist.flowercore.io`) # Method allowlist: Host + (GET || HEAD). Anything else misses every
# route and Traefik returns 404 before reaching the pod — edge-level
# defense-in-depth over the controller's strict-mode entitlement check.
# Together these block admin ops (POST /blobs, POST /manifests*) from
# ever being processed on the public surface.
- match: Host(`dist.flowercore.io`) && (Method(`GET`) || Method(`HEAD`))
kind: Rule kind: Rule
middlewares: middlewares:
- name: dist-public-profile-header - name: dist-public-profile-header