Skip to content

[WIP] GEP-1619: Define session name conflict resolution rules#4649

Draft
gcs278 wants to merge 4 commits into
kubernetes-sigs:mainfrom
gcs278:gep1619-session-name-clarification
Draft

[WIP] GEP-1619: Define session name conflict resolution rules#4649
gcs278 wants to merge 4 commits into
kubernetes-sigs:mainfrom
gcs278:gep1619-session-name-clarification

Conversation

@gcs278
Copy link
Copy Markdown
Contributor

@gcs278 gcs278 commented Mar 6, 2026

🚧 WIP (Depends on #4870, #4873, #4876).

What type of PR is this?

/kind gep

What this PR does / why we need it:
This PR updates GEP-1619 to define session name conflict resolution rules, resolving ambiguities documented in #4268.

Context: Design Doc

Require unique cookie and header names

Cookie and header names MUST be unique across all session persistence configurations within a Gateway. This includes across route rules, across BackendTrafficPolicies, and between route-level and BackendTrafficPolicy configurations. Within the same xRoute, uniqueness is enforced by CEL validation at admission time. Across xRoutes, the oldest route wins (PartiallyInvalid/UnsupportedValue). Across BackendTrafficPolicies, the oldest policy wins (Accepted: False/Conflicted).

Which issue(s) this PR fixes:

Fixes #4268

Does this PR introduce a user-facing change?:

Cookie and header names are now required to be unique across route rules (enforced by CEL validation).

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. release-note Denotes a PR that will be considered when it comes time to generate release notes. kind/gep PRs related to Gateway Enhancement Proposal(GEP) do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Mar 6, 2026
@k8s-ci-robot k8s-ci-robot requested review from arkodg and youngnick March 6, 2026 22:52
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. labels Mar 6, 2026
@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch 4 times, most recently from 59ca705 to 701ab68 Compare March 11, 2026 01:05
Comment thread geps/gep-1619/index.md
implementations, such as cloud-based global load balancers, don't have the capability to configure the cookie name.

The use case for modifying the cookie name using `SessionName` is that certain users might need to align it with an
**Cookie names MUST be unique** across all session persistence configurations within a Gateway. This includes:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the note about controllers rejecting and setting a PartiallyInvalid status below, but it this something that can/should be checked earlier in a ValidatingAdmissionPolicy? Should this be considered now that we're actually distributing a VAP alongside the Gateway API CRDs?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if we did do that, controllers will still need to check for it, because users could delete that VAP. I probably don't favor auto-including a VAP for that reason, although we could allow it (via a MAY or similar).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming you mean that implementations can implement their own VAP (rather than including it in a standard VAP that we ship). Added a MAY line about this for clarity.

@mikemorris
Copy link
Copy Markdown
Contributor

Looks like a good direction and useful clarifications so far to me!

Comment thread geps/gep-1619/index.md
Comment on lines +860 to +873
Use a single route rule with multiple path matches. The cookie path will be computed as the longest common prefix:

```yaml
rules:
- matches:
- path: /api/upload
- path: /api/download
sessionPersistence:
type: Cookie
cookie:
name: file-session
# Cookie path computed as /api (longest common prefix)
# Result: /api/upload and /api/download share the same session
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a standard way to do this? Any prior art on this kind of thing?

Feels a bit suboptimal that we don't have the computed path shown anywhere, a bit too magical for me.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing some more review: no, I don't think there is prior art for computed cookie path. I did a survey about how existing implementations and dataplanes handle cookie path (prior to GEP-1619), and here's what I found:

Implementation API Cookie Path Source
Istio DestinationRule httpCookie.path User-configured (default: omitted) source (L1487)
Contour HTTPProxy loadBalancerPolicy Hardcoded / source (L717)
HAProxy Ingress Annotations Hardcoded / template (L740); #528 requests it
Traefik IngressRoute sticky.cookie User-configured (default: /) source (L58)
Kong upstream hash_on_cookie_path User-configured (default: /) source (L194)
NGINX (dataplane) sticky cookie path= User-configured (default: omitted) docs
HAProxy (dataplane) cookie directive Hardcoded / docs
Envoy (dataplane) hash_policy cookie.path User-configured (default: omitted) API ref

So this is a good point. We are paving a new path for...path. There are pros and cons to each option:

Computed path: Scopes cookies more precisely, avoids cookie proliferation, but no prior art, can break when edge proxies rewrite the request path (#4713), and is a bit "magical".

Default /: Matches what most implementations already do (5 of 8), predictable, universally implementable, but broader scope than needed.

Computed path is a more elegant solution, but this is one of those complexity tradeoffs and we can re-evaluate.

Not defaulting and requiring an explicit cookieConfig.path field isn't a great option for users who just want to configure the bare minimum. Alternatively, omitting path entirely (letting the browser set it) feels like bad UX because the browser scopes the cookie to the parent path of the request URL, which potentially breaks shared sessions inside a multi-path route rule.

We can also take this conversation to #4713 - it is very relevant there. Thoughts on these options?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for defaulting to /
It would also be helpful to allow an optional cookieConfig.path for explicit configuration.

Comment thread geps/gep-1619/index.md Outdated
Comment on lines +1100 to +1103
This is an invalid configuration. Cookie and header names MUST be unique across all route rules, both within a single
HTTPRoute and across multiple HTTPRoutes serving the same Gateway. If multiple route rules configure session persistence
with the same cookie or header name, implementations MUST reject the configuration and set the route condition to
`PartiallyInvalid`. See [Name](#name) for the rationale behind this requirement.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, we need to explicitly specify these rules. I assume they are something like:

  • Within the same resource, all conflicting rules must be rejected, with the whole Route being rejected if that means there are no valid rules left. Otherwise, a PartiallyInvalid or similar Condition must be set on the Route in reference to that parentref. (I can't remember what the Reason should be, but that should be specified as well).
  • Across multiple resources, conflicting rules mean that the Route with the oldest creation time wins for that rule only. For all other Routes with conflicting rules, those rules must be rejected, and the Routes with conflicting, rejected rules MUST have a PartiallyInvalid Condition added. (This really sucks for implementors, because it means that you have to do per-rule comparisons across the entire Gateway set of attached routes as part of conflict resolution. However, we already specify this for path, so it's not completely unprecedented).

The second one also means that it's possible to have Routes with multiple Rules where some are valid in the older one, and some in the newer one, because the newer one contains non-conflicting rules.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - I see now that saying "just reject" isn't enough.

However, I realize we can check session name uniqueness within the same xRoute via CEL validation (I see precedent for rule name uniqueness is enforced). That's a win-win - removes the foot gun of accidentally breaking two rules by adding a duplicate cookie name, and implementations don't have to handle this special logic at all. Let me know if you know why CEL won't work.

But we can't use CEL across multiple resources, so I will add those details.

Comment thread geps/gep-1619/index.md Outdated
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 21, 2026
Copy link
Copy Markdown
Contributor Author

@gcs278 gcs278 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@youngnick @mikemorris Thank you for the reviews - my apologies for the gap in responses, but I'm allocating more time to getting this moving again.

Changes are here: 1e39b5d

Comment thread geps/gep-1619/index.md
implementations, such as cloud-based global load balancers, don't have the capability to configure the cookie name.

The use case for modifying the cookie name using `SessionName` is that certain users might need to align it with an
**Cookie names MUST be unique** across all session persistence configurations within a Gateway. This includes:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming you mean that implementations can implement their own VAP (rather than including it in a standard VAP that we ship). Added a MAY line about this for clarity.

Comment thread geps/gep-1619/index.md
Comment on lines +860 to +873
Use a single route rule with multiple path matches. The cookie path will be computed as the longest common prefix:

```yaml
rules:
- matches:
- path: /api/upload
- path: /api/download
sessionPersistence:
type: Cookie
cookie:
name: file-session
# Cookie path computed as /api (longest common prefix)
# Result: /api/upload and /api/download share the same session
```
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing some more review: no, I don't think there is prior art for computed cookie path. I did a survey about how existing implementations and dataplanes handle cookie path (prior to GEP-1619), and here's what I found:

Implementation API Cookie Path Source
Istio DestinationRule httpCookie.path User-configured (default: omitted) source (L1487)
Contour HTTPProxy loadBalancerPolicy Hardcoded / source (L717)
HAProxy Ingress Annotations Hardcoded / template (L740); #528 requests it
Traefik IngressRoute sticky.cookie User-configured (default: /) source (L58)
Kong upstream hash_on_cookie_path User-configured (default: /) source (L194)
NGINX (dataplane) sticky cookie path= User-configured (default: omitted) docs
HAProxy (dataplane) cookie directive Hardcoded / docs
Envoy (dataplane) hash_policy cookie.path User-configured (default: omitted) API ref

So this is a good point. We are paving a new path for...path. There are pros and cons to each option:

Computed path: Scopes cookies more precisely, avoids cookie proliferation, but no prior art, can break when edge proxies rewrite the request path (#4713), and is a bit "magical".

Default /: Matches what most implementations already do (5 of 8), predictable, universally implementable, but broader scope than needed.

Computed path is a more elegant solution, but this is one of those complexity tradeoffs and we can re-evaluate.

Not defaulting and requiring an explicit cookieConfig.path field isn't a great option for users who just want to configure the bare minimum. Alternatively, omitting path entirely (letting the browser set it) feels like bad UX because the browser scopes the cookie to the parent path of the request URL, which potentially breaks shared sessions inside a multi-path route rule.

We can also take this conversation to #4713 - it is very relevant there. Thoughts on these options?

Comment thread geps/gep-1619/index.md Outdated
Comment on lines +1100 to +1103
This is an invalid configuration. Cookie and header names MUST be unique across all route rules, both within a single
HTTPRoute and across multiple HTTPRoutes serving the same Gateway. If multiple route rules configure session persistence
with the same cookie or header name, implementations MUST reject the configuration and set the route condition to
`PartiallyInvalid`. See [Name](#name) for the rationale behind this requirement.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - I see now that saying "just reject" isn't enough.

However, I realize we can check session name uniqueness within the same xRoute via CEL validation (I see precedent for rule name uniqueness is enforced). That's a win-win - removes the foot gun of accidentally breaking two rules by adding a duplicate cookie name, and implementations don't have to handle this special logic at all. Let me know if you know why CEL won't work.

But we can't use CEL across multiple resources, so I will add those details.

Comment thread geps/gep-1619/index.md Outdated
@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch from 1e39b5d to 1a3b58f Compare April 21, 2026 19:55
@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 21, 2026
@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch from 1a3b58f to 754a8b0 Compare April 21, 2026 20:36
@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch 2 times, most recently from 353447e to 002a7d0 Compare April 21, 2026 20:46
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Apr 21, 2026
@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch from 002a7d0 to 1f24567 Compare April 21, 2026 20:52
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 21, 2026
@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch from 1f24567 to cf86b00 Compare April 21, 2026 20:53
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 21, 2026
Comment thread apis/v1/httproute_types.go Outdated
// +listType=atomic
// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
// <gateway:experimental:validation:XValidation:message="Session persistence cookie name must be unique across all rules within the route",rule="self.filter(l, has(l.sessionPersistence) && has(l.sessionPersistence.cookie) && has(l.sessionPersistence.cookie.name)).all(l1, self.exists_one(l2, has(l2.sessionPersistence) && has(l2.sessionPersistence.cookie) && has(l2.sessionPersistence.cookie.name) && l1.sessionPersistence.cookie.name == l2.sessionPersistence.cookie.name))">
// <gateway:experimental:validation:XValidation:message="Session persistence header name must be unique across all rules within the route",rule="self.filter(l, has(l.sessionPersistence) && has(l.sessionPersistence.header) && has(l.sessionPersistence.header.name)).all(l1, self.exists_one(l2, has(l2.sessionPersistence) && has(l2.sessionPersistence.header) && has(l2.sessionPersistence.header.name) && l1.sessionPersistence.header.name == l2.sessionPersistence.header.name))">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This uniqueness CEL rule compares header names with ==. should we normalize the headers to avoid mixed-case duplicates?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - good catch - I'll fix on my next round of updates.

Comment thread apis/v1/shared_types.go Outdated
//
// +optional
// +kubebuilder:validation:MaxLength=128
Name *string `json:"name,omitempty"`
Copy link
Copy Markdown
Contributor

@zhaohuabing zhaohuabing Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not sure cookie.name / header.name uniqueness should be a hard MUST across all route rules. This seems to prohibit intentional session sharing between routes, for example two route rules that deliberately use the same cookie or header name so clients keep the same backend affinity across related paths. For cookies, name alone is also not the full browser cookie identity because path/domain affect whether sessions are actually shared.

Would it make sense to soften this to a recommendation, or limit it to cases where duplicate names introduce ambiguity or conflicting behavior, rather than applying it to all duplicates? This would let Gateway users decide how cookies should be shared, without constraining how Routes and RouteRules are structured.

Copy link
Copy Markdown
Contributor

@zhaohuabing zhaohuabing Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#4268 (comment) suggested to use the following for shared session.

kind: HTTPRoute
spec:
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /cart
        - path:
            type: PathPrefix
            value: /checkout
      backendRefs:
        - name: svc-a
          port: 80
      sessionPersistence:
        name: shop-session

However, this may unnecessarily limit the flexibility of how Routes / RouteRules can be constructed. A single rule with multiple matches works when all matched paths have identical routing behavior, but it does not cover some cases, for example, where paths need different rule-level behavior while intentionally sharing stickiness. For example:

kind: HTTPRoute
spec:
  hostnames: ["shop.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /cart
    filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
        set:
        - name: X-Flow
          value: cart
    backendRefs:
    - name: shop-app
      port: 80
    sessionPersistence:
      type: Cookie
      cookie:
        name: shop-session

  - matches:
    - path:
        type: PathPrefix
        value: /checkout
    filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
        set:
        - name: X-Flow
          value: checkout
    backendRefs:
    - name: shop-app
      port: 80
    sessionPersistence:
      type: Cookie
      cookie:
        name: shop-session

Or where different HTTPRoutes are needed for separate policy attachment.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-public
spec:
  hostnames: ["shop.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /products
    backendRefs:
    - name: shop-app
      port: 80
    sessionPersistence:
      type: Cookie
      cookie:
        name: shop-session
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-account
spec:
  hostnames: ["shop.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /account
    backendRefs:
    - name: shop-app
      port: 80
    sessionPersistence:
      type: Cookie
      cookie:
        name: shop-session
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: account-oidc
spec:
  targetRef:
    kind: HTTPRoute
    name: shop-account
  oidc:
    provider:
      issuer: https://idp.example.com/realms/shop
    clientID: shop-web
    clientSecret:
      name: shop-oidc-client-secret

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the cookie tuple is (name, domain, path). I agree that enforcing unique session names limits the ability to share sessions for route-inline session persistence.

For softening, I suppose you are suggesting that we allow duplicate session names for route rules that:

  1. Target the same service
  2. Have the same session persistence configuration

If you don't target the same service (# 1), then you have a collision with potential breakage (encoded pod IP is not common between services). If you don't have the same configuration (# 2), then you get a thrashing cookie configuration (set-cookies fighting).

It's valid - but the tradeoff is:

  1. It feels a bit magical with implicit behavior - applying two same name sessions shares them
  2. Complexity increase for implemenations that have to compare API configurations for conflicts.

Alternatively, I suppose we could go hands off - and don't do any validation. That'd be the most simple for implementation, while allowing sharing. The tradeoff there, is that users now have foot guns for setting conflicting configuration.

For context - originally, I designed the uniqueness requirement with the assumption that session sharing would be handled by BackendTrafficPolicy, where it works naturally without nearly as much collision concerns (sharing sessions across services doesn't make as much sense like sharing across routes to the same service). However, supporting both attachment points simultaneously in the API is becoming hard to justify.

There's a broader discussion about this in #4462 - would love your input there if you get a chance. If BackendTrafficPolicy is the right end solution - then our debates on conflicts get much simpler.

Did I capture your suggestion correctly?

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 22, 2026
Copy link
Copy Markdown
Contributor Author

@gcs278 gcs278 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhaohuabing thanks for the comments, really appreciated! Feel free to keep the discussion going - I'm going to hold on any major changes until I get more input from the community on the direction we are taking.

Comment thread apis/v1/shared_types.go Outdated
//
// +optional
// +kubebuilder:validation:MaxLength=128
Name *string `json:"name,omitempty"`
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the cookie tuple is (name, domain, path). I agree that enforcing unique session names limits the ability to share sessions for route-inline session persistence.

For softening, I suppose you are suggesting that we allow duplicate session names for route rules that:

  1. Target the same service
  2. Have the same session persistence configuration

If you don't target the same service (# 1), then you have a collision with potential breakage (encoded pod IP is not common between services). If you don't have the same configuration (# 2), then you get a thrashing cookie configuration (set-cookies fighting).

It's valid - but the tradeoff is:

  1. It feels a bit magical with implicit behavior - applying two same name sessions shares them
  2. Complexity increase for implemenations that have to compare API configurations for conflicts.

Alternatively, I suppose we could go hands off - and don't do any validation. That'd be the most simple for implementation, while allowing sharing. The tradeoff there, is that users now have foot guns for setting conflicting configuration.

For context - originally, I designed the uniqueness requirement with the assumption that session sharing would be handled by BackendTrafficPolicy, where it works naturally without nearly as much collision concerns (sharing sessions across services doesn't make as much sense like sharing across routes to the same service). However, supporting both attachment points simultaneously in the API is becoming hard to justify.

There's a broader discussion about this in #4462 - would love your input there if you get a chance. If BackendTrafficPolicy is the right end solution - then our debates on conflicts get much simpler.

Did I capture your suggestion correctly?

Comment thread apis/v1/httproute_types.go Outdated
// +listType=atomic
// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
// <gateway:experimental:validation:XValidation:message="Session persistence cookie name must be unique across all rules within the route",rule="self.filter(l, has(l.sessionPersistence) && has(l.sessionPersistence.cookie) && has(l.sessionPersistence.cookie.name)).all(l1, self.exists_one(l2, has(l2.sessionPersistence) && has(l2.sessionPersistence.cookie) && has(l2.sessionPersistence.cookie.name) && l1.sessionPersistence.cookie.name == l2.sessionPersistence.cookie.name))">
// <gateway:experimental:validation:XValidation:message="Session persistence header name must be unique across all rules within the route",rule="self.filter(l, has(l.sessionPersistence) && has(l.sessionPersistence.header) && has(l.sessionPersistence.header.name)).all(l1, self.exists_one(l2, has(l2.sessionPersistence) && has(l2.sessionPersistence.header) && has(l2.sessionPersistence.header.name) && l1.sessionPersistence.header.name == l2.sessionPersistence.header.name))">
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - good catch - I'll fix on my next round of updates.

@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch from cf86b00 to f34055d Compare April 24, 2026 21:22
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 24, 2026
@zhaohuabing
Copy link
Copy Markdown
Contributor

zhaohuabing commented Apr 27, 2026

For context - originally, I designed the uniqueness requirement with the assumption that session sharing would be handled by BackendTrafficPolicy, where it works naturally without nearly as much collision concerns (sharing sessions across services doesn't make as much sense like sharing across routes to the same service). However, supporting both attachment points simultaneously in the API is becoming hard to justify.

If we clarify that sessionPersistence.cookie is meant to be used per route, and BackendTrafficPolicy should be used for session sharing, then requiring session name uniqueness across all routes sounds reasonable to me.

@zhaohuabing
Copy link
Copy Markdown
Contributor

Hi @gcs278, just checking in — is there anything blocking this PR?

We’re hoping the default cookie path / in this PR can help unblock the edge proxy rewrite use case in Envoy Gateway.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 13, 2026
@gcs278
Copy link
Copy Markdown
Contributor Author

gcs278 commented May 13, 2026

Hey @zhaohuabing - yea recently there has been discussions about Backend (#4488) - which is being considered as an alternative to policy attachment. I was waiting for those discussions to finalize before making too many more modifications to this GEP.

It sounds like there's general agreement on Session Persistence going experimental in Backend and also agreement that it shouldn't live in multiple places (e.g. route inline, backend, and BackendTrafficPolicy). I'm going to try to finalize the direction on that soon. I'll be advocating for Backend, but I need to discuss with the implementations that already shipped it as experimental in route-inline first.

I'm planning to refactor this draft GEP soon - slim it down and address only a couple things at a time. Stay tuned.

gcs278 added 4 commits May 18, 2026 09:55
Cookie and header names must be unique across all route rules.
Implementations must reject duplicates with PartiallyInvalid condition.
Adds rationale and examples.
Add CEL validation for session name uniqueness within xRoutes, specify conflict
resolution rules and status conditions for cross-resource conflicts.
Header names are case-insensitive per RFC 7230. Use lowerAscii() in the
CEL validation to catch mixed-case duplicates. Cookie names remain
case-sensitive per RFC 6265.
@gcs278 gcs278 force-pushed the gep1619-session-name-clarification branch from c06a348 to 20209a3 Compare May 18, 2026 13:55
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels May 18, 2026
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: gcs278
Once this PR has been reviewed and has the lgtm label, please assign danwinship for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@gcs278 gcs278 changed the title [WIP] GEP-1619: Session Name Refactoring and Behavior Clarification [WIP] GEP-1619: Define session name conflict resolution rules May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. kind/gep PRs related to Gateway Enhancement Proposal(GEP) release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clarify sessionPersistence scoping and conflict resolution across HTTPRoutes and Backends

5 participants