Skip to content

feat(translator): Security policies for TLS gateways - #9464

Open
asHasnain wants to merge 12 commits into
envoyproxy:mainfrom
asHasnain:security-policy-for-tls-gateways
Open

asHasnain wants to merge 12 commits into
envoyproxy:mainfrom
asHasnain:security-policy-for-tls-gateways

Conversation

@asHasnain

@asHasnain asHasnain commented Jul 9, 2026 •

Copy link
Copy Markdown

What this PR does / why we need it:
Adds SecurityPolicy support for TLSRoute with client IP-based authorization. Currently, SecurityPolicies support Gateway, HTTPRoute, GRPCRoute, and TCPRoute, but not TLSRoute. This PR extends authorization support to TLSRoute (passthrough mode), allowing users to apply client IP allow/deny lists using SecurityPolicy.

Which issue(s) this PR fixes:

Fixes #6704


PR Checklist

  • Authorship & ownership: Coding agents / AI assistants are welcome, but I have reviewed every change, understand how and why it works, can explain and maintain it, and take full responsibility for this PR. I have not submitted generated output I do not understand.
  • DCO: All commits are signed off (git commit -s). See DCO: Sign your work.
  • API agreed first: If this PR contains API changes (changes under /api), the API was discussed and agreed before the implementation. The API change can be in a separate PR, or in the same PR, but the API must be agreed before implementation. N/A if this PR does not contain API changes.
  • Required checks pass: make generate gen-check, make lint, and the unit-test/coverage build pass. (Flaky e2e failures are not considered breakages, but gen-check, lint, and coverage MUST pass.)
  • Tests added/updated: New/changed code is covered by appropriate tests. N/A if this PR does not contain code changes.
  • Docs: User-facing changes update the docs, either in this PR or a follow-up PR. N/A if this PR does not contain user-facing changes.
  • Release notes: For any non-trivial change, added a release-note fragment under release-notes/current/<section>/<pr-number>-<slug>.md (see release-notes/current/README.md for sections and naming). N/A if this PR does not contain non-trivial changes.
  • Generated files committed: Ran make gen-check and committed the result if API/helm charts/modules changed.
  • Scope & compatibility: The PR is reasonably scoped (no unrelated changes) and preserves backward compatibility, or any breaking change is called out above and documented in release-notes/current/breaking_changes/.
  • Codex review: Requested a Codex review and addressed all of its comments.
  • Copilot review: Requested a Copilot review and addressed all of its comments.

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
@asHasnain
asHasnain requested a review from a team as a code owner July 9, 2026 18:41
@netlify

netlify Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for cerulean-figolla-1f9435 ready!

Name Link
🔨 Latest commit 429a9db
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/6abb1e33762d8b0008b399b9
😎 Deploy Preview https://deploy-preview-9464--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: 0677eca60e

ℹ️ 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/provider/kubernetes/controller_test.go Outdated
Comment thread internal/gatewayapi/securitypolicy.go
…-tls-gateways

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>

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

This PR extends SecurityPolicy client-IP CIDR authorization support to TLSRoute (TLS passthrough), updating API validation/CRDs, translator logic, and adding conformance coverage.

Changes:

  • Allow SecurityPolicy.spec.targetRef(s).kind: TLSRoute via API/CEL validations and regenerated CRDs/helm outputs.
  • Apply TCP-style (CIDR-only) authorization validation/translation to TLSRoute in internal/gatewayapi/securitypolicy.go, with new xDS-IR golden testdata.
  • Add an e2e conformance test and manifests covering allow/deny-by-client-IP on TLSRoute passthrough.

Required fixes (highest severity first):

  • Update CEL validation tests for the API error-message change: api/v1alpha1/securitypolicy_types.go:49-52 now includes /TLSRoute in validation messages, but test/cel-validation/securitypolicy_test.go still asserts the old message text (will break CEL validation test expectations).
  • E2E assertion correctness: test/e2e/tests/tlsroute_authorization_client_ip.go:147-151 currently treats an empty response as success for the “allowed” path, which can mask upstream connectivity failures.
  • Error-message consistency: internal/gatewayapi/securitypolicy.go’s TCP/TLS validator should keep error strings consistently saying “TCP/TLS” (not “TCP”).

Release note risk:

  • This is a user-facing feature addition; a release-note fragment under release-notes/current/ appears to be missing.

Reviewed changes

Copilot reviewed 12 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml Regenerated CRD output reflecting TLSRoute as an allowed SecurityPolicy target kind.
test/helm/gateway-crds-helm/e2e.out.yaml Regenerated CRD output for e2e chart bundle reflecting TLSRoute validation changes.
test/helm/gateway-crds-helm/all.out.yaml Regenerated aggregate CRD output reflecting TLSRoute validation changes.
test/e2e/tests/tlsroute_authorization_client_ip.go Adds TLSRoute passthrough e2e conformance test for client-IP allow/deny authorization.
test/e2e/testdata/tlsroute-authorization-client-ip.yaml Adds Gateway/TLSRoute/SecurityPolicy manifests used by the new e2e test.
site/content/en/latest/api/extension_types.md Updates API docs to state SecurityPolicy can target TLSRoute and clarifies CIDR-only behavior.
internal/xds/translator/testdata/out/xds-ir/tls-route-authorization.routes.yaml New xDS-IR golden (routes) for TLSRoute authorization scenario.
internal/xds/translator/testdata/out/xds-ir/tls-route-authorization.listeners.yaml New xDS-IR golden (listeners) verifying RBAC + tcp_proxy wiring for SNI-based chains.
internal/xds/translator/testdata/out/xds-ir/tls-route-authorization.endpoints.yaml New xDS-IR golden (endpoints) for the TLSRoute authorization scenario.
internal/xds/translator/testdata/out/xds-ir/tls-route-authorization.clusters.yaml New xDS-IR golden (clusters) for the TLSRoute authorization scenario.
internal/xds/translator/testdata/in/xds-ir/tls-route-authorization.yaml New xDS-IR input fixture representing TLSRoute routes with authorization rules.
internal/provider/kubernetes/controller_test.go Updates controller test expectations to include SecurityPolicy reference grants for TLSRoute.
internal/gatewayapi/testdata/securitypolicy-with-merge-tcp-invalid.out.yaml Updates expected status message text to “TCP/TLS” wording.
internal/gatewayapi/securitypolicy.go Extends SecurityPolicy route processing/validation/translation to handle TLSRoute like TCPRoute (CIDR-only).
internal/gatewayapi/securitypolicy_test.go Switches unit test to call the renamed TCP/TLS validator.
charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml Regenerated CRD manifest enabling TLSRoute in SecurityPolicy target kind validation.
charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml Regenerated CRD template enabling TLSRoute in SecurityPolicy target kind validation.
api/v1alpha1/securitypolicy_types.go API docs + CEL validations updated to allow TLSRoute targets and mergeType use with TLSRoute.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/gatewayapi/securitypolicy.go
Comment thread api/v1alpha1/securitypolicy_types.go
Comment thread test/e2e/tests/tlsroute_authorization_client_ip.go

@guydc guydc 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.

Thanks @asHasnain for picking this up, it's a useful enhancement of security policy for additional TCP/TLS Scenerios.

Can we add some yaml tests in the GW-API layer covering translation of more complex scenarios like multiple rules in a single TLS route and multiple TLS routes in a listener?
TCP routes usually have a simpler xds shape than TLS routes, so I just want to make sure that reusing the existing translation of security policy for TCP covers all cases.

Comment thread api/v1alpha1/securitypolicy_types.go
Comment thread test/e2e/tests/tlsroute_passthrough_authorization_client_ip.go
@arkodg arkodg added this to the v1.9.0-rc.1 Release milestone Jul 11, 2026
Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
@asHasnain
asHasnain force-pushed the security-policy-for-tls-gateways branch from 94cabf1 to 0c9e464 Compare July 14, 2026 12:42

@asHasnain asHasnain left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks @guydc for reviewing. I've added tests for the specified scenarios.

Comment thread test/e2e/tests/tlsroute_passthrough_authorization_client_ip.go
Comment thread api/v1alpha1/securitypolicy_types.go
Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
@guydc

guydc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

cc @zhaohuabing

@codecov

codecov Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.43%. Comparing base (f1f4888) to head (429a9db).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9464      +/-   ##
==========================================
+ Coverage   81.41%   81.43%   +0.01%     
==========================================
  Files         266      266              
  Lines       41300    41306       +6     
==========================================
+ Hits        33626    33639      +13     
+ Misses       7673     7666       -7     
  Partials        1        1              

☔ 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.

@zhaohuabing

Copy link
Copy Markdown
Member

Hi @asHasnain TestE2E/TLSRouteAuthzWithClientIP/allowed_client_IP_can_connect_to_allowed.example.co is failing. Could you please fix it?

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
…-tls-gateways

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
@asHasnain

asHasnain commented Aug 6, 2026 •

Copy link
Copy Markdown
Author

Hi @asHasnain TestE2E/TLSRouteAuthzWithClientIP/allowed_client_IP_can_connect_to_allowed.example.co is failing. Could you please fix it?

Sorry, I was on vacation so could not get back earlier.

The test passed locally for me:

=== RUN   TestE2E/TLSRouteAuthzWithClientIP/blocked_client_IP_cannot_connect_to_blocked.example.com
    tlsroute_authorization_client_ip.go:87: Connection blocked as expected: EOF
    tlsroute_authorization_client_ip.go:191: RBAC filter denied 1 connections (confirmed via Prometheus)
=== RUN   TestE2E/TLSRouteAuthzWithClientIP/allowed_client_IP_can_connect_to_allowed.example.com
    tlsroute_authorization_client_ip.go:160: Successfully received response: HTTP/1.1 200 OK
        Content-Type: application/json
        X-Content-Type-Options: nosniff
        Date: Thu, 16 Jul 2026 18:24:12 GMT
        Content-Length: 439
        
        {
         "path": "/",
         "host": "allowed.example.com",
         "method": "GET",
         "proto": "HTTP/1.1",
         "headers": {
          "Accept": [
           "*/*"
          ],
          "User-Agent": [
           "test-client"
          ]
         },
         "httpPort": "3000",
         "namespace": "gateway-conformance-infra",
         "ingress": "",
         "service": "tls-backend",
         "pod": "tls-backend-5d64b6c68b-5zxdh",
         "tls": {
          "version": "TLSv1.3",
          "serverName": "allowed.example.com",
          "cipherSuite": "TLS_AES_128_GCM_SHA256"
         }
        }
    tlsroute_authorization_client_ip.go:189: RBAC filter allowed 1 connections (confirmed via Prometheus)
=== NAME  TestE2E/TLSRouteAuthzWithClientIP
    timing.go:87: 2026-07-16T20:24:12.573236+02:00: Test TLSRouteAuthzWithClientIP completed in 72ms

However, the pipeline failure might be related to the short RBAC metrics scraping timeout (10s) in the test. I've increased timeout to 1m (like another test). For verification, I checked the envoy proxy pod stats and it showed that the RBAC metric values were correctly updated:

tls-passthrough-8443.rbac.allowed: 4
tls-passthrough-8443.rbac.denied: 4
tls-passthrough-8443.rbac.shadow_allowed: 0
tls-passthrough-8443.rbac.shadow_denied: 0

The stats in Prometheus format (/stats/prometheus) did not show namespace so I've removed it from RBAC metrics query.
stats_2026-08-05.txt
e2e_test_output_2026-08-05.txt
e2e_test_output_2026-07-16.txt

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale because it has not had activity in the last 30 days. Please feel free to give a status update now, ping for review, when it's ready. Thank you for your contributions!

@github-actions github-actions Bot added the stale label Sep 5, 2026
@guydc guydc removed the stale label Sep 8, 2026
@guydc

guydc commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

/retest

@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.

Hi @asHasnain, this looks good.

I just have one question: would this also work for Terminate mode TLSRoute?

If yes, can we add tests for Termination mode and update the PR description?

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
…-tls-gateways

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
@asHasnain

Copy link
Copy Markdown
Author

@zhaohuabing Yes, it works for Terminate mode too — both modes produce the same ir.TCPRoute and go through the same SecurityPolicy translation path. The current tests only cover Passthrough so I will add a unit test fixture for Terminate mode (and update the PR description accordingly).

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>
@zhaohuabing

Copy link
Copy Markdown
Member

Hi @asHasnain is it possible to also cover terminate mode in the e2e test?

@arkodg arkodg modified the milestones: Backlog, v1.10.0-rc.1 Release Sep 14, 2026
@asHasnain

Copy link
Copy Markdown
Author

Hi @asHasnain is it possible to also cover terminate mode in the e2e test?

Yes, it's doable — in this PR or a follow-up? A couple of things I'd confirm before writing it:
The Terminate listener needs a cert/key in a kubernetes.io/tls Secret. Is it fine to add one inline in gateway-conformance-infra (same namespace as the Gateway, no ReferenceGrant — matches tlsroute-tls-termination.yaml) or do you prefer cross-namespace + ReferenceGrant?
And after terminating at the listener, forward plain TCP to infra-backend-v1:8080 (the existing echo server)?

@zhaohuabing

Copy link
Copy Markdown
Member

Hi @asHasnain is it possible to also cover terminate mode in the e2e test?

Yes, it's doable — in this PR or a follow-up? A couple of things I'd confirm before writing it: The Terminate listener needs a cert/key in a kubernetes.io/tls Secret. Is it fine to add one inline in gateway-conformance-infra (same namespace as the Gateway, no ReferenceGrant — matches tlsroute-tls-termination.yaml) or do you prefer cross-namespace + ReferenceGrant? And after terminating at the listener, forward plain TCP to infra-backend-v1:8080 (the existing echo server)?

I'd to include the test in this PR to verify the SP for teminate mode.
A inline Secret and echo server sound good to me.

Thanks!

Signed-off-by: asif.hasnain@sap.com <asif.hasnain@sap.com>

@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!

@zhaohuabing
zhaohuabing requested a review from guydc September 26, 2026 03:51

@arkodg arkodg 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.

LGTM thanks,

This branch has not been deployed

No deployments
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.

Security Policies for TLS Gateways

5 participants