-
Notifications
You must be signed in to change notification settings - Fork 140
Design for session persistence - Part II #4221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4221 +/- ##
==========================================
+ Coverage 86.01% 86.05% +0.03%
==========================================
Files 131 131
Lines 14111 14142 +31
Branches 35 35
==========================================
+ Hits 12138 12170 +32
+ Misses 1771 1770 -1
Partials 202 202 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| For **HTTPRoutes**, we do not set the `domain` attribute. Deriving a broader domain (for example, a common suffix across hostnames or a parent domain) would widen the cookie scope to sibling subdomains and increase the risk of cross-host leakage. Since users cannot explicitly configure this field, inferring a shared domain would also be vulnerable to abuse. Leaving domain unset ensures each cookie is scoped to the exact host that issued it. | ||
|
|
||
| To determine the cookie `path` for HTTPRoutes, we handle the simple case where there is a single path match as follows: | ||
|
|
||
| | Path Value | Path Match Type | Cookie `Path` Value | Cookie Match Expectations | | ||
| |-------------------------------------|-----------------|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| | `/hello-exact` | Exact | `/hello-exact` | Cookie header is sent for `/hello-exact` path only. | | ||
| | `/hello-prefix` | Prefix | `/hello-prefix` | Cookie header is sent for `/hello-prefix` and any subpath starting with `/hello-prefix` (e.g. `/hello-prefix/foo`). | | ||
| | `/hello-regex/[a-zA-Z0-9_-]+$` | Regex | `/hello-regex` | Cookie header is sent for any request whose path starts with `/hello-regex` and matches the regex in the location block (e.g. `/hello-regex/a`, `/hello-regex/abc123`). The regex still determines which requests match the route on the server side. | | ||
|
|
||
| When there are multiple path matches that share the same sessionPersistence configuration, we derive a single cookie path by computing the longest common prefix that ends on a path-segment boundary `/`. If no non-empty common prefix on a segment boundary exists, we fall back to `/` which is allowing all paths. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a reasonable first approach for HTTPRoute path handling, but if it’s viewed as over derived then, I’m also comfortable simplifying it to rely on the default cookie path behavior (i.e., not computing a path on the NGF side at all).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be sure to fill out the security/testing/use case sections as provided in the proposal template.
| # Enhancement Proposal-4051: Session Persistence for NGINX Plus and OSS | ||
|
|
||
| - Issue: https://github.com/nginx/nginx-gateway-fabric/issues/4051 | ||
| - Status: Provisional |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be updated to Implementable.
| ) | ||
| ``` | ||
|
|
||
| Note: `LoadBalancingMethod` is optional and defaults to `random two least_conn`. Adding this optional field is a non-breaking change and does not require a version bump in alignment with the [Kubernetes API compatibility guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md#on-compatibility). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's be clear that NGF sets this default, but NGINX's default is technically round robin (empty value)
| | no matching spec field | `secure` | Enabled by default for all routes. | | ||
| | no matching spec field | `httpOnly` | Enabled by default for all routes. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I like the idea of these being on by default, I'm trying to think of the future implications. If these fields get added to the API spec, then in theory they're going to be disabled by default there. Which means our default behavior is going to change...and that's a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s a fair concern. I wasn’t trying to predefine how secure / httpOnly should behave in the Gateway API, just to harden the default cookie behavior in NGF. But you’re right: if the spec later adds those fields with different defaults, we could box ourselves in.
I’ll update the design to:
- remove secure and httpOnly from the mapping table (so we’re not implying any API-level fields today), and
- call out separately that NGF currently sets
secureandhttpOnlyon the session cookie as an implementation detail, not something controlled by the sessionPersistence spec.
If the community later adds secure / httpOnly fields, we can keep the current behavior when they’re unset (flags stay on by default) and only change behavior when users set them explicitly. That preserves today’s defaults, while still letting users opt out if they really need to.
I do think there’s real security value in having these enabled by default, given the usual session-token hijack and XSS concerns, especially since this directly influences which backend handles the session atleast users will opt into a using a less secure versions themselves
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the community later adds secure / httpOnly fields, we can keep the current behavior when they’re unset (flags stay on by default) and only change behavior when users set them explicitly
The risk here is that if the API adds these fields and says that their default behavior is "off", then our default behavior doesn't fit that contract. NGINX also defaults these to off.
Another option is set them to on, with the caveat and documentation that this is an experimental API that could evolve and these default values could change. If that ever happens in the future, we would need upgrade docs to help users through that to ensure the new behavior doesn't break them.
The other question I have is that by defaulting them to "on", are we going to prevent any functionality for some users? This is an issue because they can't change the spec until the API exists for it.
Proposed changes
Write a clear and concise description that helps reviewers understand the purpose and impact of your changes. Use the
following format:
Problem: Users want sessionPersistence for their server communication
Solution: Add a detailed approach on how to support sessionPersistence for NGF while being community conformant.
Testing: Did a couple of manual checks
Please focus on (optional): If you any specific areas where you would like reviewers to focus their attention or provide
specific feedback, add them here.
Closes #4051
Checklist
Before creating a PR, run through this checklist and mark each as complete.
Release notes
If this PR introduces a change that affects users and needs to be mentioned in the release notes,
please add a brief note that summarizes the change.