gateway-api icon indicating copy to clipboard operation
gateway-api copied to clipboard

CEL Validation: HTTPRoute Case-Insensitive Header Name Uniqueness

Open robscott opened this issue 2 years ago • 9 comments

What happened: Unfortunately CEL is not currently capable of validating the case-insensitive uniqueness of header names in header modifier filters. This is the only standard channel validation we are still reliant on the validating webhook for. @gauravkghildiyal already developed a CEL rule for this:

// +kubebuilder:validation:XValidation:message="Must not match the same header (case-insensitive) multiple times in the same rule",rule="self.all(h1, self.exists_one(h2, h1.name.lowerAscii() == h2.name.lowerAscii()))"

Unfortunately there is a problem with CEL cost estimation that prevents this https://github.com/kubernetes/kubernetes/issues/119749, @jpbetz is working on a fix for this.

Anything else we need to know?: Given the Gateway API versioning policy to support the 5 latest minor Kubernetes versions, even when this is fixed upstream, it's going to be a long time before we can adopt this.

/lifecycle frozen

robscott avatar Aug 08 '23 20:08 robscott

/cc

gauravkghildiyal avatar Aug 08 '23 21:08 gauravkghildiyal

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle stale
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

k8s-triage-robot avatar May 12 '25 18:05 k8s-triage-robot

This should definitely be frozen, as it is blocked by upstream.

/remove-lifecycle stale /lifecycle frozen

youngnick avatar May 13 '25 04:05 youngnick

As the issue on k/k is closed, should we move with the validation here?

@snorwin as you have recently worked on header validations

rikatz avatar Nov 27 '25 18:11 rikatz

/assign @snorwin

snorwin avatar Nov 28 '25 14:11 snorwin

Unfortunately, the cost-estimation issue related to lowerAscii did not resolve the issue we are facing here. Due to the high level of nesting, even without lowerAscii the validation exceeds the budget by a factor of more than 100.

snorwin avatar Dec 02 '25 08:12 snorwin

/unassign @snorwin

snorwin avatar Dec 02 '25 08:12 snorwin

@snorwin I am doing the tests here

When you say the costs exceeds 100, can you give me some example on reproducing it? IIUC the problem is like, having multiple headers here will exponentially grow the cost, right?

rikatz avatar Dec 02 '25 13:12 rikatz

@rikatz I tested with:

// +kubebuilder:validation:XValidation:message="Must not match the same header (case-insensitive) multiple times in the same rule",rule="self.all(h1, self.exists_one(h2, h1.name.lowerAscii() == h2.name.lowerAscii()))"

The actual issue isn’t the expression itself but the combinatorial explosion caused by the nesting:

  • 16 (rules) x 16 (filters) x 16 x 16 (headers) x 3 (set/add/delete)
  • 16 (rules) x 16 (backend refs) x 16 (filters) x 16 x 16 (headers) x 3 (set/add/delete)

snorwin avatar Dec 02 '25 14:12 snorwin