Skip to content

fix: prevent GatewayNamespace mode from hijacking pre-existing ServiceAccounts and ConfigMaps#9215

Merged
zirain merged 26 commits into
envoyproxy:mainfrom
yuehaii:GatewayNamespace-mode
Jul 3, 2026
Merged

fix: prevent GatewayNamespace mode from hijacking pre-existing ServiceAccounts and ConfigMaps#9215
zirain merged 26 commits into
envoyproxy:mainfrom
yuehaii:GatewayNamespace-mode

Conversation

@yuehaii

@yuehaii yuehaii commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?
fix: prevent GatewayNamespace mode from hijacking pre-existing ServiceAccounts and ConfigMaps

What this PR does / why we need it:
In GatewayNamespace mode, when a Gateway is created, Envoy Gateway provisions a ServiceAccount and ConfigMap in the same namespace as the Gateway, using the Gateway's own name as the resource name.

If a resource with that name already existed in the namespace, the reconciler would silently overwrite it via ServerSideApply with client.ForceOwnership, stealing field ownership and injecting a new ownerReference pointing to the Gateway object. When the Gateway was later deleted, Kubernetes garbage collection followed the ownerReference and deleted the pre-existing resource, causing unrelated components to break.

Fixes #9136

Release Notes: Yes

@yuehaii yuehaii requested a review from a team as a code owner June 12, 2026 04:24
@netlify

netlify Bot commented Jun 12, 2026

Copy link
Copy Markdown

Deploy Preview for cerulean-figolla-1f9435 ready!

Name Link
🔨 Latest commit 70c996d
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/6a4777416246eb00080b3ee0
😎 Deploy Preview https://deploy-preview-9215--cerulean-figolla-1f9435.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4486073b16

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread internal/infrastructure/kubernetes/infra_resource.go Outdated
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.47826% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.38%. Comparing base (2af650c) to head (70c996d).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ternal/infrastructure/kubernetes/infra_resource.go 93.47% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9215      +/-   ##
==========================================
+ Coverage   75.34%   75.38%   +0.04%     
==========================================
  Files         252      252              
  Lines       41434    41471      +37     
==========================================
+ Hits        31218    31263      +45     
+ Misses       8104     8098       -6     
+ Partials     2112     2110       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zirain

zirain commented Jun 12, 2026

Copy link
Copy Markdown
Member

Can you check the failed e2e test?

yuehaii added 4 commits June 15, 2026 09:30
…pre-existing and user-managed. we must not block the apply or add an ownerReference to it.

Signed-off-by: hai.yue <[email protected]>
Signed-off-by: hai.yue <[email protected]>
@yuehaii yuehaii force-pushed the GatewayNamespace-mode branch from 18d0712 to 8a319e5 Compare June 15, 2026 01:35
@yuehaii

yuehaii commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

hi @zirain , good morning. I have fixed the failed test cases. Could you please approve those workflows for verification?

@zirain

zirain commented Jun 15, 2026

Copy link
Copy Markdown
Member

can you add e2e and release notes for this?

@yuehaii

yuehaii commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

can you add e2e and release notes for this?

sure. I will add e2e test cases and release notes.

@yuehaii

yuehaii commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

those e2e test failure have no relation with current fix for cm/sa ownership. I will retest the failure cases.

  1. this looks like tls connection timeout
    https://github.com/envoyproxy/gateway/actions/runs/27931778280/job/82646242313?pr=9215#step:7:6075
    listenerset_client_traffic_policy.go:90:
    Error Trace: /home/runner/work/gateway/gateway/test/e2e/tests/listenerset_client_traffic_policy.go:90
    /home/runner/work/gateway/gateway/test/e2e/timing.go:102
    /home/runner/go/pkg/mod/sigs.k8s.io/gateway-api/[email protected]/utils/suite/conformance.go:77
    /home/runner/go/pkg/mod/sigs.k8s.io/gateway-api/[email protected]/utils/suite/suite.go:511
    Error: Condition never satisfied
    Test: TestE2E/ListenerSetClientTrafficPolicy

  2. this e2e test caused by timeout connecting to server.

https://github.com/envoyproxy/gateway/actions/runs/27931778280/job/82646242315?pr=9215#step:7:10628
--- FAIL: TestEGUpgrade (80.85s)
--- FAIL: TestEGUpgrade/EnvoyShutdown (78.20s)
--- FAIL: TestEGUpgrade/EnvoyShutdown/All_requests_(regular_+_delayed)_must_succeed_during_rollout (78.19s)
{"ts":1782109091.807551,"level":"err","r":278,"file":"http_client.go","line":961,"msg":"Unable to connect","dest":{"IP":"172.18.0.205","Port":80,"Zone":""},"err":"dial tcp 172.18.0.205:80: i/o timeout","numfd":108,"thread":39,"run":0}

@yuehaii

yuehaii commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

hi @zirain , good day. I have added the e2e test case and release note. please help review the pr when it is convenient. thanks.

@zirain

zirain commented Jun 23, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec3265bdf1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +737 to +740
err := i.Client.Get(ctx, types.NamespacedName{Name: obj.GetName(), Namespace: obj.GetNamespace()}, existing)
if err != nil {
if apierrors.IsNotFound(err) {
return nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use a live read for ownership checks

This ownership guard is using the infrastructure client's normal Get, and the Kubernetes provider wires that client from mgr.GetClient() (internal/provider/kubernetes/kubernetes.go:402-405), so reads for cached types such as ServiceAccounts and ConfigMaps can be stale. If a tenant creates the colliding ServiceAccount/ConfigMap shortly before creating the Gateway, for example in the same apply, the Gateway reconcile can hit this IsNotFound path before the cache observes the pre-existing object and still proceed to server-side apply with force ownership, reintroducing the hijack this change is meant to prevent. Use an uncached/APIReader-style live read for this conflict check before applying.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

souds reasonable.

@zhaohuabing zhaohuabing Jun 24, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this might be acceptable as this edge case is very rare and unlikely happens in production.

a tenant creates the colliding ServiceAccount/ConfigMap shortly before creating the Gateway, for example in the same apply, the Gateway reconcile can hit this IsNotFound path before the cache observes the pre-existing object and still proceed to server-side apply with force ownership

@zhaohuabing zhaohuabing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need to also apply the same check to other resources(Deployment, DaemonSet, optional PDB, optional HPA, and Service)?

Comment thread internal/infrastructure/kubernetes/infra_resource.go Outdated
@yuehaii

yuehaii commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Do we need to also apply the same check to other resources(Deployment, DaemonSet, optional PDB, optional HPA, and Service)?

the name collision is possible for those resources. there might be rare cases having a pre-existing same name for those resources in the same namespace.

please let me know if you want me to implement similar fix for Deployment, DaemonSet, PDB, HPA, and Service.

@zhaohuabing

Copy link
Copy Markdown
Member

there might be rare cases having a pre-existing same name for those resources in the same namespace.

I’d prefer to handle all resources the same way for consistency and maintainability.

@cnvergence

cnvergence commented Jun 25, 2026

Copy link
Copy Markdown
Member

Seems like we got these resource names as gateway names in #6135.
I was thinking if we could just restore it for name collisions?
We would still need to create these resources in this case, and this issue happens only when we set the gateway name to the same as the resources already existing.

@yuehaii

yuehaii commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Seems like we got these resource names as gateway names in #6135. I was thinking if we could just restore it for name collisions? We would still need to create these resources in this case, and this issue happens only when we set the gateway name to the same as the resources already existing.

the name collisions should be carefully considered previously: "since its more intuitive for end users as well as safe to do (no collisions)".
for issue #9136, it looks more like test scenario for rare cases. we may only need to prevent such hijacking behavior in such condition.

@zhaohuabing

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6237ba9ee5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/infrastructure/kubernetes/infra_resource.go Outdated
@zhaohuabing

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 72217c06a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/infrastructure/kubernetes/infra_resource.go Outdated

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Comment thread internal/infrastructure/kubernetes/infra_resource.go
Comment thread internal/infrastructure/kubernetes/infra_resource_test.go Outdated
Comment thread test/e2e/tests/gateway_namespace_ownership.go
Comment thread test/e2e/tests/gateway_namespace_ownership.go
Comment thread internal/envoygateway/config/config.go Outdated
Comment thread internal/infrastructure/kubernetes/infra_resource.go Outdated
Comment thread internal/infrastructure/kubernetes/infra_resource.go Outdated
@yuehaii

yuehaii commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

hi @zhaohuabing , good day. I have solved the issues. could you please review the changes when it is convenient. thanks.

@zhaohuabing

zhaohuabing commented Jul 3, 2026

Copy link
Copy Markdown
Member

this gate was added to fix the #9215 (comment) when GatewayNamespaceMode and RateLimit are both enabled. @zhaohuabing , please help double check.

Thanks for the explanation. Could we make this clearer by using a method like isRatelimit() and adding some comment to explain this behavior for better maintenance?

@zhaohuabing zhaohuabing added this to the v1.9.0-rc.1 Release milestone Jul 3, 2026
// noGatewayIdentityLabels reports whether labels carry none of the three
// gateway ownership identity labels. Resources in GatewayNamespace mode
// with no identity labels (such as ratelimit resources) are controller-scoped
// and need no collision guard.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we need collision guard for all EG created resources - but it's not blocking for this PR.

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.

if needed, I can replace

if !i.EnvoyGateway.GatewayNamespaceMode() || noGatewayIdentityLabels(obj.GetLabels()) {

with

if !i.EnvoyGateway.GatewayNamespaceMode() || obj.GetNamespace() == i.ControllerNamespace

@zhaohuabing zhaohuabing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM thanks!

@yuehaii

yuehaii commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

/retest

Comment on lines 130 to +140
# custom sa for gateway namespace mode
apiVersion: v1
automountServiceAccountToken: false
kind: ServiceAccount
metadata:
name: custom-sa
namespace: gateway-conformance-infra
labels:
app.kubernetes.io/managed-by: envoy-gateway
gateway.envoyproxy.io/owning-gateway-namespace: gateway-conformance-infra
gateway.envoyproxy.io/owning-gateway-name: eg-deployment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I cannot recall why this's put here, but it should be fine to remove this directly.

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.

it is added to fix the "TestE2E/EnvoyProxyCustomName" and "TestE2E/EnvoyProxyCustomName/Deployment" test cases failure. please refer this thread.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could remove the SA entirely, let's give a try later.

@zirain zirain merged commit dc73f48 into envoyproxy:main Jul 3, 2026
59 of 65 checks passed
@yuehaii yuehaii deleted the GatewayNamespace-mode branch July 4, 2026 08:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When using the GatewayNamespace mode, it will overwrite the service account or ConfigMap with the same name in the same namespace.

6 participants