Repository: envoyproxy/gateway
Pull request #3378 (2024-05-13 04:24:29)

build(deps): bump github.com/golangci/golangci-lint from 1.58.0 to 1.58.1 in /tools/src/golangci-lint
Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.58.0 to 1.58.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/golangci/golangci-lint/releases">github.com/golangci/golangci-lint's releases</a>.</em></p>
<blockquote>
<h2>v1.58.1</h2>
<p><code>golangci-lint</code> is a free and open-source project built by volunteers.</p>
<p>If you value it, consider supporting us, the <a href="https://opencollective.com/golangci-lint">maintainers</a> and <a href="https://golangci-lint.run/product/thanks/">linter authors</a>.</p>
<p>We appreciate it! :heart:</p>
<p>For key updates, see the <a href="https://golangci-lint.run/product/changelog/%5B#1581%5D(https://redirect.github.com/golangci/golangci-lint/issues/1581)">changelog</a>.</p>
<h2>Changelog</h2>
<ul>
<li>dc281531 build(deps): bump github.com/4meepo/tagalign from 1.3.3 to 1.3.4 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4705">#4705</a>)</li>
<li>9116634a build(deps): bump github.com/ghostiam/protogetter from 0.3.5 to 0.3.6 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4707">#4707</a>)</li>
<li>d64e1de7 build(deps): bump golang.org/x/tools from 0.20.0 to 0.21.0 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4706">#4706</a>)</li>
<li>ee97dbf7 build(deps): bump golangci/golangci-lint-action from 5.1.0 to 5.3.0 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4701">#4701</a>)</li>
<li>4532eb98 fix: gochecknoinits shadow name (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4698">#4698</a>)</li>
<li>6767d7c2 fix: remove GitHub Action problem matchers (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4700">#4700</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md">github.com/golangci/golangci-lint's changelog</a>.</em></p>
<blockquote>
<h3>v1.58.1</h3>
<ol>
<li>Updated linters
<ul>
<li><code>tagalign</code>: from 1.3.3 to 1.3.4</li>
<li><code>protogetter</code>: from 0.3.5 to 0.3.6</li>
<li><code>gochecknoinits</code>: fix analyzer name</li>
</ul>
</li>
<li>Fixes
<ul>
<li>Restores previous <code>gihub-actions</code> output format (removes GitHub Action problem matchers)</li>
</ul>
</li>
</ol>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/golangci/golangci-lint/commit/dc2815312726b4f374f5c69a1c183a85990917a7"><code>dc28153</code></a> build(deps): bump github.com/4meepo/tagalign from 1.3.3 to 1.3.4 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4705">#4705</a>)</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/9116634a7c31cef337675deacd4b63d0cb9410f5"><code>9116634</code></a> build(deps): bump github.com/ghostiam/protogetter from 0.3.5 to 0.3.6 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4707">#4707</a>)</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/d64e1de713c3be23f0fe33c23496634090ce31f0"><code>d64e1de</code></a> build(deps): bump golang.org/x/tools from 0.20.0 to 0.21.0 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4706">#4706</a>)</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/6767d7c2c985bd6ce76ca855477773aae64c52f4"><code>6767d7c</code></a> fix: remove GitHub Action problem matchers (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4700">#4700</a>)</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/ee97dbf75b10c46eff8eaa1f4c84d6f20a290715"><code>ee97dbf</code></a> build(deps): bump golangci/golangci-lint-action from 5.1.0 to 5.3.0 (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4701">#4701</a>)</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/9209e3e7a8829d01f0cf933e857aa939541b3421"><code>9209e3e</code></a> build(deps): bump golang.org/x/oauth2 from 0.19.0 to 0.20.0 in /scripts/gen_g...</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/4532eb98ef1e43e34a6f68aea2e70bec6c13775a"><code>4532eb9</code></a> fix: gochecknoinits shadow name (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4698">#4698</a>)</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/4bf574a12bb61234e28e3d6172be6ed95b0e8baf"><code>4bf574a</code></a> chore: keep v1.57 JSON schema</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/30c05e9f75b0afe41ee7e901daf76b229d534754"><code>30c05e9</code></a> docs: update documentation (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4694">#4694</a>)</li>
<li><a href="https://github.com/golangci/golangci-lint/commit/620a72cfa30c72a390b6da904c218f16fc96daaf"><code>620a72c</code></a> docs: update documentation assets (<a href="https://redirect.github.com/golangci/golangci-lint/issues/4692">#4692</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/golangci/golangci-lint/compare/v1.58.0...v1.58.1">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/golangci/golangci-lint&package-manager=go_modules&previous-version=1.58.0&new-version=1.58.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/cherrypick.yaml b/.github/workflows/cherrypick.yaml
index bda95da1b..797fe2241 100644
--- a/.github/workflows/cherrypick.yaml
+++ b/.github/workflows/cherrypick.yaml
@@ -18,7 +18,7 @@ jobs:
     if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v1.0') && github.event.pull_request.merged == true }}
     steps:
       - name: Checkout
-        uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+        uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
         with:
           fetch-depth: 0
       - name: Cherry pick into release/v1.0
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index bc69c9130..e50f4b292 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -32,18 +32,18 @@ jobs:
 
     steps:
     - name: Checkout repository
-      uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+      uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14  # v3.25.3
+      uses: github/codeql-action/init@ccf74c947955fd1cf117aef6a0e4e66191ef6f61  # v3.25.4
       with:
         languages: ${{ matrix.language }}
 
     - name: Autobuild
-      uses: github/codeql-action/autobuild@d39d31e687223d841ef683f52467bd88e9b21c14  # v3.25.3
+      uses: github/codeql-action/autobuild@ccf74c947955fd1cf117aef6a0e4e66191ef6f61  # v3.25.4
 
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@d39d31e687223d841ef683f52467bd88e9b21c14  # v3.25.3
+      uses: github/codeql-action/analyze@ccf74c947955fd1cf117aef6a0e4e66191ef6f61  # v3.25.4
       with:
         category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index 28ec10e0b..bf07583b0 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -23,7 +23,7 @@ jobs:
     runs-on: ubuntu-22.04
     steps:
     - name: Check out code
-      uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+      uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
       with:
         ref: ${{ github.event.pull_request.head.sha }}
 
@@ -48,7 +48,7 @@ jobs:
       contents: write
     steps:
     - name: Git checkout
-      uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+      uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
       with:
         submodules: true
         ref: ${{ github.event.pull_request.head.sha }}
diff --git a/.github/workflows/experimental_conformance.yaml b/.github/workflows/experimental_conformance.yaml
index c7f00139f..7bb4e92bc 100644
--- a/.github/workflows/experimental_conformance.yaml
+++ b/.github/workflows/experimental_conformance.yaml
@@ -20,7 +20,7 @@ jobs:
       matrix:
         version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ]
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     # gateway api experimental conformance
diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml
index 035c12c0c..50a82ebba 100644
--- a/.github/workflows/osv-scanner.yml
+++ b/.github/workflows/osv-scanner.yml
@@ -19,14 +19,14 @@ permissions:
 jobs:
   scan-scheduled:
     if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
-    uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@1f1242919d8a60496dd1874b24b62b2370ed4c78"  # v1.7.1
+    uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@75532bf0bf75464b047d80414dbce04449498365"  # v1.7.3
     permissions:
       contents: read
       # Require writing security events to upload SARIF file to security tab
       security-events: write
   scan-pr:
     if: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}
-    uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@1f1242919d8a60496dd1874b24b62b2370ed4c78"  # v1.7.1
+    uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@75532bf0bf75464b047d80414dbce04449498365"  # v1.7.3
     permissions:
       contents: read
       # Require writing security events to upload SARIF file to security tab
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index f69ef4164..e8057ad6a 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -15,7 +15,7 @@ jobs:
     permissions:
       contents: write
     steps:
-      - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+      - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
 
       - name: Extract Release Tag and Commit SHA
         id: vars
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 77c1a3dcb..8347d4367 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -21,7 +21,7 @@ jobs:
 
     steps:
     - name: "Checkout code"
-      uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+      uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
       with:
         persist-credentials: false
 
@@ -40,6 +40,6 @@ jobs:
         retention-days: 5
 
     - name: "Upload to code-scanning"
-      uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14  # v3.25.3
+      uses: github/codeql-action/upload-sarif@ccf74c947955fd1cf117aef6a0e4e66191ef6f61  # v3.25.4
       with:
         sarif_file: results.sarif
diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml
index 87a7483f6..1529aaf24 100644
--- a/.github/workflows/trivy.yml
+++ b/.github/workflows/trivy.yml
@@ -18,7 +18,7 @@ jobs:
     runs-on: ubuntu-22.04
     steps:
     - name: Checkout code
-      uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+      uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
 
     - name: Build an image from Dockerfile
       run: |
diff --git a/api/v1alpha1/loadbalancer_types.go b/api/v1alpha1/loadbalancer_types.go
index 795390bb5..d4912aebd 100644
--- a/api/v1alpha1/loadbalancer_types.go
+++ b/api/v1alpha1/loadbalancer_types.go
@@ -66,6 +66,15 @@ type ConsistentHash struct {
 	//
 	// +optional
 	Header *Header `json:"header,omitempty"`
+
+	// The table size for consistent hashing, must be prime number limited to 5000011.
+	//
+	// +kubebuilder:validation:Minimum=2
+	// +kubebuilder:validation:Maximum=5000011
+	// +kubebuilder:default=65537
+	// +optional
+	// +notImplementedHide
+	TableSize *uint64 `json:"tableSize,omitempty"`
 }
 
 // Header defines the header hashing configuration for consistent hash based
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 5dc259601..c584ae2d6 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -783,6 +783,11 @@ func (in *ConsistentHash) DeepCopyInto(out *ConsistentHash) {
 		*out = new(Header)
 		**out = **in
 	}
+	if in.TableSize != nil {
+		in, out := &in.TableSize, &out.TableSize
+		*out = new(uint64)
+		**out = **in
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsistentHash.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
index 6f5b369ce..37aabbbef 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
@@ -422,6 +422,14 @@ spec:
                         required:
                         - name
                         type: object
+                      tableSize:
+                        default: 65537
+                        description: The table size for consistent hashing, must be
+                          prime number limited to 5000011.
+                        format: int64
+                        maximum: 5000011
+                        minimum: 2
+                        type: integer
                       type:
                         description: ConsistentHashType defines the type of input
                           to hash on. Valid Type values are "SourceIP" or "Header".
diff --git a/examples/kubernetes/grpc-routing.yaml b/examples/kubernetes/grpc-routing.yaml
index 5e33a1683..7b4db3d19 100644
--- a/examples/kubernetes/grpc-routing.yaml
+++ b/examples/kubernetes/grpc-routing.yaml
@@ -61,7 +61,7 @@ spec:
   selector:
     app: yages
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
 kind: GRPCRoute
 metadata:
   name: yages
diff --git a/examples/kubernetes/jwt/grpc-jwt.yaml b/examples/kubernetes/jwt/grpc-jwt.yaml
index c992f524f..c841ddb72 100644
--- a/examples/kubernetes/jwt/grpc-jwt.yaml
+++ b/examples/kubernetes/jwt/grpc-jwt.yaml
@@ -13,7 +13,7 @@ spec:
       remoteJWKS:
         uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
 kind: GRPCRoute
 metadata:
   name: yages
diff --git a/go.mod b/go.mod
index 2161f6966..f32eaef58 100644
--- a/go.mod
+++ b/go.mod
@@ -21,7 +21,7 @@ require (
 	github.com/google/go-cmp v0.6.0
 	github.com/grafana/tempo v1.5.0
 	github.com/miekg/dns v1.1.59
-	github.com/prometheus/client_golang v1.19.0
+	github.com/prometheus/client_golang v1.19.1
 	github.com/prometheus/common v0.53.0
 	github.com/spf13/cobra v1.8.0
 	github.com/spf13/pflag v1.0.5
@@ -40,7 +40,7 @@ require (
 	golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
 	golang.org/x/sys v0.20.0
 	google.golang.org/grpc v1.63.2
-	google.golang.org/protobuf v1.34.0
+	google.golang.org/protobuf v1.34.1
 	gopkg.in/yaml.v3 v3.0.1
 	helm.sh/helm/v3 v3.14.4
 	k8s.io/api v0.30.0
@@ -50,7 +50,7 @@ require (
 	k8s.io/client-go v0.30.0
 	k8s.io/kubectl v0.30.0
 	k8s.io/utils v0.0.0-20240423183400-0849a56e8f22
-	sigs.k8s.io/controller-runtime v0.18.1
+	sigs.k8s.io/controller-runtime v0.18.2
 	sigs.k8s.io/gateway-api v1.1.0
 	sigs.k8s.io/mcs-api v0.1.0
 	sigs.k8s.io/yaml v1.4.0
@@ -110,7 +110,7 @@ require (
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
-	golang.org/x/crypto v0.22.0 // indirect
+	golang.org/x/crypto v0.23.0 // indirect
 	k8s.io/apiserver v0.30.0 // indirect
 	oras.land/oras-go v1.2.4 // indirect
 )
@@ -173,11 +173,11 @@ require (
 	go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	golang.org/x/mod v0.17.0 // indirect
-	golang.org/x/net v0.24.0
+	golang.org/x/net v0.25.0
 	golang.org/x/oauth2 v0.19.0 // indirect
 	golang.org/x/sync v0.7.0 // indirect
-	golang.org/x/term v0.19.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/term v0.20.0 // indirect
+	golang.org/x/text v0.15.0 // indirect
 	golang.org/x/time v0.5.0 // indirect
 	golang.org/x/tools v0.20.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
diff --git a/go.sum b/go.sum
index 58573d20d..df1a517bd 100644
--- a/go.sum
+++ b/go.sum
@@ -553,8 +553,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
-github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
-github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
+github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
+github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -720,8 +720,8 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
-golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
 golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
@@ -758,8 +758,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
-golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -815,8 +815,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
-golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
+golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -824,8 +824,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -889,8 +889,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4=
-google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
+google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -977,8 +977,8 @@ oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY=
 oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
 sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
-sigs.k8s.io/controller-runtime v0.18.1 h1:RpWbigmuiylbxOCLy0tGnq1cU1qWPwNIQzoJk+QeJx4=
-sigs.k8s.io/controller-runtime v0.18.1/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw=
+sigs.k8s.io/controller-runtime v0.18.2 h1:RqVW6Kpeaji67CY5nPEfRz6ZfFMk0lWQlNrLqlNpx+Q=
+sigs.k8s.io/controller-runtime v0.18.2/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw=
 sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
 sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
 sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go
index 852cc201d..1a2df010d 100644
--- a/internal/gatewayapi/backendtrafficpolicy.go
+++ b/internal/gatewayapi/backendtrafficpolicy.go
@@ -339,8 +339,8 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
 		}
 	}
 
-	for _, ir := range xdsIR {
-		for _, tcp := range ir.TCP {
+	for _, x := range xdsIR {
+		for _, tcp := range x.TCP {
 			for _, r := range tcp.Routes {
 				if strings.HasPrefix(r.Destination.Name, prefix) {
 					r.LoadBalancer = lb
@@ -353,34 +353,37 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
 			}
 		}
 
-		for _, udp := range ir.UDP {
+		for _, udp := range x.UDP {
 			if strings.HasPrefix(udp.Destination.Name, prefix) {
 				udp.LoadBalancer = lb
 				udp.Timeout = to
 			}
 		}
 
-		for _, http := range ir.HTTP {
+		for _, http := range x.HTTP {
 			for _, r := range http.Routes {
 				// Apply if there is a match
 				if strings.HasPrefix(r.Name, prefix) {
-					r.RateLimit = rl
-					r.LoadBalancer = lb
-					r.ProxyProtocol = pp
-					r.HealthCheck = hc
+					r.Traffic = &ir.TrafficFeatures{
+						RateLimit:      rl,
+						LoadBalancer:   lb,
+						ProxyProtocol:  pp,
+						HealthCheck:    hc,
+						CircuitBreaker: cb,
+						FaultInjection: fi,
+						TCPKeepalive:   ka,
+						Retry:          rt,
+					}
+
 					// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
-					r.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
-					r.CircuitBreaker = cb
-					r.FaultInjection = fi
-					r.TCPKeepalive = ka
-					r.Retry = rt
+					r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
 
-					// some timeout setting originate from the route
+					// Some timeout setting originate from the route.
 					if policy.Spec.Timeout != nil {
 						if to, err = t.buildTimeout(policy, r); err != nil {
 							return errors.Wrap(err, "Timeout")
 						}
-						r.Timeout = to
+						r.Traffic.Timeout = to
 					}
 
 					if policy.Spec.UseClientProtocol != nil {
@@ -445,7 +448,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
 	// set by a policy attaching to the route
 	irKey := t.getIRKey(gateway.Gateway)
 	// Should exist since we've validated this
-	ir := xdsIR[irKey]
+	x := xdsIR[irKey]
 
 	policyTarget := irStringKey(policy.Namespace, string(policy.Spec.TargetRef.Name))
 
@@ -455,7 +458,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
 		}
 	}
 
-	for _, tcp := range ir.TCP {
+	for _, tcp := range x.TCP {
 		gatewayName := tcp.Name[0:strings.LastIndex(tcp.Name, "/")]
 		if t.MergeGateways && gatewayName != policyTarget {
 			continue
@@ -481,7 +484,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
 		}
 	}
 
-	for _, udp := range ir.UDP {
+	for _, udp := range x.UDP {
 		gatewayName := udp.Name[0:strings.LastIndex(udp.Name, "/")]
 		if t.MergeGateways && gatewayName != policyTarget {
 			continue
@@ -498,7 +501,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
 		}
 	}
 
-	for _, http := range ir.HTTP {
+	for _, http := range x.HTTP {
 		gatewayName := http.Name[0:strings.LastIndex(http.Name, "/")]
 		if t.MergeGateways && gatewayName != policyTarget {
 			continue
@@ -509,52 +512,29 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
 		for _, r := range http.Routes {
 			// If any of the features are already set, it means that a more specific
 			// policy(targeting xRoute) has already set it, so we skip it.
-			// TODO: zhaohuabing group the features into a struct and check if all of them are set
-			if r.RateLimit != nil || r.LoadBalancer != nil ||
-				r.ProxyProtocol != nil || r.HealthCheck != nil ||
-				r.CircuitBreaker != nil || r.FaultInjection != nil ||
-				r.TCPKeepalive != nil || r.Retry != nil ||
-				r.Timeout != nil {
+			if r.Traffic != nil {
 				continue
 			}
 
-			// Apply if not already set
-			if r.RateLimit == nil {
-				r.RateLimit = rl
-			}
-			if r.LoadBalancer == nil {
-				r.LoadBalancer = lb
-			}
-			if r.ProxyProtocol == nil {
-				r.ProxyProtocol = pp
-			}
-			if r.HealthCheck == nil {
-				r.HealthCheck = hc
-				// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
-				r.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
+			r.Traffic = &ir.TrafficFeatures{
+				RateLimit:      rl,
+				LoadBalancer:   lb,
+				ProxyProtocol:  pp,
+				HealthCheck:    hc,
+				CircuitBreaker: cb,
+				FaultInjection: fi,
+				TCPKeepalive:   ka,
+				Retry:          rt,
 			}
 
-			if r.CircuitBreaker == nil {
-				r.CircuitBreaker = cb
-			}
-			if r.FaultInjection == nil {
-				r.FaultInjection = fi
-			}
-			if r.TCPKeepalive == nil {
-				r.TCPKeepalive = ka
-			}
-			if r.Retry == nil {
-				r.Retry = rt
-			}
+			// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
+			r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
 
 			if policy.Spec.Timeout != nil {
 				if ct, err = t.buildTimeout(policy, r); err != nil {
 					return errors.Wrap(err, "Timeout")
 				}
-
-				if r.Timeout == nil {
-					r.Timeout = ct
-				}
+				r.Traffic.Timeout = ct
 			}
 
 			if policy.Spec.UseClientProtocol != nil {
@@ -1066,13 +1046,17 @@ func (t *Translator) buildTimeout(policy *egv1a1.BackendTrafficPolicy, r *ir.HTT
 
 	// http request timeout is translated during the gateway-api route resource translation
 	// merge route timeout setting with backendtrafficpolicy timeout settings
-	if r != nil && r.Timeout != nil && r.Timeout.HTTP != nil && r.Timeout.HTTP.RequestTimeout != nil {
+	if r != nil &&
+		r.Traffic != nil &&
+		r.Traffic.Timeout != nil &&
+		r.Traffic.Timeout.HTTP != nil &&
+		r.Traffic.Timeout.HTTP.RequestTimeout != nil {
 		if hto == nil {
 			hto = &ir.HTTPTimeout{
-				RequestTimeout: r.Timeout.HTTP.RequestTimeout,
+				RequestTimeout: r.Traffic.Timeout.HTTP.RequestTimeout,
 			}
 		} else {
-			hto.RequestTimeout = r.Timeout.HTTP.RequestTimeout
+			hto.RequestTimeout = r.Traffic.Timeout.HTTP.RequestTimeout
 		}
 	}
 
diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go
index d10331ca2..8abbac6c8 100644
--- a/internal/gatewayapi/route.go
+++ b/internal/gatewayapi/route.go
@@ -248,8 +248,8 @@ func processTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
 		var rto *ir.Timeout
 
 		// Timeout is translated from multiple resources and may already be partially set
-		if irRoute.Timeout != nil {
-			rto = irRoute.Timeout.DeepCopy()
+		if irRoute.Traffic != nil && irRoute.Traffic.Timeout != nil {
+			rto = irRoute.Traffic.Timeout.DeepCopy()
 		} else {
 			rto = &ir.Timeout{}
 		}
@@ -272,7 +272,9 @@ func processTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
 			setRequestTimeout(rto, metav1.Duration{Duration: d})
 		}
 
-		irRoute.Timeout = rto
+		irRoute.Traffic = &ir.TrafficFeatures{
+			Timeout: rto,
+		}
 	}
 }
 
@@ -681,14 +683,18 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
 					URLRewrite:            routeRoute.URLRewrite,
 					Mirrors:               routeRoute.Mirrors,
 					ExtensionRefs:         routeRoute.ExtensionRefs,
-					Timeout:               routeRoute.Timeout,
-					Retry:                 routeRoute.Retry,
 					IsHTTP2:               routeRoute.IsHTTP2,
 				}
 				// Don't bother copying over the weights unless the route has invalid backends.
 				if routeRoute.BackendWeights.Invalid > 0 {
 					hostRoute.BackendWeights = routeRoute.BackendWeights
 				}
+				if routeRoute.Traffic != nil {
+					hostRoute.Traffic = &ir.TrafficFeatures{
+						Timeout: routeRoute.Traffic.Timeout,
+						Retry:   routeRoute.Traffic.Retry,
+					}
+				}
 				perHostRoutes = append(perHostRoutes, hostRoute)
 			}
 		}
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index c7862d3cc..e68cf3fab 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -465,7 +465,7 @@ func (t *Translator) translateSecurityPolicyForGateway(
 		for _, r := range h.Routes {
 			// If any of the features are already set, it means that a more specific
 			// policy(targeting xRoute) has already set it, so we skip it.
-			if !r.Security.Empty() {
+			if r.Security != nil {
 				continue
 			}
 
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 126e8f8fb..25e3f5834 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -476,6 +476,24 @@ type HTTPRoute struct {
 	Destination *RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
 	// Rewrite to be changed for this route.
 	URLRewrite *URLRewrite `json:"urlRewrite,omitempty" yaml:"urlRewrite,omitempty"`
+	// ExtensionRefs holds unstructured resources that were introduced by an extension and used on the HTTPRoute as extensionRef filters
+	ExtensionRefs []*UnstructuredRef `json:"extensionRefs,omitempty" yaml:"extensionRefs,omitempty"`
+	// External Processing extensions
+	ExtProcs []ExtProc `json:"extProc,omitempty" yaml:"extProc,omitempty"`
+	// Wasm extensions
+	Wasms []Wasm `json:"wasm,omitempty" yaml:"wasm,omitempty"`
+
+	// Traffic holds the features associated with BackendTrafficPolicy
+	Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"`
+	// Security holds the features associated with SecurityPolicy
+	Security *SecurityFeatures `json:"security,omitempty" yaml:"security,omitempty"`
+	// UseClientProtocol enables using the same protocol upstream that was used downstream
+	UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"`
+}
+
+// TrafficFeatures holds the information associated with the Backend Traffic Policy.
+// +k8s:deepcopy-gen=true
+type TrafficFeatures struct {
 	// RateLimit defines the more specific match conditions as well as limits for ratelimiting
 	// the requests on this route.
 	RateLimit *RateLimit `json:"rateLimit,omitempty" yaml:"rateLimit,omitempty"`
@@ -487,8 +505,6 @@ type HTTPRoute struct {
 	HealthCheck *HealthCheck `json:"healthCheck,omitempty" yaml:"healthCheck,omitempty"`
 	// FaultInjection defines the schema for injecting faults into HTTP requests.
 	FaultInjection *FaultInjection `json:"faultInjection,omitempty" yaml:"faultInjection,omitempty"`
-	// ExtensionRefs holds unstructured resources that were introduced by an extension and used on the HTTPRoute as extensionRef filters
-	ExtensionRefs []*UnstructuredRef `json:"extensionRefs,omitempty" yaml:"extensionRefs,omitempty"`
 	// Circuit Breaker Settings
 	CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"`
 	// Request and connection timeout settings
@@ -497,15 +513,23 @@ type HTTPRoute struct {
 	TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"`
 	// Retry settings
 	Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"`
-	// External Processing extensions
-	ExtProcs []ExtProc `json:"extProc,omitempty" yaml:"extProc,omitempty"`
-	// Wasm extensions
-	Wasms []Wasm `json:"wasm,omitempty" yaml:"wasm,omitempty"`
+}
 
-	// Security holds the features associated with SecurityPolicy
-	Security *SecurityFeatures `json:"security,omitempty" yaml:"security,omitempty"`
-	// UseClientProtocol enables using the same protocol upstream that was used downstream
-	UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"`
+func (b *TrafficFeatures) Validate() error {
+	var errs error
+
+	if b.LoadBalancer != nil {
+		if err := b.LoadBalancer.Validate(); err != nil {
+			errs = errors.Join(errs, err)
+		}
+	}
+	if b.HealthCheck != nil {
+		if err := b.HealthCheck.Validate(); err != nil {
+			errs = errors.Join(errs, err)
+		}
+	}
+
+	return errs
 }
 
 // SecurityFeatures holds the information associated with the Security Policy.
@@ -523,19 +547,6 @@ type SecurityFeatures struct {
 	ExtAuth *ExtAuth `json:"extAuth,omitempty" yaml:"extAuth,omitempty"`
 }
 
-// Empty returns true if all the features are not set.
-func (s *SecurityFeatures) Empty() bool {
-	if s == nil {
-		return true
-	}
-
-	return s.CORS == nil &&
-		s.JWT == nil &&
-		s.OIDC == nil &&
-		s.BasicAuth == nil &&
-		s.ExtAuth == nil
-}
-
 func (s *SecurityFeatures) Printable() *SecurityFeatures {
 	out := s.DeepCopy()
 	if out.OIDC != nil {
@@ -872,8 +883,8 @@ func (h HTTPRoute) Validate() error {
 			occurred.Insert(header)
 		}
 	}
-	if h.LoadBalancer != nil {
-		if err := h.LoadBalancer.Validate(); err != nil {
+	if h.Traffic != nil {
+		if err := h.Traffic.Validate(); err != nil {
 			errs = errors.Join(errs, err)
 		}
 	}
@@ -882,11 +893,6 @@ func (h HTTPRoute) Validate() error {
 			errs = errors.Join(errs, err)
 		}
 	}
-	if h.HealthCheck != nil {
-		if err := h.HealthCheck.Validate(); err != nil {
-			errs = errors.Join(errs, err)
-		}
-	}
 
 	return errs
 }
diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go
index bd0ce421a..514543c80 100644
--- a/internal/ir/zz_generated.deepcopy.go
+++ b/internal/ir/zz_generated.deepcopy.go
@@ -1021,31 +1021,6 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
 		*out = new(URLRewrite)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.RateLimit != nil {
-		in, out := &in.RateLimit, &out.RateLimit
-		*out = new(RateLimit)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.LoadBalancer != nil {
-		in, out := &in.LoadBalancer, &out.LoadBalancer
-		*out = new(LoadBalancer)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.ProxyProtocol != nil {
-		in, out := &in.ProxyProtocol, &out.ProxyProtocol
-		*out = new(ProxyProtocol)
-		**out = **in
-	}
-	if in.HealthCheck != nil {
-		in, out := &in.HealthCheck, &out.HealthCheck
-		*out = new(HealthCheck)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.FaultInjection != nil {
-		in, out := &in.FaultInjection, &out.FaultInjection
-		*out = new(FaultInjection)
-		(*in).DeepCopyInto(*out)
-	}
 	if in.ExtensionRefs != nil {
 		in, out := &in.ExtensionRefs, &out.ExtensionRefs
 		*out = make([]*UnstructuredRef, len(*in))
@@ -1057,26 +1032,6 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
 			}
 		}
 	}
-	if in.CircuitBreaker != nil {
-		in, out := &in.CircuitBreaker, &out.CircuitBreaker
-		*out = new(CircuitBreaker)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.Timeout != nil {
-		in, out := &in.Timeout, &out.Timeout
-		*out = new(Timeout)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.TCPKeepalive != nil {
-		in, out := &in.TCPKeepalive, &out.TCPKeepalive
-		*out = new(TCPKeepalive)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.Retry != nil {
-		in, out := &in.Retry, &out.Retry
-		*out = new(Retry)
-		(*in).DeepCopyInto(*out)
-	}
 	if in.ExtProcs != nil {
 		in, out := &in.ExtProcs, &out.ExtProcs
 		*out = make([]ExtProc, len(*in))
@@ -1091,6 +1046,11 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
+	if in.Traffic != nil {
+		in, out := &in.Traffic, &out.Traffic
+		*out = new(TrafficFeatures)
+		(*in).DeepCopyInto(*out)
+	}
 	if in.Security != nil {
 		in, out := &in.Security, &out.Security
 		*out = new(SecurityFeatures)
@@ -2424,6 +2384,66 @@ func (in *Tracing) DeepCopy() *Tracing {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) {
+	*out = *in
+	if in.RateLimit != nil {
+		in, out := &in.RateLimit, &out.RateLimit
+		*out = new(RateLimit)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.LoadBalancer != nil {
+		in, out := &in.LoadBalancer, &out.LoadBalancer
+		*out = new(LoadBalancer)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ProxyProtocol != nil {
+		in, out := &in.ProxyProtocol, &out.ProxyProtocol
+		*out = new(ProxyProtocol)
+		**out = **in
+	}
+	if in.HealthCheck != nil {
+		in, out := &in.HealthCheck, &out.HealthCheck
+		*out = new(HealthCheck)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.FaultInjection != nil {
+		in, out := &in.FaultInjection, &out.FaultInjection
+		*out = new(FaultInjection)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.CircuitBreaker != nil {
+		in, out := &in.CircuitBreaker, &out.CircuitBreaker
+		*out = new(CircuitBreaker)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.Timeout != nil {
+		in, out := &in.Timeout, &out.Timeout
+		*out = new(Timeout)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.TCPKeepalive != nil {
+		in, out := &in.TCPKeepalive, &out.TCPKeepalive
+		*out = new(TCPKeepalive)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.Retry != nil {
+		in, out := &in.Retry, &out.Retry
+		*out = new(Retry)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures.
+func (in *TrafficFeatures) DeepCopy() *TrafficFeatures {
+	if in == nil {
+		return nil
+	}
+	out := new(TrafficFeatures)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *UDPListener) DeepCopyInto(out *UDPListener) {
 	*out = *in
diff --git a/internal/metrics/options.go b/internal/metrics/options.go
index f274582f4..5b9ca961d 100644
--- a/internal/metrics/options.go
+++ b/internal/metrics/options.go
@@ -5,7 +5,7 @@
 
 package metrics
 
-// Options encode changes to the options passed to a Metric at creation time.
+// MetricOption encode changes to the options passed to a Metric at creation time.
 type MetricOption func(*MetricOptions)
 
 type MetricOptions struct {
diff --git a/internal/metrics/register.go b/internal/metrics/register.go
index 9c8abdf47..e6332aeb8 100644
--- a/internal/metrics/register.go
+++ b/internal/metrics/register.go
@@ -12,6 +12,8 @@ import (
 	"net/http"
 	"time"
 
+	"github.com/prometheus/client_golang/prometheus"
+	"github.com/prometheus/client_golang/prometheus/promhttp"
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
 	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
@@ -19,9 +21,6 @@ import (
 	"go.opentelemetry.io/otel/sdk/metric"
 	metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics"
 
-	"github.com/prometheus/client_golang/prometheus"
-	"github.com/prometheus/client_golang/prometheus/promhttp"
-
 	"github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/envoygateway/config"
 )
diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go
index 8e23f656a..e7329d49a 100644
--- a/internal/provider/kubernetes/controller.go
+++ b/internal/provider/kubernetes/controller.go
@@ -441,7 +441,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
 
 			if backendNamespace != policy.Namespace {
 				from := ObjectKindNamespacedName{
-					kind:      gatewayapi.KindHTTPRoute,
+					kind:      gatewayapi.KindSecurityPolicy,
 					namespace: policy.Namespace,
 					name:      policy.Name,
 				}
diff --git a/internal/provider/kubernetes/metrics.go b/internal/provider/kubernetes/metrics.go
new file mode 100644
index 000000000..236aa150e
--- /dev/null
+++ b/internal/provider/kubernetes/metrics.go
@@ -0,0 +1,19 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package kubernetes
+
+import "github.com/envoyproxy/gateway/internal/metrics"
+
+var (
+	statusUpdateTotal           = metrics.NewCounter("status_update_total", "Total number of status updates by object kind.")
+	statusUpdateFailed          = metrics.NewCounter("status_update_failed_total", "Number of status updates that failed by object kind.")
+	statusUpdateConflict        = metrics.NewCounter("status_update_conflict_total", "Number of status update conflicts encountered by object kind.")
+	statusUpdateSuccess         = metrics.NewCounter("status_update_success_total", "Number of status updates that succeeded by object kind.")
+	statusUpdateNoop            = metrics.NewCounter("status_update_noop_total", "Number of status updates that are no-ops by object kind. This is a subset of successful status updates.")
+	statusUpdateDurationSeconds = metrics.NewHistogram("status_update_duration_seconds", "How long a status update takes to finish.", []float64{0.001, 0.01, 0.1, 1, 5, 10})
+
+	kindLabel = metrics.NewLabel("kind")
+)
diff --git a/internal/provider/kubernetes/status_updater.go b/internal/provider/kubernetes/status_updater.go
index 1b25cfbf4..cce15c1b0 100644
--- a/internal/provider/kubernetes/status_updater.go
+++ b/internal/provider/kubernetes/status_updater.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"time"
 
 	"github.com/go-logr/logr"
 	"github.com/google/go-cmp/cmp"
@@ -21,6 +22,7 @@ import (
 	gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+	"github.com/envoyproxy/gateway/internal/gatewayapi"
 )
 
 // Update contains an all the information needed to update an object's status.
@@ -66,9 +68,26 @@ func NewUpdateHandler(log logr.Logger, client client.Client) *UpdateHandler {
 }
 
 func (u *UpdateHandler) apply(update Update) {
-	if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
-		obj := update.Resource
+	var (
+		startTime = time.Now()
+		obj       = update.Resource
+		objKind   = kindOf(obj)
+	)
 
+	statusUpdateTotal.With(kindLabel.Value(objKind)).Increment()
+
+	defer func() {
+		updateDuration := time.Since(startTime)
+		statusUpdateDurationSeconds.With(kindLabel.Value(objKind)).Record(updateDuration.Seconds())
+	}()
+
+	if err := retry.OnError(retry.DefaultBackoff, func(err error) bool {
+		if kerrors.IsConflict(err) {
+			statusUpdateConflict.With(kindLabel.Value(objKind)).Increment()
+			return true
+		}
+		return false
+	}, func() error {
 		// Get the resource.
 		if err := u.client.Get(context.Background(), update.NamespacedName, obj); err != nil {
 			if kerrors.IsNotFound(err) {
@@ -83,6 +102,8 @@ func (u *UpdateHandler) apply(update Update) {
 			u.log.WithName(update.NamespacedName.Name).
 				WithName(update.NamespacedName.Namespace).
 				Info("status unchanged, bypassing update")
+
+			statusUpdateNoop.With(kindLabel.Value(objKind)).Increment()
 			return nil
 		}
 
@@ -92,6 +113,10 @@ func (u *UpdateHandler) apply(update Update) {
 	}); err != nil {
 		u.log.Error(err, "unable to update status", "name", update.NamespacedName.Name,
 			"namespace", update.NamespacedName.Namespace)
+
+		statusUpdateFailed.With(kindLabel.Value(objKind)).Increment()
+	} else {
+		statusUpdateSuccess.With(kindLabel.Value(objKind)).Increment()
 	}
 }
 
@@ -162,8 +187,10 @@ func (u *UpdateWriter) Send(update Update) {
 //	GRPCRoute
 //	EnvoyPatchPolicy
 //	ClientTrafficPolicy
+//	BackendTrafficPolicy
 //	SecurityPolicy
 //	BackendTLSPolicy
+//	EnvoyExtensionPolicy
 func isStatusEqual(objA, objB interface{}) bool {
 	opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")
 	switch a := objA.(type) {
@@ -233,7 +260,7 @@ func isStatusEqual(objA, objB interface{}) bool {
 				return true
 			}
 		}
-	case gwapiv1a3.BackendTLSPolicy:
+	case *gwapiv1a3.BackendTLSPolicy:
 		if b, ok := objB.(*gwapiv1a3.BackendTLSPolicy); ok {
 			if cmp.Equal(a.Status, b.Status, opts) {
 				return true
@@ -248,3 +275,57 @@ func isStatusEqual(objA, objB interface{}) bool {
 	}
 	return false
 }
+
+// kindOf returns the known kind string for the given Kubernetes object,
+// returns Unknown for the unsupported object.
+//
+// Supported objects:
+//
+//	GatewayClasses
+//	Gateway
+//	HTTPRoute
+//	TLSRoute
+//	TCPRoute
+//	UDPRoute
+//	GRPCRoute
+//	EnvoyPatchPolicy
+//	ClientTrafficPolicy
+//	BackendTrafficPolicy
+//	SecurityPolicy
+//	BackendTLSPolicy
+//	EnvoyExtensionPolicy
+func kindOf(obj interface{}) string {
+	var kind string
+	switch obj.(type) {
+	case *gwapiv1.GatewayClass:
+		kind = gatewayapi.KindGatewayClass
+	case *gwapiv1.Gateway:
+		kind = gatewayapi.KindGateway
+	case *gwapiv1.HTTPRoute:
+		kind = gatewayapi.KindHTTPRoute
+	case *gwapiv1a2.TLSRoute:
+		kind = gatewayapi.KindTLSRoute
+	case *gwapiv1a2.TCPRoute:
+		kind = gatewayapi.KindTCPRoute
+	case *gwapiv1a2.UDPRoute:
+		kind = gatewayapi.KindUDPRoute
+	case *gwapiv1.GRPCRoute:
+		kind = gatewayapi.KindGRPCRoute
+	case *egv1a1.EnvoyPatchPolicy:
+		kind = gatewayapi.KindEnvoyPatchPolicy
+	case *egv1a1.ClientTrafficPolicy:
+		kind = gatewayapi.KindClientTrafficPolicy
+	case *egv1a1.BackendTrafficPolicy:
+		kind = gatewayapi.KindBackendTrafficPolicy
+	case *egv1a1.SecurityPolicy:
+		kind = gatewayapi.KindSecurityPolicy
+	case *egv1a1.EnvoyExtensionPolicy:
+		kind = gatewayapi.KindEnvoyExtensionPolicy
+	case *gwapiv1a3.BackendTLSPolicy:
+		kind = gatewayapi.KindBackendTLSPolicy
+	default:
+		kind = "Unknown"
+	}
+
+	return kind
+}
diff --git a/internal/xds/translator/fault.go b/internal/xds/translator/fault.go
index 46642934c..43fae199c 100644
--- a/internal/xds/translator/fault.go
+++ b/internal/xds/translator/fault.go
@@ -36,7 +36,7 @@ var _ httpFilter = &fault{}
 
 // patchHCM builds and appends the fault Filters to the HTTP Connection Manager
 // if applicable, and it does not already exist.
-// Note: this method creates an fault filter for each route that contains an Fault config.
+// Note: this method creates a fault filter for each route that contains an Fault config.
 func (*fault) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error {
 	if mgr == nil {
 		return errors.New("hcm is nil")
@@ -99,7 +99,9 @@ func listenerContainsFault(irListener *ir.HTTPListener) bool {
 
 // routeContainsFault returns true if Fault exists for the provided route.
 func routeContainsFault(irRoute *ir.HTTPRoute) bool {
-	if irRoute != nil && irRoute.FaultInjection != nil {
+	if irRoute != nil &&
+		irRoute.Traffic != nil &&
+		irRoute.Traffic.FaultInjection != nil {
 		return true
 	}
 	return false
@@ -118,7 +120,7 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
 	if irRoute == nil {
 		return errors.New("ir route is nil")
 	}
-	if irRoute.FaultInjection == nil {
+	if irRoute.Traffic == nil || irRoute.Traffic.FaultInjection == nil {
 		return nil
 	}
 
@@ -131,34 +133,35 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
 
 	routeCfgProto := &xdshttpfaultv3.HTTPFault{}
 
-	if irRoute.FaultInjection.Delay != nil {
+	delay := irRoute.Traffic.FaultInjection.Delay
+	if delay != nil {
 		routeCfgProto.Delay = &xdsfault.FaultDelay{}
-		if irRoute.FaultInjection.Delay.Percentage != nil {
-			routeCfgProto.Delay.Percentage = translatePercentToFractionalPercent(irRoute.FaultInjection.Delay.Percentage)
+		if delay.Percentage != nil {
+			routeCfgProto.Delay.Percentage = translatePercentToFractionalPercent(delay.Percentage)
 		}
-		if irRoute.FaultInjection.Delay.FixedDelay != nil {
+		if delay.FixedDelay != nil {
 			routeCfgProto.Delay.FaultDelaySecifier = &xdsfault.FaultDelay_FixedDelay{
-				FixedDelay: durationpb.New(irRoute.FaultInjection.Delay.FixedDelay.Duration),
+				FixedDelay: durationpb.New(delay.FixedDelay.Duration),
 			}
 		}
 	}
 
-	if irRoute.FaultInjection.Abort != nil {
+	abort := irRoute.Traffic.FaultInjection.Abort
+	if abort != nil {
 		routeCfgProto.Abort = &xdshttpfaultv3.FaultAbort{}
-		if irRoute.FaultInjection.Abort.Percentage != nil {
-			routeCfgProto.Abort.Percentage = translatePercentToFractionalPercent(irRoute.FaultInjection.Abort.Percentage)
+		if abort.Percentage != nil {
+			routeCfgProto.Abort.Percentage = translatePercentToFractionalPercent(abort.Percentage)
 		}
-		if irRoute.FaultInjection.Abort.HTTPStatus != nil {
+		if abort.HTTPStatus != nil {
 			routeCfgProto.Abort.ErrorType = &xdshttpfaultv3.FaultAbort_HttpStatus{
-				HttpStatus: uint32(*irRoute.FaultInjection.Abort.HTTPStatus),
+				HttpStatus: uint32(*abort.HTTPStatus),
 			}
 		}
-		if irRoute.FaultInjection.Abort.GrpcStatus != nil {
+		if abort.GrpcStatus != nil {
 			routeCfgProto.Abort.ErrorType = &xdshttpfaultv3.FaultAbort_GrpcStatus{
-				GrpcStatus: uint32(*irRoute.FaultInjection.Abort.GrpcStatus),
+				GrpcStatus: uint32(*abort.GrpcStatus),
 			}
 		}
-
 	}
 
 	if routeCfgProto.Delay == nil && routeCfgProto.Abort == nil {
@@ -179,7 +182,7 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
 	return nil
 }
 
-// translatePercentToFractionalPercent translates an v1alpha3 Percent instance
+// translatePercentToFractionalPercent translates a v1alpha3 Percent instance
 // to an envoy.type.FractionalPercent instance.
 func translatePercentToFractionalPercent(p *float32) *xdstype.FractionalPercent {
 	return &xdstype.FractionalPercent{
diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go
index 688461e9f..1a0d88d5d 100644
--- a/internal/xds/translator/local_ratelimit.go
+++ b/internal/xds/translator/local_ratelimit.go
@@ -96,7 +96,10 @@ func listenerContainsLocalRateLimit(irListener *ir.HTTPListener) bool {
 }
 
 func routeContainsLocalRateLimit(irRoute *ir.HTTPRoute) bool {
-	if irRoute == nil || irRoute.RateLimit == nil || irRoute.RateLimit.Local == nil {
+	if irRoute == nil ||
+		irRoute.Traffic == nil ||
+		irRoute.Traffic.RateLimit == nil ||
+		irRoute.Traffic.RateLimit.Local == nil {
 		return false
 	}
 
@@ -113,7 +116,7 @@ func (*localRateLimit) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) e
 	routeAction := route.GetRoute()
 
 	// Return early if no rate limit config exists.
-	if irRoute.RateLimit == nil || irRoute.RateLimit.Local == nil || routeAction == nil {
+	if !routeContainsLocalRateLimit(irRoute) || routeAction == nil {
 		return nil
 	}
 
@@ -125,7 +128,7 @@ func (*localRateLimit) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) e
 			route.Name)
 	}
 
-	local := irRoute.RateLimit.Local
+	local := irRoute.Traffic.RateLimit.Local
 
 	rateLimits, descriptors, err := buildRouteLocalRateLimits(local)
 	if err != nil {
diff --git a/internal/xds/translator/ratelimit.go b/internal/xds/translator/ratelimit.go
index 02b1c3d60..4534f303f 100644
--- a/internal/xds/translator/ratelimit.go
+++ b/internal/xds/translator/ratelimit.go
@@ -73,6 +73,17 @@ func (t *Translator) patchHCMWithRateLimit(mgr *hcmv3.HttpConnectionManager, irL
 	mgr.HttpFilters = append([]*hcmv3.HttpFilter{rateLimitFilter}, mgr.HttpFilters...)
 }
 
+func routeContainsGlobalRateLimit(irRoute *ir.HTTPRoute) bool {
+	if irRoute == nil ||
+		irRoute.Traffic == nil ||
+		irRoute.Traffic.RateLimit == nil ||
+		irRoute.Traffic.RateLimit.Global == nil {
+		return false
+	}
+
+	return true
+}
+
 // isRateLimitPresent returns true if rate limit config exists for the listener.
 func (t *Translator) isRateLimitPresent(irListener *ir.HTTPListener) bool {
 	// Return false if global ratelimiting is disabled.
@@ -81,7 +92,7 @@ func (t *Translator) isRateLimitPresent(irListener *ir.HTTPListener) bool {
 	}
 	// Return true if rate limit config exists.
 	for _, route := range irListener.Routes {
-		if route.RateLimit != nil && route.RateLimit.Global != nil {
+		if routeContainsGlobalRateLimit(route) {
 			return true
 		}
 	}
@@ -128,11 +139,11 @@ func (t *Translator) buildRateLimitFilter(irListener *ir.HTTPListener) *hcmv3.Ht
 // patchRouteWithRateLimit builds rate limit actions and appends to the route.
 func patchRouteWithRateLimit(xdsRouteAction *routev3.RouteAction, irRoute *ir.HTTPRoute) error { //nolint:unparam
 	// Return early if no rate limit config exists.
-	if irRoute.RateLimit == nil || irRoute.RateLimit.Global == nil || xdsRouteAction == nil {
+	if !routeContainsGlobalRateLimit(irRoute) || xdsRouteAction == nil {
 		return nil
 	}
 
-	rateLimits := buildRouteRateLimits(irRoute.Name, irRoute.RateLimit.Global)
+	rateLimits := buildRouteRateLimits(irRoute.Name, irRoute.Traffic.RateLimit.Global)
 	xdsRouteAction.RateLimits = rateLimits
 	return nil
 }
@@ -287,8 +298,8 @@ func BuildRateLimitServiceConfig(irListener *ir.HTTPListener) *rlsconfv3.RateLim
 	pbDescriptors := make([]*rlsconfv3.RateLimitDescriptor, 0, len(irListener.Routes))
 
 	for _, route := range irListener.Routes {
-		if route.RateLimit != nil && route.RateLimit.Global != nil {
-			serviceDescriptors := buildRateLimitServiceDescriptors(route.RateLimit.Global)
+		if routeContainsGlobalRateLimit(route) {
+			serviceDescriptors := buildRateLimitServiceDescriptors(route.Traffic.RateLimit.Global)
 
 			// Get route rule descriptors within each route.
 			//
diff --git a/internal/xds/translator/route.go b/internal/xds/translator/route.go
index a52371103..bf68ac7df 100644
--- a/internal/xds/translator/route.go
+++ b/internal/xds/translator/route.go
@@ -10,8 +10,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/envoyproxy/gateway/internal/utils/protocov"
-
 	corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
 	routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
 	previoushost "github.com/envoyproxy/go-control-plane/envoy/extensions/retry/host/previous_hosts/v3"
@@ -20,6 +18,7 @@ import (
 	"google.golang.org/protobuf/types/known/wrapperspb"
 
 	"github.com/envoyproxy/gateway/internal/ir"
+	"github.com/envoyproxy/gateway/internal/utils/protocov"
 )
 
 const (
@@ -99,13 +98,18 @@ func buildXdsRoute(httpRoute *ir.HTTPRoute) (*routev3.Route, error) {
 	}
 
 	// Timeouts
-	if router.GetRoute() != nil && httpRoute.Timeout != nil && httpRoute.Timeout.HTTP != nil &&
-		httpRoute.Timeout.HTTP.RequestTimeout != nil {
-		router.GetRoute().Timeout = durationpb.New(httpRoute.Timeout.HTTP.RequestTimeout.Duration)
+	if router.GetRoute() != nil &&
+		httpRoute.Traffic != nil &&
+		httpRoute.Traffic.Timeout != nil &&
+		httpRoute.Traffic.Timeout.HTTP != nil &&
+		httpRoute.Traffic.Timeout.HTTP.RequestTimeout != nil {
+		router.GetRoute().Timeout = durationpb.New(httpRoute.Traffic.Timeout.HTTP.RequestTimeout.Duration)
 	}
 
 	// Retries
-	if router.GetRoute() != nil && httpRoute.Retry != nil {
+	if router.GetRoute() != nil &&
+		httpRoute.Traffic != nil &&
+		httpRoute.Traffic.Retry != nil {
 		if rp, err := buildRetryPolicy(httpRoute); err == nil {
 			router.GetRoute().RetryPolicy = rp
 		} else {
@@ -259,22 +263,24 @@ func buildXdsWeightedRouteAction(httpRoute *ir.HTTPRoute) *routev3.RouteAction {
 }
 
 func idleTimeout(httpRoute *ir.HTTPRoute) *durationpb.Duration {
-	if httpRoute.Timeout != nil && httpRoute.Timeout.HTTP != nil {
-		if httpRoute.Timeout.HTTP.RequestTimeout != nil {
-			timeout := time.Hour // Default to 1 hour
+	if httpRoute.Traffic != nil &&
+		httpRoute.Traffic.Timeout != nil &&
+		httpRoute.Traffic.Timeout.HTTP != nil &&
+		httpRoute.Traffic.Timeout.HTTP.RequestTimeout != nil {
+		rt := httpRoute.Traffic.Timeout.HTTP.RequestTimeout
+		timeout := time.Hour // Default to 1 hour
 
-			// Ensure is not less than the request timeout
-			if timeout < httpRoute.Timeout.HTTP.RequestTimeout.Duration {
-				timeout = httpRoute.Timeout.HTTP.RequestTimeout.Duration
-			}
-
-			// Disable idle timeout when request timeout is disabled
-			if httpRoute.Timeout.HTTP.RequestTimeout.Duration == 0 {
-				timeout = 0
-			}
+		// Ensure is not less than the request timeout
+		if timeout < rt.Duration {
+			timeout = rt.Duration
+		}
 
-			return durationpb.New(timeout)
+		// Disable idle timeout when request timeout is disabled
+		if rt.Duration == 0 {
+			timeout = 0
 		}
+
+		return durationpb.New(timeout)
 	}
 	return nil
 }
@@ -436,22 +442,27 @@ func buildXdsAddedHeaders(headersToAdd []ir.AddHeader) []*corev3.HeaderValueOpti
 
 func buildHashPolicy(httpRoute *ir.HTTPRoute) []*routev3.RouteAction_HashPolicy {
 	// Return early
-	if httpRoute == nil || httpRoute.LoadBalancer == nil || httpRoute.LoadBalancer.ConsistentHash == nil {
+	if httpRoute == nil ||
+		httpRoute.Traffic == nil ||
+		httpRoute.Traffic.LoadBalancer == nil ||
+		httpRoute.Traffic.LoadBalancer.ConsistentHash == nil {
 		return nil
 	}
 
+	ch := httpRoute.Traffic.LoadBalancer.ConsistentHash
+
 	switch {
-	case httpRoute.LoadBalancer.ConsistentHash.Header != nil:
+	case ch.Header != nil:
 		hashPolicy := &routev3.RouteAction_HashPolicy{
 			PolicySpecifier: &routev3.RouteAction_HashPolicy_Header_{
 				Header: &routev3.RouteAction_HashPolicy_Header{
-					HeaderName: httpRoute.LoadBalancer.ConsistentHash.Header.Name,
+					HeaderName: ch.Header.Name,
 				},
 			},
 		}
 		return []*routev3.RouteAction_HashPolicy{hashPolicy}
-	case httpRoute.LoadBalancer.ConsistentHash.SourceIP != nil:
-		if !*httpRoute.LoadBalancer.ConsistentHash.SourceIP {
+	case ch.SourceIP != nil:
+		if !*ch.SourceIP {
 			return nil
 		}
 		hashPolicy := &routev3.RouteAction_HashPolicy{
@@ -468,68 +479,64 @@ func buildHashPolicy(httpRoute *ir.HTTPRoute) []*routev3.RouteAction_HashPolicy
 }
 
 func buildRetryPolicy(route *ir.HTTPRoute) (*routev3.RetryPolicy, error) {
-	if route.Retry != nil {
-		rr := route.Retry
-		rp := &routev3.RetryPolicy{
-			RetryOn:              retryDefaultRetryOn,
-			RetriableStatusCodes: []uint32{retryDefaultRetriableStatusCode},
-			NumRetries:           &wrapperspb.UInt32Value{Value: retryDefaultNumRetries},
-			RetryHostPredicate: []*routev3.RetryPolicy_RetryHostPredicate{
-				{
-					Name: "envoy.retry_host_predicates.previous_hosts",
-					ConfigType: &routev3.RetryPolicy_RetryHostPredicate_TypedConfig{
-						TypedConfig: protocov.ToAny(&previoushost.PreviousHostsPredicate{}),
-					},
+	rr := route.Traffic.Retry
+	rp := &routev3.RetryPolicy{
+		RetryOn:              retryDefaultRetryOn,
+		RetriableStatusCodes: []uint32{retryDefaultRetriableStatusCode},
+		NumRetries:           &wrapperspb.UInt32Value{Value: retryDefaultNumRetries},
+		RetryHostPredicate: []*routev3.RetryPolicy_RetryHostPredicate{
+			{
+				Name: "envoy.retry_host_predicates.previous_hosts",
+				ConfigType: &routev3.RetryPolicy_RetryHostPredicate_TypedConfig{
+					TypedConfig: protocov.ToAny(&previoushost.PreviousHostsPredicate{}),
 				},
 			},
-			HostSelectionRetryMaxAttempts: 5,
-		}
+		},
+		HostSelectionRetryMaxAttempts: 5,
+	}
 
-		if rr.NumRetries != nil {
-			rp.NumRetries = &wrapperspb.UInt32Value{Value: *rr.NumRetries}
-		}
+	if rr.NumRetries != nil {
+		rp.NumRetries = &wrapperspb.UInt32Value{Value: *rr.NumRetries}
+	}
 
-		if rr.RetryOn != nil {
-			if rr.RetryOn.Triggers != nil && len(rr.RetryOn.Triggers) > 0 {
-				if ro, err := buildRetryOn(rr.RetryOn.Triggers); err == nil {
-					rp.RetryOn = ro
-				} else {
-					return nil, err
-				}
+	if rr.RetryOn != nil {
+		if rr.RetryOn.Triggers != nil && len(rr.RetryOn.Triggers) > 0 {
+			if ro, err := buildRetryOn(rr.RetryOn.Triggers); err == nil {
+				rp.RetryOn = ro
+			} else {
+				return nil, err
 			}
+		}
 
-			if rr.RetryOn.HTTPStatusCodes != nil && len(rr.RetryOn.HTTPStatusCodes) > 0 {
-				rp.RetriableStatusCodes = buildRetryStatusCodes(rr.RetryOn.HTTPStatusCodes)
-			}
+		if rr.RetryOn.HTTPStatusCodes != nil && len(rr.RetryOn.HTTPStatusCodes) > 0 {
+			rp.RetriableStatusCodes = buildRetryStatusCodes(rr.RetryOn.HTTPStatusCodes)
 		}
+	}
 
-		if rr.PerRetry != nil {
-			if rr.PerRetry.Timeout != nil {
-				rp.PerTryTimeout = durationpb.New(rr.PerRetry.Timeout.Duration)
-			}
+	if rr.PerRetry != nil {
+		if rr.PerRetry.Timeout != nil {
+			rp.PerTryTimeout = durationpb.New(rr.PerRetry.Timeout.Duration)
+		}
 
-			if rr.PerRetry.BackOff != nil {
-				bbo := false
-				rbo := &routev3.RetryPolicy_RetryBackOff{}
-				if rr.PerRetry.BackOff.BaseInterval != nil {
-					rbo.BaseInterval = durationpb.New(rr.PerRetry.BackOff.BaseInterval.Duration)
-					bbo = true
-				}
+		if rr.PerRetry.BackOff != nil {
+			bbo := false
+			rbo := &routev3.RetryPolicy_RetryBackOff{}
+			if rr.PerRetry.BackOff.BaseInterval != nil {
+				rbo.BaseInterval = durationpb.New(rr.PerRetry.BackOff.BaseInterval.Duration)
+				bbo = true
+			}
 
-				if rr.PerRetry.BackOff.MaxInterval != nil {
-					rbo.MaxInterval = durationpb.New(rr.PerRetry.BackOff.MaxInterval.Duration)
-					bbo = true
-				}
+			if rr.PerRetry.BackOff.MaxInterval != nil {
+				rbo.MaxInterval = durationpb.New(rr.PerRetry.BackOff.MaxInterval.Duration)
+				bbo = true
+			}
 
-				if bbo {
-					rp.RetryBackOff = rbo
-				}
+			if bbo {
+				rp.RetryBackOff = rbo
 			}
 		}
-		return rp, nil
 	}
-
-	return nil, nil
+	return rp, nil
 }
 
 func buildRetryStatusCodes(codes []ir.HTTPStatus) []uint32 {
diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go
index a88f4e3fc..cab26d1f9 100644
--- a/internal/xds/translator/translator.go
+++ b/internal/xds/translator/translator.go
@@ -643,21 +643,28 @@ func findXdsEndpoint(tCtx *types.ResourceVersionTable, name string) *endpointv3.
 
 // processXdsCluster processes a xds cluster by its endpoint address type.
 func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute, http1Settings *ir.HTTP1Settings, metrics *ir.Metrics) error {
-	if err := addXdsCluster(tCtx, &xdsClusterArgs{
+	clusterArgs := &xdsClusterArgs{
 		name:              httpRoute.Destination.Name,
 		settings:          httpRoute.Destination.Settings,
 		tSocket:           nil,
 		endpointType:      buildEndpointType(httpRoute.Destination.Settings),
-		loadBalancer:      httpRoute.LoadBalancer,
-		proxyProtocol:     httpRoute.ProxyProtocol,
-		circuitBreaker:    httpRoute.CircuitBreaker,
-		healthCheck:       httpRoute.HealthCheck,
 		http1Settings:     http1Settings,
-		timeout:           httpRoute.Timeout,
-		tcpkeepalive:      httpRoute.TCPKeepalive,
 		metrics:           metrics,
 		useClientProtocol: ptr.Deref(httpRoute.UseClientProtocol, false),
-	}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
+	}
+
+	// Populate traffic features.
+	bt := httpRoute.Traffic
+	if bt != nil {
+		clusterArgs.loadBalancer = bt.LoadBalancer
+		clusterArgs.proxyProtocol = bt.ProxyProtocol
+		clusterArgs.circuitBreaker = bt.CircuitBreaker
+		clusterArgs.healthCheck = bt.HealthCheck
+		clusterArgs.timeout = bt.Timeout
+		clusterArgs.tcpkeepalive = bt.TCPKeepalive
+	}
+
+	if err := addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) {
 		return err
 	}
 
diff --git a/site/content/en/contributions/design/eg-metrics.md b/site/content/en/contributions/design/eg-metrics.md
index 0ca0e7229..6b27bbac7 100644
--- a/site/content/en/contributions/design/eg-metrics.md
+++ b/site/content/en/contributions/design/eg-metrics.md
@@ -6,7 +6,7 @@ title: "Control Plane Observability: Metrics"
 This document aims to cover all aspects of envoy gateway control plane metrics observability.
 
 {{% alert title="Note" color="secondary" %}}
-**Data plane** observability (while important) is outside of scope for this document. For dataplane observability, refer to [here](../metrics).
+**Data plane** observability (while important) is outside of scope for this document. For data plane observability, refer to [here](./proxy-metrics).
 {{% /alert %}}
 
 ## Current State
@@ -100,7 +100,7 @@ New APIs will be added to Envoy Gateway config, which are used to manage Control
 
 ### EnvoyGatewayTelemetry
 
-``` go
+```go
 // EnvoyGatewayTelemetry defines telemetry configurations for envoy gateway control plane.
 // Control plane will focus on metrics observability telemetry and tracing telemetry later.
 type EnvoyGatewayTelemetry struct {
@@ -113,7 +113,7 @@ type EnvoyGatewayTelemetry struct {
 
 > Prometheus will be exposed on 0.0.0.0:19001, which is not supported to be configured yet.
 
-``` go
+```go
 // EnvoyGatewayMetrics defines control plane push/pull metrics configurations.
 type EnvoyGatewayMetrics struct {
 	// Sinks defines the metric sinks where metrics are sent to.
@@ -162,7 +162,7 @@ type EnvoyGatewayPrometheusProvider struct {
 
 + The following is an example to disable prometheus metric.
 
-``` yaml
+```yaml
 apiVersion: gateway.envoyproxy.io/v1alpha1
 kind: EnvoyGateway
 gateway:
@@ -180,7 +180,7 @@ telemetry:
 
 + The following is an example to send metric via Open Telemetry sink to OTEL gRPC Collector.
 
-``` yaml
+```yaml
 apiVersion: gateway.envoyproxy.io/v1alpha1
 kind: EnvoyGateway
 gateway:
@@ -202,7 +202,7 @@ telemetry:
 
 + The following is an example to disable prometheus metric and send metric via Open Telemetry sink to OTEL HTTP Collector at the same time.
 
-``` yaml
+```yaml
 apiVersion: gateway.envoyproxy.io/v1alpha1
 kind: EnvoyGateway
 gateway:
diff --git a/site/content/en/contributions/design/accesslog.md b/site/content/en/contributions/design/proxy-accesslog.md
similarity index 96%
rename from site/content/en/contributions/design/accesslog.md
rename to site/content/en/contributions/design/proxy-accesslog.md
index a229d5f6e..7557e97ad 100644
--- a/site/content/en/contributions/design/accesslog.md
+++ b/site/content/en/contributions/design/proxy-accesslog.md
@@ -1,10 +1,14 @@
 ---
-title: "Observability: Accesslog"
+title: "Data Plane Observability: Accesslog"
 ---
 
 ## Overview
 
-Envoy supports extensible accesslog to different sinks, File, gRPC etc. Envoy supports customizable access log formats using predefined fields as well as arbitrary HTTP request and response headers. Envoy supports several built-in access log filters and extension filters that are registered at runtime.
+Envoy supports extensible accesslog to different sinks, File, gRPC etc. 
+
+Envoy supports customizable access log formats using predefined fields as well as arbitrary HTTP request and response headers. 
+
+Envoy supports several built-in access log filters and extension filters that are registered at runtime.
 
 Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementers such as Envoy Gateway to expose features. Since accesslog is not covered by `Core` or `Extended` APIs, EG should provide an easy to config access log formats and sinks per `EnvoyProxy`.
 
diff --git a/site/content/en/contributions/design/metrics.md b/site/content/en/contributions/design/proxy-metrics.md
similarity index 91%
rename from site/content/en/contributions/design/metrics.md
rename to site/content/en/contributions/design/proxy-metrics.md
index 78b05eea9..7ae2f7b30 100644
--- a/site/content/en/contributions/design/metrics.md
+++ b/site/content/en/contributions/design/proxy-metrics.md
@@ -1,7 +1,13 @@
 ---
-title: "Observability: Metrics"
+title: "Data Plane Observability: Metrics"
 ---
 
+This document aims to cover all aspects of envoy gateway data plane metrics observability.
+
+{{% alert title="Note" color="secondary" %}}
+**Control plane** observability (while important) is outside of scope for this document. For control plane observability, refer to [here](./eg-metrics).
+{{% /alert %}}
+
 ## Overview
 
 Envoy provide robust platform for metrics, Envoy support three different kinds of stats: counter, gauges, histograms.
diff --git a/site/content/en/contributions/design/tracing.md b/site/content/en/contributions/design/proxy-tracing.md
similarity index 99%
rename from site/content/en/contributions/design/tracing.md
rename to site/content/en/contributions/design/proxy-tracing.md
index a2790690f..d3542f3b7 100644
--- a/site/content/en/contributions/design/tracing.md
+++ b/site/content/en/contributions/design/proxy-tracing.md
@@ -1,5 +1,5 @@
 ---
-title: "Observability: Tracing"
+title: "Data Plane Observability: Tracing"
 ---
 
 ## Overview
diff --git a/site/content/en/v1.0.1/tasks/security/threat-model.md b/site/content/en/v1.0.1/tasks/security/threat-model.md
index 79a69b482..c1bba3f97 100644
--- a/site/content/en/v1.0.1/tasks/security/threat-model.md
+++ b/site/content/en/v1.0.1/tasks/security/threat-model.md
@@ -528,7 +528,7 @@ When considering internal threat actors, we chose to follow the [security model]
 
  **Threat**: Threat actors establish persistence and move laterally through the cluster unnoticed.
 
- **Recommendation**: Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.
+ **Recommendation**: Configure [access logging](../../../contributions/design/proxy-accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.
 
  Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR).
 
@@ -612,7 +612,7 @@ Set runAsUser and runAsGroup security context options to specific UIDs (e.g., ru
 |EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.<br/><br/>| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway<br/><br/>|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
 |EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.<br/><br/>| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.<br/><br/>|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 |EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.<br/><br/>| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.<br/><br/>|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.<br/><br/>| Threat actors establish persistence and move laterally through the cluster unnoticed.<br/><br/>|Low| Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.<br/><br/> Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.<br/><br/>| Threat actors establish persistence and move laterally through the cluster unnoticed.<br/><br/>|Low| Configure [access logging](../../../contributions/design/proxy-accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.<br/><br/> Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
 |EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.<br/><br/>| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.<br/><br/>|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.<br/><br/> Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
 |EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.<br/><br/>| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).<br/><br/>|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.<br/><br/> Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
 |EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
diff --git a/tools/src/golangci-lint/go.mod b/tools/src/golangci-lint/go.mod
index c4185482b..45f2ecfe2 100644
--- a/tools/src/golangci-lint/go.mod
+++ b/tools/src/golangci-lint/go.mod
@@ -2,12 +2,12 @@ module local
 
 go 1.22.3
 
-require github.com/golangci/golangci-lint v1.58.0
+require github.com/golangci/golangci-lint v1.58.1
 
 require (
 	4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
 	4d63.com/gochecknoglobals v0.2.1 // indirect
-	github.com/4meepo/tagalign v1.3.3 // indirect
+	github.com/4meepo/tagalign v1.3.4 // indirect
 	github.com/Abirdcfly/dupword v0.0.14 // indirect
 	github.com/Antonboom/errname v0.1.13 // indirect
 	github.com/Antonboom/nilnil v0.1.8 // indirect
@@ -48,7 +48,7 @@ require (
 	github.com/firefart/nonamedreturns v1.0.5 // indirect
 	github.com/fsnotify/fsnotify v1.5.4 // indirect
 	github.com/fzipp/gocyclo v0.6.0 // indirect
-	github.com/ghostiam/protogetter v0.3.5 // indirect
+	github.com/ghostiam/protogetter v0.3.6 // indirect
 	github.com/go-critic/go-critic v0.11.3 // indirect
 	github.com/go-toolsmith/astcast v1.1.0 // indirect
 	github.com/go-toolsmith/astcopy v1.1.0 // indirect
@@ -176,9 +176,9 @@ require (
 	golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
 	golang.org/x/mod v0.17.0 // indirect
 	golang.org/x/sync v0.7.0 // indirect
-	golang.org/x/sys v0.19.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
-	golang.org/x/tools v0.20.0 // indirect
+	golang.org/x/tools v0.21.0 // indirect
 	google.golang.org/protobuf v1.33.0 // indirect
 	gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
diff --git a/tools/src/golangci-lint/go.sum b/tools/src/golangci-lint/go.sum
index e0f706803..ad72e8906 100644
--- a/tools/src/golangci-lint/go.sum
+++ b/tools/src/golangci-lint/go.sum
@@ -35,8 +35,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-github.com/4meepo/tagalign v1.3.3 h1:ZsOxcwGD/jP4U/aw7qeWu58i7dwYemfy5Y+IF1ACoNw=
-github.com/4meepo/tagalign v1.3.3/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE=
+github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8=
+github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0=
 github.com/Abirdcfly/dupword v0.0.14 h1:3U4ulkc8EUo+CaT105/GJ1BQwtgyj6+VaBVbAX11Ba8=
 github.com/Abirdcfly/dupword v0.0.14/go.mod h1:VKDAbxdY8YbKUByLGg8EETzYSuC4crm9WwI6Y3S0cLI=
 github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHOVvM=
@@ -147,8 +147,8 @@ github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwV
 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
 github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
 github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
-github.com/ghostiam/protogetter v0.3.5 h1:+f7UiF8XNd4w3a//4DnusQ2SZjPkUjxkMEfjbxOK4Ug=
-github.com/ghostiam/protogetter v0.3.5/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw=
+github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk=
+github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw=
 github.com/go-critic/go-critic v0.11.3 h1:SJbYD/egY1noYjTMNTlhGaYlfQ77rQmrNH7h+gtn0N0=
 github.com/go-critic/go-critic v0.11.3/go.mod h1:Je0h5Obm1rR5hAGA9mP2PDiOOk53W+n7pyvXErFKIgI=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -226,8 +226,8 @@ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9
 github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
 github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e h1:ULcKCDV1LOZPFxGZaA6TlQbiM3J2GCPnkx/bGF6sX/g=
 github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM=
-github.com/golangci/golangci-lint v1.58.0 h1:r8duFARMJ0VdSM9tDXAdt2+f57dfZQmagvYX6kmkUKQ=
-github.com/golangci/golangci-lint v1.58.0/go.mod h1:WAY3BnSLvTUEv41Q0v3ZFzNybLRF+a7Vd9Da8Jx9Eqo=
+github.com/golangci/golangci-lint v1.58.1 h1:IYKjkt7nofq/mYXiDUyJiBZQi5kxD0jPCjBy6VXxjz8=
+github.com/golangci/golangci-lint v1.58.1/go.mod h1:IX9uSbhwDDOVTcceKZWmshlally+fOQYv1pZhIJCMNw=
 github.com/golangci/misspell v0.5.1 h1:/SjR1clj5uDjNLwYzCahHwIOPmQgoH04AyQIiWGbhCM=
 github.com/golangci/misspell v0.5.1/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
 github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA=
@@ -675,8 +675,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
 golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
-golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -752,8 +752,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
-golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -836,8 +836,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
 golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
 golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
-golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
+golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
+golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=


Test patch:
diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml
index 66bf96ebd..e812062f3 100644
--- a/.github/workflows/build_and_test.yaml
+++ b/.github/workflows/build_and_test.yaml
@@ -20,7 +20,7 @@ jobs:
   lint:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
     # Generate the installation manifests first, so it can check
     # for errors while running `make -k lint`
@@ -31,21 +31,21 @@ jobs:
   gen-check:
     runs-on: ubuntu-22.04
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
     - run: make -k gen-check
 
   license-check:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
     - run: make -k licensecheck
 
   coverage-test:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     # test
@@ -63,7 +63,7 @@ jobs:
     runs-on: ubuntu-latest
     needs: [lint, gen-check, license-check, coverage-test]
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     - name: Build EG Multiarch Binaries
@@ -82,7 +82,7 @@ jobs:
       matrix:
         version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ]
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     - name: Download EG Binaries
@@ -110,7 +110,7 @@ jobs:
       matrix:
         version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ]
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     - name: Download EG Binaries
@@ -135,7 +135,7 @@ jobs:
     runs-on: ubuntu-latest
     needs: [conformance-test, e2e-test]
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     - name: Download EG Binaries
diff --git a/.github/workflows/latest_release.yaml b/.github/workflows/latest_release.yaml
index 9a3f8b468..5560014ba 100644
--- a/.github/workflows/latest_release.yaml
+++ b/.github/workflows/latest_release.yaml
@@ -22,7 +22,7 @@ jobs:
     permissions:
       contents: write
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b  # v4.1.4
+    - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b  # v4.1.5
     - uses: ./tools/github-actions/setup-deps
 
     - name: Generate Release Manifests
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml
index b6cf93163..c5ad9495b 100755
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml
@@ -232,14 +232,15 @@ xdsIR:
             weight: 1
         hostname: gateway.envoyproxy.io
         isHTTP2: false
-        loadBalancer:
-          consistentHash:
-            sourceIP: true
         name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
         pathMatch:
           distinct: false
           name: ""
           prefix: /foo
+        traffic:
+          loadBalancer:
+            consistentHash:
+              sourceIP: true
       - backendWeights:
           invalid: 0
           valid: 0
@@ -254,16 +255,17 @@ xdsIR:
             weight: 1
         hostname: gateway.envoyproxy.io
         isHTTP2: false
-        loadBalancer:
-          random: {}
         name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
         pathMatch:
           distinct: false
           name: ""
           prefix: /bar
-        timeout:
-          http:
-            connectionIdleTimeout: 21s
-            maxConnectionDuration: 22s
-          tcp:
-            connectTimeout: 20s
+        traffic:
+          loadBalancer:
+            random: {}
+          timeout:
+            http:
+              connectionIdleTimeout: 21s
+              maxConnectionDuration: 22s
+            tcp:
+              connectTimeout: 20s
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
index 41088add2..edbf09d03 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
@@ -557,6 +557,7 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
+        traffic: {}
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -584,6 +585,7 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/envoy-gateway/grpcroute-1/rule/0/match/0/*
+        traffic: {}
     tcp:
     - address: 0.0.0.0
       name: envoy-gateway/gateway-2/tcp
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml
index 7d7867841..31566cafd 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml
@@ -351,16 +351,17 @@ xdsIR:
               port: 8080
             protocol: GRPC
             weight: 1
-        faultInjection:
-          abort:
-            grpcStatus: 14
-            percentage: 100
-          delay:
-            fixedDelay: 5.4s
-            percentage: 80
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+        traffic:
+          faultInjection:
+            abort:
+              grpcStatus: 14
+              percentage: 100
+            delay:
+              fixedDelay: 5.4s
+              percentage: 80
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -388,10 +389,6 @@ xdsIR:
               port: 8080
             protocol: HTTP
             weight: 1
-        faultInjection:
-          abort:
-            httpStatus: 14
-            percentage: 0.01
         hostname: gateway.envoyproxy.io
         isHTTP2: false
         name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
@@ -399,6 +396,11 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /route2
+        traffic:
+          faultInjection:
+            abort:
+              httpStatus: 14
+              percentage: 0.01
       - backendWeights:
           invalid: 0
           valid: 0
@@ -411,13 +413,6 @@ xdsIR:
               port: 8080
             protocol: HTTP
             weight: 1
-        faultInjection:
-          abort:
-            httpStatus: 500
-            percentage: 100
-          delay:
-            fixedDelay: 5.4s
-            percentage: 80
         hostname: gateway.envoyproxy.io
         isHTTP2: false
         name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
@@ -425,3 +420,11 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
+        traffic:
+          faultInjection:
+            abort:
+              httpStatus: 500
+              percentage: 100
+            delay:
+              fixedDelay: 5.4s
+              percentage: 80
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml
index 5711eea32..2f43d16b4 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml
@@ -156,4 +156,5 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
+        traffic: {}
         useClientProtocol: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml
index aa471f547..b3f265b9b 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml
@@ -266,12 +266,6 @@ xdsIR:
       - backendWeights:
           invalid: 0
           valid: 0
-        circuitBreaker:
-          maxConnections: 2048
-          maxParallelRequests: 4294967295
-          maxParallelRetries: 1024
-          maxPendingRequests: 1
-          maxRequestsPerConnection: 1
         destination:
           name: grpcroute/default/grpcroute-1/rule/0
           settings:
@@ -284,6 +278,13 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+        traffic:
+          circuitBreaker:
+            maxConnections: 2048
+            maxParallelRequests: 4294967295
+            maxParallelRetries: 1024
+            maxPendingRequests: 1
+            maxRequestsPerConnection: 1
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -302,12 +303,6 @@ xdsIR:
       - backendWeights:
           invalid: 0
           valid: 0
-        circuitBreaker:
-          maxConnections: 42
-          maxParallelRequests: 42
-          maxParallelRetries: 24
-          maxPendingRequests: 42
-          maxRequestsPerConnection: 42
         destination:
           name: httproute/default/httproute-1/rule/0
           settings:
@@ -324,3 +319,10 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
+        traffic:
+          circuitBreaker:
+            maxConnections: 42
+            maxParallelRequests: 42
+            maxParallelRetries: 24
+            maxPendingRequests: 42
+            maxRequestsPerConnection: 42
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
index b49ec2daf..ee23bed19 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
@@ -483,32 +483,33 @@ xdsIR:
               port: 8080
             protocol: GRPC
             weight: 1
-        healthCheck:
-          active:
-            healthyThreshold: 1
-            http:
-              expectedResponse:
-                binary: RXZlcnl0aGluZyBPSw==
-              expectedStatuses:
-              - 200
-              - 300
-              host: '*'
-              method: GET
-              path: /healthz
-            interval: 3s
-            timeout: 500ms
-            unhealthyThreshold: 3
-          passive:
-            baseEjectionTime: 2m40s
-            consecutive5XxErrors: 5
-            consecutiveGatewayErrors: 0
-            consecutiveLocalOriginFailures: 5
-            interval: 2s
-            maxEjectionPercent: 100
-            splitExternalLocalOriginErrors: false
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+        traffic:
+          healthCheck:
+            active:
+              healthyThreshold: 1
+              http:
+                expectedResponse:
+                  binary: RXZlcnl0aGluZyBPSw==
+                expectedStatuses:
+                - 200
+                - 300
+                host: '*'
+                method: GET
+                path: /healthz
+              interval: 3s
+              timeout: 500ms
+              unhealthyThreshold: 3
+            passive:
+              baseEjectionTime: 2m40s
+              consecutive5XxErrors: 5
+              consecutiveGatewayErrors: 0
+              consecutiveLocalOriginFailures: 5
+              interval: 2s
+              maxEjectionPercent: 100
+              splitExternalLocalOriginErrors: false
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -536,25 +537,6 @@ xdsIR:
               port: 8080
             protocol: HTTP
             weight: 1
-        healthCheck:
-          active:
-            healthyThreshold: 3
-            interval: 5s
-            tcp:
-              receive:
-                text: pong
-              send:
-                text: ping
-            timeout: 1s
-            unhealthyThreshold: 3
-          passive:
-            baseEjectionTime: 10s
-            consecutive5XxErrors: 5
-            consecutiveGatewayErrors: 0
-            consecutiveLocalOriginFailures: 5
-            interval: 10s
-            maxEjectionPercent: 10
-            splitExternalLocalOriginErrors: false
         hostname: gateway.envoyproxy.io
         isHTTP2: false
         name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
@@ -562,6 +544,26 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /v2
+        traffic:
+          healthCheck:
+            active:
+              healthyThreshold: 3
+              interval: 5s
+              tcp:
+                receive:
+                  text: pong
+                send:
+                  text: ping
+              timeout: 1s
+              unhealthyThreshold: 3
+            passive:
+              baseEjectionTime: 10s
+              consecutive5XxErrors: 5
+              consecutiveGatewayErrors: 0
+              consecutiveLocalOriginFailures: 5
+              interval: 10s
+              maxEjectionPercent: 10
+              splitExternalLocalOriginErrors: false
       - backendWeights:
           invalid: 0
           valid: 0
@@ -574,25 +576,6 @@ xdsIR:
               port: 8080
             protocol: HTTP
             weight: 1
-        healthCheck:
-          active:
-            healthyThreshold: 1
-            interval: 3s
-            tcp:
-              receive:
-                binary: RXZlcnl0aGluZyBPSw==
-              send:
-                binary: cGluZw==
-            timeout: 1s
-            unhealthyThreshold: 3
-          passive:
-            baseEjectionTime: 2m40s
-            consecutive5XxErrors: 5
-            consecutiveGatewayErrors: 0
-            consecutiveLocalOriginFailures: 5
-            interval: 8ms
-            maxEjectionPercent: 11
-            splitExternalLocalOriginErrors: false
         hostname: gateway.envoyproxy.io
         isHTTP2: false
         name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
@@ -600,6 +583,26 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /v3
+        traffic:
+          healthCheck:
+            active:
+              healthyThreshold: 1
+              interval: 3s
+              tcp:
+                receive:
+                  binary: RXZlcnl0aGluZyBPSw==
+                send:
+                  binary: cGluZw==
+              timeout: 1s
+              unhealthyThreshold: 3
+            passive:
+              baseEjectionTime: 2m40s
+              consecutive5XxErrors: 5
+              consecutiveGatewayErrors: 0
+              consecutiveLocalOriginFailures: 5
+              interval: 8ms
+              maxEjectionPercent: 11
+              splitExternalLocalOriginErrors: false
       - backendWeights:
           invalid: 0
           valid: 0
@@ -612,29 +615,6 @@ xdsIR:
               port: 8080
             protocol: HTTP
             weight: 1
-        healthCheck:
-          active:
-            healthyThreshold: 3
-            http:
-              expectedResponse:
-                text: pong
-              expectedStatuses:
-              - 200
-              - 201
-              host: gateway.envoyproxy.io
-              method: GET
-              path: /healthz
-            interval: 5s
-            timeout: 1s
-            unhealthyThreshold: 3
-          passive:
-            baseEjectionTime: 2m30s
-            consecutive5XxErrors: 5
-            consecutiveGatewayErrors: 0
-            consecutiveLocalOriginFailures: 5
-            interval: 1s
-            maxEjectionPercent: 100
-            splitExternalLocalOriginErrors: false
         hostname: gateway.envoyproxy.io
         isHTTP2: false
         name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
@@ -642,3 +622,27 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
+        traffic:
+          healthCheck:
+            active:
+              healthyThreshold: 3
+              http:
+                expectedResponse:
+                  text: pong
+                expectedStatuses:
+                - 200
+                - 201
+                host: gateway.envoyproxy.io
+                method: GET
+                path: /healthz
+              interval: 5s
+              timeout: 1s
+              unhealthyThreshold: 3
+            passive:
+              baseEjectionTime: 2m30s
+              consecutive5XxErrors: 5
+              consecutiveGatewayErrors: 0
+              consecutiveLocalOriginFailures: 5
+              interval: 1s
+              maxEjectionPercent: 100
+              splitExternalLocalOriginErrors: false
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml
index d308794c0..6114cd008 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml
@@ -374,9 +374,10 @@ xdsIR:
             weight: 1
         hostname: '*'
         isHTTP2: true
-        loadBalancer:
-          random: {}
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+        traffic:
+          loadBalancer:
+            random: {}
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -406,15 +407,16 @@ xdsIR:
             weight: 1
         hostname: gateway.envoyproxy.io
         isHTTP2: false
-        loadBalancer:
-          leastRequest:
-            slowStart:
-              window: 5m0s
         name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
         pathMatch:
           distinct: false
           name: ""
           prefix: /test2
+        traffic:
+          loadBalancer:
+            leastRequest:
+              slowStart:
+                window: 5m0s
       - backendWeights:
           invalid: 0
           valid: 0
@@ -429,11 +431,12 @@ xdsIR:
             weight: 1
         hostname: gateway.envoyproxy.io
         isHTTP2: false
-        loadBalancer:
-          consistentHash:
-            sourceIP: true
         name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
         pathMatch:
           distinct: false
           name: ""
           prefix: /
+        traffic:
+          loadBalancer:
+            consistentHash:
+              sourceIP: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml
index dcd818488..c55cf6333 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml
@@ -179,34 +179,35 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        rateLimit:
-          local:
-            default:
-              requests: 4294967295
-              unit: Second
-            rules:
-            - headerMatches:
-              - distinct: false
-                exact: one
-                name: x-user-id
-              - distinct: false
-                exact: foo
-                name: x-org-id
-              limit:
-                requests: 10
-                unit: Hour
-            - cidrMatch:
-                cidr: 192.168.0.0/16
-                distinct: false
-                ipv6: false
-                maskLen: 16
-              headerMatches:
-              - distinct: false
-                exact: two
-                name: x-user-id
-              - distinct: false
-                exact: bar
-                name: x-org-id
-              limit:
-                requests: 10
-                unit: Minute
+        traffic:
+          rateLimit:
+            local:
+              default:
+                requests: 4294967295
+                unit: Second
+              rules:
+              - headerMatches:
+                - distinct: false
+                  exact: one
+                  name: x-user-id
+                - distinct: false
+                  exact: foo
+                  name: x-org-id
+                limit:
+                  requests: 10
+                  unit: Hour
+              - cidrMatch:
+                  cidr: 192.168.0.0/16
+                  distinct: false
+                  ipv6: false
+                  maskLen: 16
+                headerMatches:
+                - distinct: false
+                  exact: two
+                  name: x-user-id
+                - distinct: false
+                  exact: bar
+                  name: x-org-id
+                limit:
+                  requests: 10
+                  unit: Minute
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml
index b331cd6fa..9c9d73f35 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml
@@ -182,34 +182,35 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        rateLimit:
-          local:
-            default:
-              requests: 10
-              unit: Minute
-            rules:
-            - headerMatches:
-              - distinct: false
-                exact: one
-                name: x-user-id
-              - distinct: false
-                exact: foo
-                name: x-org-id
-              limit:
-                requests: 10
-                unit: Hour
-            - cidrMatch:
-                cidr: 192.168.0.0/16
-                distinct: false
-                ipv6: false
-                maskLen: 16
-              headerMatches:
-              - distinct: false
-                exact: two
-                name: x-user-id
-              - distinct: false
-                exact: bar
-                name: x-org-id
-              limit:
+        traffic:
+          rateLimit:
+            local:
+              default:
                 requests: 10
                 unit: Minute
+              rules:
+              - headerMatches:
+                - distinct: false
+                  exact: one
+                  name: x-user-id
+                - distinct: false
+                  exact: foo
+                  name: x-org-id
+                limit:
+                  requests: 10
+                  unit: Hour
+              - cidrMatch:
+                  cidr: 192.168.0.0/16
+                  distinct: false
+                  ipv6: false
+                  maskLen: 16
+                headerMatches:
+                - distinct: false
+                  exact: two
+                  name: x-user-id
+                - distinct: false
+                  exact: bar
+                  name: x-org-id
+                limit:
+                  requests: 10
+                  unit: Minute
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml
index 8e6332a01..92245edd5 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml
@@ -270,8 +270,9 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
-        proxyProtocol:
-          version: V1
+        traffic:
+          proxyProtocol:
+            version: V1
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -306,5 +307,6 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        proxyProtocol:
-          version: V2
+        traffic:
+          proxyProtocol:
+            version: V2
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
index d3d6c8eb5..7a8ea390f 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
@@ -290,18 +290,19 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
-        rateLimit:
-          global:
-            rules:
-            - headerMatches:
-              - distinct: false
-                exact: one
-                name: x-user-id
-              - distinct: true
-                name: x-org-id
-              limit:
-                requests: 10
-                unit: Hour
+        traffic:
+          rateLimit:
+            global:
+              rules:
+              - headerMatches:
+                - distinct: false
+                  exact: one
+                  name: x-user-id
+                - distinct: true
+                  name: x-org-id
+                limit:
+                  requests: 10
+                  unit: Hour
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -336,15 +337,16 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        rateLimit:
-          global:
-            rules:
-            - cidrMatch:
-                cidr: 192.168.0.0/16
-                distinct: true
-                ipv6: false
-                maskLen: 16
-              headerMatches: []
-              limit:
-                requests: 20
-                unit: Hour
+        traffic:
+          rateLimit:
+            global:
+              rules:
+              - cidrMatch:
+                  cidr: 192.168.0.0/16
+                  distinct: true
+                  ipv6: false
+                  maskLen: 16
+                headerMatches: []
+                limit:
+                  requests: 20
+                  unit: Hour
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml
index ae83655a6..e2db512f8 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml
@@ -289,15 +289,16 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
-        retry:
-          perRetry:
-            backOff:
-              baseInterval: 100ms
-              maxInterval: 10s
-            timeout: 250ms
-          retryOn:
-            triggers:
-            - cancelled
+        traffic:
+          retry:
+            perRetry:
+              backOff:
+                baseInterval: 100ms
+                maxInterval: 10s
+              timeout: 250ms
+            retryOn:
+              triggers:
+              - cancelled
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -332,17 +333,18 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        retry:
-          numRetries: 5
-          perRetry:
-            backOff:
-              baseInterval: 100ms
-              maxInterval: 10s
-            timeout: 250ms
-          retryOn:
-            httpStatusCodes:
-            - 429
-            - 503
-            triggers:
-            - connect-failure
-            - retriable-status-codes
+        traffic:
+          retry:
+            numRetries: 5
+            perRetry:
+              backOff:
+                baseInterval: 100ms
+                maxInterval: 10s
+              timeout: 250ms
+            retryOn:
+              httpStatusCodes:
+              - 429
+              - 503
+              triggers:
+              - connect-failure
+              - retriable-status-codes
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml
index c9a22a833..ad6bbe269 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml
@@ -182,10 +182,6 @@ xdsIR:
       - backendWeights:
           invalid: 0
           valid: 0
-        circuitBreaker:
-          maxConnections: 2048
-          maxParallelRequests: 4294967295
-          maxPendingRequests: 1
         destination:
           name: httproute/default/httproute-1/rule/0
           settings:
@@ -202,6 +198,11 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
+        traffic:
+          circuitBreaker:
+            maxConnections: 2048
+            maxParallelRequests: 4294967295
+            maxPendingRequests: 1
       - backendWeights:
           invalid: 0
           valid: 0
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml
index eb796b42f..902cdd313 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml
@@ -274,10 +274,11 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
-        tcpKeepalive:
-          idleTime: 1200
-          interval: 60
-          probes: 3
+        traffic:
+          tcpKeepalive:
+            idleTime: 1200
+            interval: 60
+            probes: 3
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -312,7 +313,8 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        tcpKeepalive:
-          idleTime: 10
-          interval: 1800
-          probes: 6
+        traffic:
+          tcpKeepalive:
+            idleTime: 10
+            interval: 1800
+            probes: 6
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml
index 27ed1f540..b7dc2f6a0 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml
@@ -278,12 +278,13 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
-        timeout:
-          http:
-            connectionIdleTimeout: 16s
-            maxConnectionDuration: 17s
-          tcp:
-            connectTimeout: 15s
+        traffic:
+          timeout:
+            http:
+              connectionIdleTimeout: 16s
+              maxConnectionDuration: 17s
+            tcp:
+              connectTimeout: 15s
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -318,9 +319,10 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        timeout:
-          http:
-            connectionIdleTimeout: 21s
-            maxConnectionDuration: 22s
-          tcp:
-            connectTimeout: 20s
+        traffic:
+          timeout:
+            http:
+              connectionIdleTimeout: 21s
+              maxConnectionDuration: 22s
+            tcp:
+              connectTimeout: 20s
diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml
index b6093872e..3a85ecb7c 100644
--- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml
@@ -163,6 +163,7 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        timeout:
-          http:
-            requestTimeout: 1s
+        traffic:
+          timeout:
+            http:
+              requestTimeout: 1s
diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml
index 2f060c2db..097b37b51 100644
--- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml
@@ -279,12 +279,13 @@ xdsIR:
         hostname: '*'
         isHTTP2: true
         name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
-        timeout:
-          http:
-            connectionIdleTimeout: 16s
-            maxConnectionDuration: 17s
-          tcp:
-            connectTimeout: 15s
+        traffic:
+          timeout:
+            http:
+              connectionIdleTimeout: 16s
+              maxConnectionDuration: 17s
+            tcp:
+              connectTimeout: 15s
   envoy-gateway/gateway-2:
     accessLog:
       text:
@@ -319,9 +320,9 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        timeout:
-          http:
-            maxConnectionDuration: 22s
-            requestTimeout: 1s
-          tcp:
-            connectTimeout: 20s
+        traffic:
+          timeout:
+            http:
+              maxConnectionDuration: 22s
+            tcp:
+              connectTimeout: 20s
diff --git a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml
index f56835ccb..33076734d 100644
--- a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml
@@ -129,6 +129,7 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        timeout:
-          http:
-            requestTimeout: 1s
+        traffic:
+          timeout:
+            http:
+              requestTimeout: 1s
diff --git a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml
index 3d3f73076..49c64cfe6 100644
--- a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml
@@ -129,6 +129,7 @@ xdsIR:
           distinct: false
           name: ""
           prefix: /
-        timeout:
-          http:
-            requestTimeout: 5s
+        traffic:
+          timeout:
+            http:
+              requestTimeout: 5s
diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml
index 674289ecd..62df76b1b 100755
--- a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml
+++ b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml
@@ -546,10 +546,11 @@ xdsIR:
             - x-header-7
             - x-header-8
             maxAge: 33m20s
-        tcpKeepalive:
-          idleTime: 1200
-          interval: 60
-          probes: 3
+        traffic:
+          tcpKeepalive:
+            idleTime: 1200
+            interval: 60
+            probes: 3
       timeout:
         http:
           requestReceivedTimeout: 5s
@@ -598,10 +599,11 @@ xdsIR:
             - x-header-7
             - x-header-8
             maxAge: 33m20s
-        tcpKeepalive:
-          idleTime: 1200
-          interval: 60
-          probes: 3
+        traffic:
+          tcpKeepalive:
+            idleTime: 1200
+            interval: 60
+            probes: 3
       timeout:
         http:
           requestReceivedTimeout: 5s
diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml
index d2bc2693c..9c3438bff 100644
--- a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml
+++ b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml
@@ -338,10 +338,11 @@ xdsIR:
             - x-header-7
             - x-header-8
             maxAge: 33m20s
-        tcpKeepalive:
-          idleTime: 1200
-          interval: 60
-          probes: 3
+        traffic:
+          tcpKeepalive:
+            idleTime: 1200
+            interval: 60
+            probes: 3
     - address: 0.0.0.0
       hostnames:
       - '*'
diff --git a/internal/xds/translator/route_test.go b/internal/xds/translator/route_test.go
index ed9198b6c..3d7d6a972 100644
--- a/internal/xds/translator/route_test.go
+++ b/internal/xds/translator/route_test.go
@@ -32,23 +32,39 @@ func Test_buildHashPolicy(t *testing.T) {
 			want:      nil,
 		},
 		{
-			name:      "Nil ConsistentHash in LoadBalancer",
-			httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{}},
-			want:      nil,
+			name: "Nil ConsistentHash in LoadBalancer",
+			httpRoute: &ir.HTTPRoute{
+				Traffic: &ir.TrafficFeatures{
+					LoadBalancer: &ir.LoadBalancer{},
+				},
+			},
+			want: nil,
 		},
 		{
-			name:      "ConsistentHash with nil SourceIP and Header",
-			httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{}}},
-			want:      nil,
+			name: "ConsistentHash with nil SourceIP and Header",
+			httpRoute: &ir.HTTPRoute{
+				Traffic: &ir.TrafficFeatures{
+					LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{}},
+				},
+			},
+			want: nil,
 		},
 		{
-			name:      "ConsistentHash with SourceIP set to false",
-			httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(false)}}},
-			want:      nil,
+			name: "ConsistentHash with SourceIP set to false",
+			httpRoute: &ir.HTTPRoute{
+				Traffic: &ir.TrafficFeatures{
+					LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(false)}},
+				},
+			},
+			want: nil,
 		},
 		{
-			name:      "ConsistentHash with SourceIP set to true",
-			httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(true)}}},
+			name: "ConsistentHash with SourceIP set to true",
+			httpRoute: &ir.HTTPRoute{
+				Traffic: &ir.TrafficFeatures{
+					LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{SourceIP: ptr.To(true)}},
+				},
+			},
 			want: []*routev3.RouteAction_HashPolicy{
 				{
 					PolicySpecifier: &routev3.RouteAction_HashPolicy_ConnectionProperties_{
@@ -60,8 +76,12 @@ func Test_buildHashPolicy(t *testing.T) {
 			},
 		},
 		{
-			name:      "ConsistentHash with Header",
-			httpRoute: &ir.HTTPRoute{LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{Header: &ir.Header{Name: "name"}}}},
+			name: "ConsistentHash with Header",
+			httpRoute: &ir.HTTPRoute{
+				Traffic: &ir.TrafficFeatures{
+					LoadBalancer: &ir.LoadBalancer{ConsistentHash: &ir.ConsistentHash{Header: &ir.Header{Name: "name"}}},
+				},
+			},
 			want: []*routev3.RouteAction_HashPolicy{
 				{
 					PolicySpecifier: &routev3.RouteAction_HashPolicy_Header_{
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml
index 0f3f97496..742805ac2 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/distinct-match.yaml
@@ -8,15 +8,16 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - headerMatches:
-        - name: "x-user-id"
-          distinct: true
-        limit:
-          requests: 5
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - headerMatches:
+          - name: "x-user-id"
+            distinct: true
+          limit:
+            requests: 5
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml
index 7ff820e7b..4fbb48de3 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/distinct-remote-address-match.yaml
@@ -8,17 +8,18 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - cidrMatch:
-          cidr: "192.168.0.0/16"
-          ipv6: false
-          maskLen: 16
-          distinct: true
-        limit:
-          requests: 5
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - cidrMatch:
+            cidr: "192.168.0.0/16"
+            ipv6: false
+            maskLen: 16
+            distinct: true
+          limit:
+            requests: 5
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml b/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml
index ca13b2132..0de76f96e 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/empty-header-matches.yaml
@@ -8,12 +8,13 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - limit:
-          requests: 5
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - limit:
+            requests: 5
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml
index 70531d48a..4e21ae73c 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/masked-remote-address-match.yaml
@@ -8,16 +8,17 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - cidrMatch:
-          cidr: "192.168.0.0/16"
-          ipv6: false
-          maskLen: 16
-        limit:
-          requests: 5
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - cidrMatch:
+            cidr: "192.168.0.0/16"
+            ipv6: false
+            maskLen: 16
+          limit:
+            requests: 5
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml
index 32792f005..3f5dba6a9 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-masked-remote-address-match-with-same-cidr.yaml
@@ -8,16 +8,17 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - cidrMatch:
-          cidr: "192.168.0.10/32"
-          ipv6: false
-          maskLen: 32
-        limit:
-          requests: 15
-          unit: Hour
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - cidrMatch:
+            cidr: "192.168.0.10/32"
+            ipv6: false
+            maskLen: 32
+          limit:
+            requests: 15
+            unit: Hour
   pathMatch:
     exact: "foo/bar"
   destination:
@@ -27,16 +28,17 @@ routes:
       - host: "1.2.3.4"
         port: 50000
 - name: "second-route"
-  rateLimit:
-    global:
-      rules:
-      - cidrMatch:
-          cidr: "192.168.0.10/32"
-          ipv6: false
-          maskLen: 32
-        limit:
-          requests: 300
-          unit: Hour
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - cidrMatch:
+            cidr: "192.168.0.10/32"
+            ipv6: false
+            maskLen: 32
+          limit:
+            requests: 300
+            unit: Hour
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml
index 67de62abb..bebb4cb14 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-matches.yaml
@@ -8,17 +8,18 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - headerMatches:
-        - name: "x-user-id"
-          exact: "one"
-        - name: "x-user-id"
-          exact: "two"
-        limit:
-          requests: 5
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - headerMatches:
+          - name: "x-user-id"
+            exact: "one"
+          - name: "x-user-id"
+            exact: "two"
+          limit:
+            requests: 5
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml
index c5a768c9b..6db5c96e8 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-routes.yaml
@@ -8,27 +8,29 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - headerMatches:
-        - name: "x-user-id"
-          exact: "one"
-        limit:
-          requests: 5
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - headerMatches:
+          - name: "x-user-id"
+            exact: "one"
+          limit:
+            requests: 5
+            unit: second
   pathMatch:
     exact: "foo/baz"
 - name: "second-route"
-  rateLimit:
-    global:
-      rules:
-      - headerMatches:
-        - name: "x-user-id"
-          exact: "two"
-        limit:
-          requests: 10
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - headerMatches:
+          - name: "x-user-id"
+            exact: "two"
+          limit:
+            requests: 10
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml b/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml
index ef9b8d228..3267a695b 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/multiple-rules.yaml
@@ -8,21 +8,22 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - headerMatches:
-        - name: "x-user-id"
-          exact: "one"
-        limit:
-          requests: 5
-          unit: second
-      - headerMatches:
-        - name: "x-user-id"
-          exact: "two"
-        limit:
-          requests: 10
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - headerMatches:
+          - name: "x-user-id"
+            exact: "one"
+          limit:
+            requests: 5
+            unit: second
+        - headerMatches:
+          - name: "x-user-id"
+            exact: "two"
+          limit:
+            requests: 10
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml b/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml
index 8fc933e92..a265cab5c 100644
--- a/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml
+++ b/internal/xds/translator/testdata/in/ratelimit-config/value-match.yaml
@@ -8,15 +8,16 @@ path:
   escapedSlashesAction: UnescapeAndRedirect
 routes:
 - name: "first-route"
-  rateLimit:
-    global:
-      rules:
-      - headerMatches:
-        - name: "x-user-id"
-          exact: "one"
-        limit:
-          requests: 5
-          unit: second
+  traffic:
+    rateLimit:
+      global:
+        rules:
+        - headerMatches:
+          - name: "x-user-id"
+            exact: "one"
+          limit:
+            requests: 5
+            unit: second
   pathMatch:
     exact: "foo/bar"
   destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml b/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml
index a63297e26..f4dd3bbaa 100644
--- a/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/circuit-breaker.yaml
@@ -10,12 +10,13 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    circuitBreaker:
-      maxConnections: 1
-      maxPendingRequests: 1
-      maxParallelRequests: 1
-      maxParallelRetries: 2
-      maxRequestsPerConnection: 10
+    traffic:
+      circuitBreaker:
+        maxConnections: 1
+        maxPendingRequests: 1
+        maxParallelRequests: 1
+        maxParallelRetries: 2
+        maxRequestsPerConnection: 10
     destination:
       name: "first-route-dest"
       settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml
index 06c44b051..6c3cfa3aa 100644
--- a/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/client-timeout.yaml
@@ -20,4 +20,3 @@ http:
       http:
         requestReceivedTimeout: "5s"
         idleTimeout: "10s"
-
diff --git a/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml b/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml
index a99b77d5e..39b351eb6 100644
--- a/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/fault-injection.yaml
@@ -10,10 +10,11 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    faultInjection:
-      abort:
-        httpStatus: 500
-        percentage: 0.01
+    traffic:
+      faultInjection:
+        abort:
+          httpStatus: 500
+          percentage: 0.01
     pathMatch:
       exact: "foo/bar"
     destination:
@@ -24,10 +25,11 @@ http:
           port: 50000
   - name: "second-route"
     hostname: "*"
-    faultInjection:
-      delay:
-        fixedDelay: 5.4s
-        percentage: 80
+    traffic:
+      faultInjection:
+        delay:
+          fixedDelay: 5.4s
+          percentage: 80
     pathMatch:
       exact: "example"
     destination:
@@ -38,13 +40,14 @@ http:
           port: 50000
   - name: "third-route"
     hostname: "*"
-    faultInjection:
-      abort:
-        httpStatus: 500
-        percentage: 100
-      delay:
-        fixedDelay: 5.005s
-        percentage: 100
+    traffic:
+      faultInjection:
+        abort:
+          httpStatus: 500
+          percentage: 100
+        delay:
+          fixedDelay: 5.005s
+          percentage: 100
     pathMatch:
       exact: "test"
     destination:
@@ -55,13 +58,14 @@ http:
           port: 50000
   - name: "fourth-route"
     hostname: "*"
-    faultInjection:
-      abort:
-        grpcStatus: 14
-        percentage: 100
-      delay:
-        fixedDelay: 5.005s
-        percentage: 100
+    traffic:
+      faultInjection:
+        abort:
+          grpcStatus: 14
+          percentage: 100
+        delay:
+          fixedDelay: 5.005s
+          percentage: 100
     pathMatch:
       exact: "test"
     destination:
@@ -72,7 +76,8 @@ http:
           port: 50000
   - name: "fifth-route"
     hostname: "*"
-    faultInjection:
+    traffic:
+      faultInjection: {}
     pathMatch:
       exact: "test"
     destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
index a767bdab2..30ecd2da7 100644
--- a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
@@ -10,28 +10,29 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    healthCheck:
-      active:
-        timeout: "500ms"
-        interval: "3s"
-        unhealthyThreshold: 3
-        healthyThreshold: 1
-        http:
-          host: "*"
-          path: "/healthz"
-          expectedResponse:
-            text: "ok"
-          expectedStatuses:
-          - 200
-          - 300
-      passive:
-        baseEjectionTime: 180s
-        interval: 2s
-        maxEjectionPercent: 100
-        consecutive5XxErrors: 5
-        consecutiveGatewayErrors: 0
-        consecutiveLocalOriginFailures: 5
-        splitExternalLocalOriginErrors: false
+    traffic:
+      healthCheck:
+        active:
+          timeout: "500ms"
+          interval: "3s"
+          unhealthyThreshold: 3
+          healthyThreshold: 1
+          http:
+            host: "*"
+            path: "/healthz"
+            expectedResponse:
+              text: "ok"
+            expectedStatuses:
+            - 200
+            - 300
+        passive:
+          baseEjectionTime: 180s
+          interval: 2s
+          maxEjectionPercent: 100
+          consecutive5XxErrors: 5
+          consecutiveGatewayErrors: 0
+          consecutiveLocalOriginFailures: 5
+          splitExternalLocalOriginErrors: false
     destination:
       name: "first-route-dest"
       settings:
@@ -40,28 +41,29 @@ http:
           port: 50000
   - name: "second-route"
     hostname: "*"
-    healthCheck:
-      active:
-        timeout: "1s"
-        interval: "5s"
-        unhealthyThreshold: 3
-        healthyThreshold: 3
-        http:
-          host: "*"
-          path: "/healthz"
-          expectedResponse:
-            binary: "cG9uZw=="
-          expectedStatuses:
-          - 200
-          - 201
-      passive:
-        baseEjectionTime: 180s
-        interval: 1s
-        maxEjectionPercent: 100
-        consecutive5XxErrors: 5
-        consecutiveGatewayErrors: 0
-        consecutiveLocalOriginFailures: 5
-        splitExternalLocalOriginErrors: false
+    traffic:
+      healthCheck:
+        active:
+          timeout: "1s"
+          interval: "5s"
+          unhealthyThreshold: 3
+          healthyThreshold: 3
+          http:
+            host: "*"
+            path: "/healthz"
+            expectedResponse:
+              binary: "cG9uZw=="
+            expectedStatuses:
+            - 200
+            - 201
+        passive:
+          baseEjectionTime: 180s
+          interval: 1s
+          maxEjectionPercent: 100
+          consecutive5XxErrors: 5
+          consecutiveGatewayErrors: 0
+          consecutiveLocalOriginFailures: 5
+          splitExternalLocalOriginErrors: false
     destination:
       name: "second-route-dest"
       settings:
@@ -70,25 +72,26 @@ http:
           port: 50000
   - name: "third-route"
     hostname: "*"
-    healthCheck:
-      active:
-        timeout: "1s"
-        interval: "5s"
-        unhealthyThreshold: 3
-        healthyThreshold: 3
-        tcp:
-          send:
-            text: "ping"
-          receive:
-            text: "pong"
-      passive:
-        baseEjectionTime: 160s
-        interval: 1s
-        maxEjectionPercent: 100
-        consecutive5XxErrors: 5
-        consecutiveGatewayErrors: 0
-        consecutiveLocalOriginFailures: 5
-        splitExternalLocalOriginErrors: false
+    traffic:
+      healthCheck:
+        active:
+          timeout: "1s"
+          interval: "5s"
+          unhealthyThreshold: 3
+          healthyThreshold: 3
+          tcp:
+            send:
+              text: "ping"
+            receive:
+              text: "pong"
+        passive:
+          baseEjectionTime: 160s
+          interval: 1s
+          maxEjectionPercent: 100
+          consecutive5XxErrors: 5
+          consecutiveGatewayErrors: 0
+          consecutiveLocalOriginFailures: 5
+          splitExternalLocalOriginErrors: false
     destination:
       name: "third-route-dest"
       settings:
@@ -97,25 +100,26 @@ http:
           port: 50000
   - name: "fourth-route"
     hostname: "*"
-    healthCheck:
-      active:
-        timeout: "1s"
-        interval: "5s"
-        unhealthyThreshold: 3
-        healthyThreshold: 3
-        tcp:
-          send:
-            binary: "cGluZw=="
-          receive:
-            binary: "cG9uZw=="
-      passive:
-        baseEjectionTime: 180s
-        interval: 1s
-        maxEjectionPercent: 90
-        consecutive5XxErrors: 5
-        consecutiveGatewayErrors: 0
-        consecutiveLocalOriginFailures: 5
-        splitExternalLocalOriginErrors: true
+    traffic:
+      healthCheck:
+        active:
+          timeout: "1s"
+          interval: "5s"
+          unhealthyThreshold: 3
+          healthyThreshold: 3
+          tcp:
+            send:
+              binary: "cGluZw=="
+            receive:
+              binary: "cG9uZw=="
+        passive:
+          baseEjectionTime: 180s
+          interval: 1s
+          maxEjectionPercent: 90
+          consecutive5XxErrors: 5
+          consecutiveGatewayErrors: 0
+          consecutiveLocalOriginFailures: 5
+          splitExternalLocalOriginErrors: true
     destination:
       name: "fourth-route-dest"
       settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml
index fdd2b84ef..746d49225 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-timeout.yaml
@@ -10,9 +10,10 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    timeout:
-      http:
-        requestTimeout: 5s
+    traffic:
+      timeout:
+        http:
+          requestTimeout: 5s
     headerMatches:
     - name: user
       stringMatch:
@@ -25,9 +26,10 @@ http:
           port: 50000
   - name: "second-route"
     hostname: "*"
-    timeout:
-      http:
-        requestTimeout: 4000s
+    traffic:
+      timeout:
+        http:
+          requestTimeout: 4000s
     destination:
       name: "second-route-dest"
       settings:
@@ -36,9 +38,10 @@ http:
           port: 50001
   - name: "third-route"
     hostname: "*"
-    timeout:
-      http:
-        requestTimeout: 0s
+    traffic:
+      timeout:
+        http:
+          requestTimeout: 0s
     destination:
       name: "third-route-dest"
       settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml
index 7dd532ab4..a706244db 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-with-tlsbundle-multiple-certs.yaml
@@ -56,8 +56,9 @@ http:
       - backendWeights:
           invalid: 0
           valid: 0
-        proxyProtocol:
-          version: "V2"
+        traffic:
+          proxyProtocol:
+            version: "V2"
         destination:
           name: httproute/envoy-gateway/httproute-btls-2/rule/0
           settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml
index a4682250a..008b5b9bd 100644
--- a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml
@@ -10,15 +10,16 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - headerMatches:
-          - name: "x-user-id"
-            exact: "one"
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - headerMatches:
+            - name: "x-user-id"
+              exact: "one"
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "foo/bar"
     destination:
@@ -38,15 +39,16 @@ http:
             uri: https://192.168.1.250/jwt/public-key/jwks.json
   - name: "second-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - headerMatches:
-          - name: "x-user-id"
-            distinct: true
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - headerMatches:
+            - name: "x-user-id"
+              distinct: true
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "example"
     destination:
@@ -57,12 +59,13 @@ http:
           port: 50000
   - name: "third-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "test"
     destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml b/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml
index 9c76ca46b..2d8ef97ef 100644
--- a/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/load-balancer.yaml
@@ -10,8 +10,9 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    loadBalancer:
-      roundRobin: {}
+    traffic:
+      loadBalancer:
+        roundRobin: {}
     destination:
       name: "first-route-dest"
       settings:
@@ -20,8 +21,9 @@ http:
           port: 50000
   - name: "second-route"
     hostname: "*"
-    loadBalancer:
-      random: {}
+    traffic:
+      loadBalancer:
+        random: {}
     destination:
       name: "second-route-dest"
       settings:
@@ -30,8 +32,9 @@ http:
           port: 50000
   - name: "third-route"
     hostname: "*"
-    loadBalancer:
-      leastRequest: {}
+    traffic:
+      loadBalancer:
+        leastRequest: {}
     destination:
       name: "third-route-dest"
       settings:
@@ -40,9 +43,10 @@ http:
           port: 50000
   - name: "fourth-route"
     hostname: "*"
-    loadBalancer:
-      consistentHash:
-        sourceIP: true
+    traffic:
+      loadBalancer:
+        consistentHash:
+          sourceIP: true
     destination:
       name: "fourth-route-dest"
       settings:
@@ -51,10 +55,11 @@ http:
           port: 50000
   - name: "fifth-route"
     hostname: "*"
-    loadBalancer:
-      leastRequest:
-        slowStart:
-          window: 60s
+    traffic:
+      loadBalancer:
+        leastRequest:
+          slowStart:
+            window: 60s
     destination:
       name: "fifth-route-dest"
       settings:
@@ -63,10 +68,11 @@ http:
           port: 50000
   - name: "sixth-route"
     hostname: "*"
-    loadBalancer:
-      roundRobin:
-        slowStart:
-          window: 300s
+    traffic:
+      loadBalancer:
+        roundRobin:
+          slowStart:
+            window: 300s
     destination:
       name: "sixth-route-dest"
       settings:
@@ -75,10 +81,11 @@ http:
           port: 50000
   - name: "seventh-route"
     hostname: "*"
-    loadBalancer:
-      consistentHash:
-        header:
-          name: name
+    traffic:
+      loadBalancer:
+        consistentHash:
+          header:
+            name: name
     destination:
       name: "seventh-route-dest"
       settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml
index 9e818b4d1..fb7baf05c 100644
--- a/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/local-ratelimit.yaml
@@ -10,20 +10,21 @@ http:
   routes:
   - name: "first-route-ratelimit-single-rule"
     hostname: "*"
-    rateLimit:
-      local:
-        default:
-          requests: 10
-          unit: Minute
-        rules:
-        - headerMatches:
-          - name: x-user-id
-            exact: one
-          - name: x-org-id
-            exact: foo
-          limit:
+    traffic:
+      rateLimit:
+        local:
+          default:
             requests: 10
-            unit: Hour
+            unit: Minute
+          rules:
+          - headerMatches:
+            - name: x-user-id
+              exact: one
+            - name: x-org-id
+              exact: foo
+            limit:
+              requests: 10
+              unit: Hour
     pathMatch:
       exact: "foo/bar"
     destination:
@@ -34,31 +35,32 @@ http:
           port: 50000
   - name: "second-route-ratelimit-multiple-rules"
     hostname: "*"
-    rateLimit:
-      local:
-        default:
-          requests: 10
-          unit: Minute
-        rules:
-        - headerMatches:
-          - name: x-user-id
-            exact: one
-          - name: x-org-id
-            exact: foo
-          limit:
-            requests: 10
-            unit: Hour
-        - cidrMatch:
-            cidr: 192.168.0.0/16
-            maskLen: 16
-          headerMatches:
-          - name: x-user-id
-            exact: two
-          - name: x-org-id
-            exact: bar
-          limit:
+    traffic:
+      rateLimit:
+        local:
+          default:
             requests: 10
             unit: Minute
+          rules:
+          - headerMatches:
+            - name: x-user-id
+              exact: one
+            - name: x-org-id
+              exact: foo
+            limit:
+              requests: 10
+              unit: Hour
+          - cidrMatch:
+              cidr: 192.168.0.0/16
+              maskLen: 16
+            headerMatches:
+            - name: x-user-id
+              exact: two
+            - name: x-org-id
+              exact: bar
+            limit:
+              requests: 10
+              unit: Minute
     pathMatch:
       exact: "example"
     destination:
@@ -69,11 +71,12 @@ http:
           port: 50000
   - name: "third-route-ratelimit-no-rule"
     hostname: "*"
-    rateLimit:
-      local:
-        default:
-          requests: 10
-          unit: Minute
+    traffic:
+      rateLimit:
+        local:
+          default:
+            requests: 10
+            unit: Minute
     pathMatch:
       exact: "test"
     destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml b/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml
index adf21ca8f..47df0026b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/proxy-protocol-upstream.yaml
@@ -10,8 +10,9 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    proxyProtocol:
-      version: "V2"
+    traffic:
+      proxyProtocol:
+        version: "V2"
     destination:
       name: "first-route-dest"
       settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml
index 8d9c2f5b4..271d39cfd 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml
@@ -10,15 +10,16 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - headerMatches:
-          - name: "x-user-id"
-            exact: "one"
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - headerMatches:
+            - name: "x-user-id"
+              exact: "one"
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "foo/bar"
     destination:
@@ -29,15 +30,16 @@ http:
           port: 50000
   - name: "second-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - headerMatches:
-          - name: "x-user-id"
-            distinct: true
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - headerMatches:
+            - name: "x-user-id"
+              distinct: true
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "example"
     destination:
@@ -48,12 +50,13 @@ http:
           port: 50000
   - name: "third-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "test"
     destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml
index 56a4b8d48..32f951172 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml
@@ -12,15 +12,16 @@ http:
     routes:
       - name: "first-route"
         hostname: "*"
-        rateLimit:
-          global:
-            rules:
-              - headerMatches:
-                  - name: "x-user-id"
-                    exact: "one"
-                limit:
-                  requests: 5
-                  unit: second
+        traffic:
+          rateLimit:
+            global:
+              rules:
+                - headerMatches:
+                    - name: "x-user-id"
+                      exact: "one"
+                  limit:
+                    requests: 5
+                    unit: second
         pathMatch:
           exact: "foo/bar"
         destination:
@@ -31,15 +32,16 @@ http:
                   port: 50000
       - name: "second-route"
         hostname: "*"
-        rateLimit:
-          global:
-            rules:
-              - headerMatches:
-                  - name: "x-user-id"
-                    distinct: true
-                limit:
-                  requests: 5
-                  unit: second
+        traffic:
+          rateLimit:
+            global:
+              rules:
+                - headerMatches:
+                    - name: "x-user-id"
+                      distinct: true
+                  limit:
+                    requests: 5
+                    unit: second
         pathMatch:
           exact: "example"
         destination:
@@ -50,12 +52,13 @@ http:
                   port: 50000
       - name: "third-route"
         hostname: "*"
-        rateLimit:
-          global:
-            rules:
-              - limit:
-                  requests: 5
-                  unit: second
+        traffic:
+          rateLimit:
+            global:
+              rules:
+                - limit:
+                    requests: 5
+                    unit: second
         pathMatch:
           exact: "test"
         destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml
index 69b3480fc..495fa9b7a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml
@@ -10,15 +10,16 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - cidrMatch:
-            cidr: 192.168.0.0/16
-            maskLen: 16
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - cidrMatch:
+              cidr: 192.168.0.0/16
+              maskLen: 16
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "foo/bar"
     destination:
@@ -29,15 +30,16 @@ http:
           port: 50000
   - name: "second-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - cidrMatch:
-            cidr: 192.168.0.0/24
-            maskLen: 24
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - cidrMatch:
+              cidr: 192.168.0.0/24
+              maskLen: 24
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "example"
     destination:
@@ -48,12 +50,13 @@ http:
           port: 50000
   - name: "third-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "test"
     destination:
@@ -64,16 +67,17 @@ http:
           port: 50000
   - name: "fourth-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - cidrMatch:
-            cidr: 192.168.0.0/16
-            maskLen: 16
-            distinct: true
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - cidrMatch:
+              cidr: 192.168.0.0/16
+              maskLen: 16
+              distinct: true
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "distinct"
     destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml
index 8d9c2f5b4..271d39cfd 100644
--- a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml
@@ -10,15 +10,16 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - headerMatches:
-          - name: "x-user-id"
-            exact: "one"
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - headerMatches:
+            - name: "x-user-id"
+              exact: "one"
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "foo/bar"
     destination:
@@ -29,15 +30,16 @@ http:
           port: 50000
   - name: "second-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - headerMatches:
-          - name: "x-user-id"
-            distinct: true
-          limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - headerMatches:
+            - name: "x-user-id"
+              distinct: true
+            limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "example"
     destination:
@@ -48,12 +50,13 @@ http:
           port: 50000
   - name: "third-route"
     hostname: "*"
-    rateLimit:
-      global:
-        rules:
-        - limit:
-            requests: 5
-            unit: second
+    traffic:
+      rateLimit:
+        global:
+          rules:
+          - limit:
+              requests: 5
+              unit: second
     pathMatch:
       exact: "test"
     destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml
index 7f5938fd6..748335672 100644
--- a/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/retry-partial-invalid.yaml
@@ -10,21 +10,22 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    retry:
-      numRetries: 5
-      retryOn:
-        httpStatusCodes:
-        - 429
-        - 503
-        triggers:
-        - reset
-        - connect-failure
-        - retriable-status-codes
-      perRetry:
-        timeout: 250ms
-        backoff:
-          baseInterval: 100ms
-          maxInterval: 10s
+    traffic:
+      retry:
+        numRetries: 5
+        retryOn:
+          httpStatusCodes:
+          - 429
+          - 503
+          triggers:
+          - reset
+          - connect-failure
+          - retriable-status-codes
+        perRetry:
+          timeout: 250ms
+          backoff:
+            baseInterval: 100ms
+            maxInterval: 10s
     destination:
       name: "first-route-dest"
       settings:
@@ -33,7 +34,8 @@ http:
           port: 50000
   - name: "second-route-defaults"
     hostname: "foo"
-    retry: {}
+    traffic:
+      retry: {}
     destination:
       name: "first-route-dest"
       settings:
@@ -42,10 +44,11 @@ http:
           port: 50000
   - name: "third-route-error"
     hostname: "bar"
-    retry:
-      retryOn:
-        triggers:
-        - this-is-not-a-trigger
+    traffic:
+      retry:
+        retryOn:
+          triggers:
+          - this-is-not-a-trigger
     destination:
       name: "first-route-dest"
       settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/timeout.yaml b/internal/xds/translator/testdata/in/xds-ir/timeout.yaml
index daee154f0..8abc0af3c 100644
--- a/internal/xds/translator/testdata/in/xds-ir/timeout.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/timeout.yaml
@@ -10,12 +10,13 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    timeout:
-      tcp:
-        connectTimeout: "31s"
-      http:
-        connectionIdleTimeout: "32s"
-        maxConnectionDuration: "33s"
+    traffic:
+      timeout:
+        tcp:
+          connectTimeout: "31s"
+        http:
+          connectionIdleTimeout: "32s"
+          maxConnectionDuration: "33s"
     destination:
       name: "first-route-dest"
       settings:
diff --git a/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml b/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml
index bb7febec8..b00f5e55a 100644
--- a/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/upstream-tcpkeepalive.yaml
@@ -10,10 +10,11 @@ http:
   routes:
   - name: "first-route"
     hostname: "*"
-    tcpKeepalive:
-      idleTime: 1200
-      interval: 60
-      probes: 3
+    traffic:
+      tcpKeepalive:
+        idleTime: 1200
+        interval: 60
+        probes: 3
     destination:
       name: "first-route-dest"
       settings:
diff --git a/site/content/en/latest/install/install-helm.md b/site/content/en/latest/install/install-helm.md
index 69efd4539..903abe509 100644
--- a/site/content/en/latest/install/install-helm.md
+++ b/site/content/en/latest/install/install-helm.md
@@ -61,7 +61,11 @@ consideration when debugging.
 
 ## Helm chart customizations
 
-Some of the quick ways of using the helm install command for envoy gateway installation are below. 
+Some of the quick ways of using the helm install command for envoy gateway installation are below.
+
+{{% alert title="Helm Chart Values" color="primary" %}}
+If you want to know all the available fields inside the values.yaml file, please see the [Helm Chart Values](../api).
+{{% /alert %}}
 
 ### Increase the replicas
 
@@ -114,10 +118,6 @@ You can use the below command to install the envoy gateway using values.yaml fil
 helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace -f values.yaml
 ```
 
-{{% alert title="Helm Chart Values" color="primary" %}}
-If you want to know all the available fields inside the values.yaml file, please see the [Helm Chart Values](../api).
-{{% /alert %}}
-
 ## Open Ports
 
 These are the ports used by Envoy Gateway and the managed Envoy Proxy.
diff --git a/site/content/en/latest/tasks/observability/gateway-observability.md b/site/content/en/latest/tasks/observability/gateway-observability.md
new file mode 100644
index 000000000..6409dcee5
--- /dev/null
+++ b/site/content/en/latest/tasks/observability/gateway-observability.md
@@ -0,0 +1,182 @@
+---
+title: "Gateway Observability"
+---
+
+Envoy Gateway provides observability for the ControlPlane and the underlying EnvoyProxy instances.
+This task show you how to config gateway control-plane observability, includes metrics.
+
+## Prerequisites
+
+Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+[OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) offers a vendor-agnostic implementation of how to receive, process and export telemetry data.
+Install OTel-Collector:
+
+```shell
+helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
+helm repo update
+helm upgrade --install otel-collector open-telemetry/opentelemetry-collector -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/otel-collector/helm-values.yaml -n monitoring --create-namespace --version 0.60.0
+```
+
+## Metrics
+
+The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it
+using a `ConfigMap`. In this section, we will update this resource to enable various ways to retrieve metrics
+from Envoy Gateway.
+
+### Retrieve Prometheus Metrics from Envoy Gateway
+
+By default, prometheus metric is enabled. You can directly retrieve metrics from Envoy Gateway:
+
+```shell
+export ENVOY_POD_NAME=$(kubectl get pod -n envoy-gateway-system --selector=control-plane=envoy-gateway,app.kubernetes.io/instance=eg -o jsonpath='{.items[0].metadata.name}')
+kubectl port-forward pod/$ENVOY_POD_NAME -n envoy-gateway-system 19001:19001
+
+# check metrics 
+curl localhost:19001/metrics
+```
+
+The following is an example to disable prometheus metric for Envoy Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: envoy-gateway-config
+  namespace: envoy-gateway-system
+data:
+  envoy-gateway.yaml: |
+    apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: EnvoyGateway
+    provider:
+      type: Kubernetes
+    gateway:
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    telemetry:
+      metrics:
+        prometheus:
+          disable: true
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: envoy-gateway-config
+  namespace: envoy-gateway-system
+data:
+  envoy-gateway.yaml: |
+    apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: EnvoyGateway
+    provider:
+      type: Kubernetes
+    gateway:
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    telemetry:
+      metrics:
+        prometheus:
+          disable: true
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in:
+
+```shell
+kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
+```
+
+### Enable Open Telemetry sink in Envoy Gateway
+
+The following is an example to send metric via Open Telemetry sink to OTEL gRPC Collector.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: envoy-gateway-config
+  namespace: envoy-gateway-system
+data:
+  envoy-gateway.yaml: |
+    apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: EnvoyGateway
+    provider:
+      type: Kubernetes
+    gateway:
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    telemetry:
+      metrics:
+        sinks:
+          - type: OpenTelemetry
+            openTelemetry:
+              host: otel-collector.monitoring.svc.cluster.local
+              port: 4317
+              protocol: grpc
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: envoy-gateway-config
+  namespace: envoy-gateway-system
+data:
+  envoy-gateway.yaml: |
+    apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: EnvoyGateway
+    provider:
+      type: Kubernetes
+    gateway:
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    telemetry:
+      metrics:
+        sinks:
+          - type: OpenTelemetry
+            openTelemetry:
+              host: otel-collector.monitoring.svc.cluster.local
+              port: 4317
+              protocol: grpc
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in:
+
+```shell
+kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
+```
+
+Verify OTel-Collector metrics:
+
+```shell
+export OTEL_POD_NAME=$(kubectl get pod -n monitoring --selector=app.kubernetes.io/name=opentelemetry-collector -o jsonpath='{.items[0].metadata.name}')
+kubectl port-forward pod/$OTEL_POD_NAME -n monitoring 19001:19001
+
+# check metrics 
+curl localhost:19001/metrics
+```
+
+[EnvoyGateway]: ../../api/extension_types#envoygateway
diff --git a/site/content/en/latest/tasks/observability/proxy-observability.md b/site/content/en/latest/tasks/observability/proxy-observability.md
index 5a1800ff3..90cab9193 100644
--- a/site/content/en/latest/tasks/observability/proxy-observability.md
+++ b/site/content/en/latest/tasks/observability/proxy-observability.md
@@ -59,7 +59,7 @@ export ENVOY_POD_NAME=$(kubectl get pod -n envoy-gateway-system --selector=gatew
 kubectl port-forward pod/$ENVOY_POD_NAME -n envoy-gateway-system 19001:19001
 
 # check metrics 
-curl localhost:19001/stats/prometheus  | grep "default/backend/rule/0/match/0-www"
+curl localhost:19001/stats/prometheus  | grep "default/backend/rule/0"
 ```
 
 You can disable metrics by setting the `telemetry.metrics.prometheus.disable` to `true` in the `EnvoyProxy` CRD.
@@ -82,7 +82,7 @@ export OTEL_POD_NAME=$(kubectl get pod -n monitoring --selector=app.kubernetes.i
 kubectl port-forward pod/$OTEL_POD_NAME -n monitoring 19001:19001
 
 # check metrics 
-curl localhost:19001/metrics  | grep "default/backend/rule/0/match/0-www"
+curl localhost:19001/metrics  | grep "default/backend/rule/0"
 ```
 
 ## Logs
diff --git a/site/content/en/latest/tasks/security/threat-model.md b/site/content/en/latest/tasks/security/threat-model.md
index fcf8643e1..cd5927e8d 100644
--- a/site/content/en/latest/tasks/security/threat-model.md
+++ b/site/content/en/latest/tasks/security/threat-model.md
@@ -528,7 +528,7 @@ When considering internal threat actors, we chose to follow the [security model]
 
  **Threat**: Threat actors establish persistence and move laterally through the cluster unnoticed.
 
- **Recommendation**: Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.
+ **Recommendation**: Configure [access logging](../../../contributions/design/proxy-accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.
 
  Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR).
 
@@ -612,7 +612,7 @@ Set runAsUser and runAsGroup security context options to specific UIDs (e.g., ru
 |EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.<br/><br/>| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway<br/><br/>|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
 |EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.<br/><br/>| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.<br/><br/>|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 |EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.<br/><br/>| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.<br/><br/>|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.<br/><br/>| Threat actors establish persistence and move laterally through the cluster unnoticed.<br/><br/>|Low| Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.<br/><br/> Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.<br/><br/>| Threat actors establish persistence and move laterally through the cluster unnoticed.<br/><br/>|Low| Configure [access logging](../../../contributions/design/proxy-accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.<br/><br/> Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
 |EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.<br/><br/>| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.<br/><br/>|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.<br/><br/> Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
 |EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.<br/><br/>| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).<br/><br/>|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.<br/><br/> Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
 |EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |