Repository: envoyproxy/gateway
Pull request #3481 (2024-05-27 04:12:56)

build(deps): bump codespell from 2.2.6 to 2.3.0 in /tools/src/codespell
Bumps [codespell](https://github.com/codespell-project/codespell) from 2.2.6 to 2.3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/codespell-project/codespell/releases">codespell's releases</a>.</em></p>
<blockquote>
<h2>v2.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>[pre-commit.ci] pre-commit autoupdate by <a href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3115">codespell-project/codespell#3115</a></li>
<li>Add schematrion-&gt;schematron by <a href="https://github.com/AirQuick"><code>@​AirQuick</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3116">codespell-project/codespell#3116</a></li>
<li>Add explicit Python 3.12 support by <a href="https://github.com/korverdev"><code>@​korverdev</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3121">codespell-project/codespell#3121</a></li>
<li>Add miscellaneous typos by <a href="https://github.com/korverdev"><code>@​korverdev</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3117">codespell-project/codespell#3117</a></li>
<li>fix: aesthetic(s) should be kept as is by <a href="https://github.com/SimonVerhoeven"><code>@​SimonVerhoeven</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3126">codespell-project/codespell#3126</a></li>
<li>Add more labour* variants by <a href="https://github.com/SimonVerhoeven"><code>@​SimonVerhoeven</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3128">codespell-project/codespell#3128</a></li>
<li>Add additional spelling corrections for prior and variant. by <a href="https://github.com/cfi-gb"><code>@​cfi-gb</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3135">codespell-project/codespell#3135</a></li>
<li>Fix <code>no-commit-to-branch</code> Pre-Commit check by <a href="https://github.com/korverdev"><code>@​korverdev</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3130">codespell-project/codespell#3130</a></li>
<li>[pre-commit.ci] pre-commit autoupdate by <a href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3131">codespell-project/codespell#3131</a></li>
<li>[pre-commit.ci] pre-commit autoupdate by <a href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3155">codespell-project/codespell#3155</a></li>
<li>Return exit status in <strong>main</strong>.py by <a href="https://github.com/szepeviktor"><code>@​szepeviktor</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3157">codespell-project/codespell#3157</a></li>
<li>Fix ruff alerts (currently) not caught by pre-commit by <a href="https://github.com/DimitriPapadopoulos"><code>@​DimitriPapadopoulos</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3158">codespell-project/codespell#3158</a></li>
<li>Added new word by <a href="https://github.com/muhahahmad68"><code>@​muhahahmad68</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3146">codespell-project/codespell#3146</a></li>
<li><code>dictionary.txt</code> additions by <a href="https://github.com/janosh"><code>@​janosh</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3149">codespell-project/codespell#3149</a></li>
<li>Add Gelma's typos that start with &quot;a&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3150">codespell-project/codespell#3150</a></li>
<li>Add Gelma's typos from &quot;b&quot; to &quot;cl&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3163">codespell-project/codespell#3163</a></li>
<li>Add some academies typos by <a href="https://github.com/peternewman"><code>@​peternewman</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3173">codespell-project/codespell#3173</a></li>
<li>Add Gelma's typos from &quot;co&quot; to &quot;cy&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3167">codespell-project/codespell#3167</a></li>
<li>Add Gelma's typos that start with &quot;d&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3168">codespell-project/codespell#3168</a></li>
<li>Refactor code using <code>encodings</code> by <a href="https://github.com/DimitriPapadopoulos"><code>@​DimitriPapadopoulos</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3172">codespell-project/codespell#3172</a></li>
<li>[pre-commit.ci] pre-commit autoupdate by <a href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3176">codespell-project/codespell#3176</a></li>
<li>Add Gelma's typos that start with &quot;e&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3174">codespell-project/codespell#3174</a></li>
<li>Add Gelma's typos from &quot;f&quot; to &quot;h&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3175">codespell-project/codespell#3175</a></li>
<li>Add alwats-&gt;always correction. by <a href="https://github.com/cfi-gb"><code>@​cfi-gb</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3178">codespell-project/codespell#3178</a></li>
<li>Add obsloete-&gt;obsolete and friend by <a href="https://github.com/peternewman"><code>@​peternewman</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3019">codespell-project/codespell#3019</a></li>
<li>Add entries to rare dictionary by <a href="https://github.com/DimitriPapadopoulos"><code>@​DimitriPapadopoulos</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3179">codespell-project/codespell#3179</a></li>
<li>Add Gelma's typos that start with &quot;i&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3177">codespell-project/codespell#3177</a></li>
<li>diagional -&gt; diagonal by <a href="https://github.com/tkoyama010"><code>@​tkoyama010</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3183">codespell-project/codespell#3183</a></li>
<li>Add Gelma's typos from &quot;j&quot; to &quot;m&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3180">codespell-project/codespell#3180</a></li>
<li>Add Gelma's typos from &quot;n&quot; to &quot;o&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3182">codespell-project/codespell#3182</a></li>
<li>Add corrections for vulnerbailit(y|ies)-&gt;vulnerabilit(y|ies). by <a href="https://github.com/cfi-gb"><code>@​cfi-gb</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3185">codespell-project/codespell#3185</a></li>
<li>Add Gelma's typos that start with &quot;p&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3184">codespell-project/codespell#3184</a></li>
<li>Add Gelma's typos from &quot;q&quot; to &quot;r&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3186">codespell-project/codespell#3186</a></li>
<li>[pre-commit.ci] pre-commit autoupdate by <a href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3193">codespell-project/codespell#3193</a></li>
<li>openign-&gt;opening by <a href="https://github.com/claydugo"><code>@​claydugo</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3194">codespell-project/codespell#3194</a></li>
<li>Add Gelma's typos that start with &quot;s&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3187">codespell-project/codespell#3187</a></li>
<li>Add spelling corrections for evaluate by <a href="https://github.com/adrien-berchet"><code>@​adrien-berchet</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3195">codespell-project/codespell#3195</a></li>
<li>Add Gelma's typos from &quot;t&quot; to &quot;z&quot; by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3188">codespell-project/codespell#3188</a></li>
<li>Dict update by <a href="https://github.com/macpijan"><code>@​macpijan</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3197">codespell-project/codespell#3197</a></li>
<li>Improve existing suggestions by <a href="https://github.com/int-y1"><code>@​int-y1</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3200">codespell-project/codespell#3200</a></li>
<li>Add a timeout to jobs that may benefit from it by <a href="https://github.com/DimitriPapadopoulos"><code>@​DimitriPapadopoulos</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3199">codespell-project/codespell#3199</a></li>
<li>[pre-commit.ci] pre-commit autoupdate by <a href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3201">codespell-project/codespell#3201</a></li>
<li>Unify multiple identities of luzpuz and Dimitri by <a href="https://github.com/yarikoptic"><code>@​yarikoptic</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3205">codespell-project/codespell#3205</a></li>
<li>Ignore personal names Damon and Manuel by <a href="https://github.com/hugovk"><code>@​hugovk</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3204">codespell-project/codespell#3204</a></li>
<li>[pre-commit.ci] pre-commit autoupdate by <a href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3214">codespell-project/codespell#3214</a></li>
<li>Ignore ill-formed INI files instead of crashing by <a href="https://github.com/DimitriPapadopoulos"><code>@​DimitriPapadopoulos</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3213">codespell-project/codespell#3213</a></li>
<li>don't show stacktrace from KeyboardInterrupt <a href="https://redirect.github.com/codespell-project/codespell/issues/3217">#3217</a> by <a href="https://github.com/jcubic"><code>@​jcubic</code></a> in <a href="https://redirect.github.com/codespell-project/codespell/pull/3218">codespell-project/codespell#3218</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/codespell-project/codespell/commit/193cd7d27cd571f79358af09a8fb8997e54f8fff"><code>193cd7d</code></a> [pre-commit.ci] pre-commit autoupdate</li>
<li><a href="https://github.com/codespell-project/codespell/commit/5c0343bda132afe7a3721419ac2a863a533c612d"><code>5c0343b</code></a> Materials science-related corrections 3 (<a href="https://redirect.github.com/codespell-project/codespell/issues/3424">#3424</a>)</li>
<li><a href="https://github.com/codespell-project/codespell/commit/f1b41a2ed692201a839fed74d0a6997b87831966"><code>f1b41a2</code></a> Add <code>arragne-&gt;arrange</code> typo (<a href="https://redirect.github.com/codespell-project/codespell/issues/3421">#3421</a>)</li>
<li><a href="https://github.com/codespell-project/codespell/commit/a2c7564e5299ef0095e840673ce5be7bf28f9610"><code>a2c7564</code></a> [pre-commit.ci] pre-commit autoupdate</li>
<li><a href="https://github.com/codespell-project/codespell/commit/b84170513cf6c6612e38af34e34511eb37ea1636"><code>b841705</code></a> Add coverage files to .gitignore</li>
<li><a href="https://github.com/codespell-project/codespell/commit/10c2abcfc94db9ca543c62c3b4760422a67fb335"><code>10c2abc</code></a> [pre-commit.ci] pre-commit autoupdate</li>
<li><a href="https://github.com/codespell-project/codespell/commit/0b09d75a330b38c012265a243a3c2f0c988e1d8c"><code>0b09d75</code></a> mian-&gt;main (<a href="https://redirect.github.com/codespell-project/codespell/issues/3339">#3339</a>)</li>
<li><a href="https://github.com/codespell-project/codespell/commit/d64c47604ebee700d6aae25f2168657ec2a8867e"><code>d64c476</code></a> insstance typo (<a href="https://redirect.github.com/codespell-project/codespell/issues/3418">#3418</a>)</li>
<li><a href="https://github.com/codespell-project/codespell/commit/0c63f96636bb2b52cee03afffd2fa2bb2435da41"><code>0c63f96</code></a> Add netflify typo (<a href="https://redirect.github.com/codespell-project/codespell/issues/3417">#3417</a>)</li>
<li><a href="https://github.com/codespell-project/codespell/commit/5875f4f19b82838b82b92963bc799daa262f352a"><code>5875f4f</code></a> [pre-commit.ci] pre-commit autoupdate</li>
<li>Additional commits viewable in <a href="https://github.com/codespell-project/codespell/compare/v2.2.6...v2.3.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=codespell&package-manager=pip&previous-version=2.2.6&new-version=2.3.0)](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>

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/3481?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 67.32%. Comparing base [(`3f7767f`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/3f7767f71f89419bfbd920849580ea0ae4d71a8c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`257468c`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/257468c5152ff128b2b36723df0ac6b35c7c9c28?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #3481      +/-   ##
==========================================
+ Coverage   67.22%   67.32%   +0.09%     
==========================================
  Files         166      166              
  Lines       19722    19722              
==========================================
+ Hits        13258    13277      +19     
+ Misses       5507     5492      -15     
+ Partials      957      953       -4     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/3481?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).

zirain: @dependabot rebase
zirain: /retest

Patch:
diff --git a/api/v1alpha1/authorization_types.go b/api/v1alpha1/authorization_types.go
index c52a2063b..e02ba4daf 100644
--- a/api/v1alpha1/authorization_types.go
+++ b/api/v1alpha1/authorization_types.go
@@ -6,7 +6,8 @@
 package v1alpha1
 
 // Authorization defines the authorization configuration.
-// +notImplementedHide
+//
+// Note: if neither `Rules` nor `DefaultAction` is specified, the default action is to deny all requests.
 type Authorization struct {
 	// Rules defines a list of authorization rules.
 	// These rules are evaluated in order, the first matching rule will be applied,
@@ -16,50 +17,53 @@ type Authorization struct {
 	// and the second rule denies it, when a request matches both rules, it will be allowed.
 	//
 	// +optional
-	Rules []Rule `json:"rules,omitempty"`
+	Rules []AuthorizationRule `json:"rules,omitempty"`
 
 	// DefaultAction defines the default action to be taken if no rules match.
 	// If not specified, the default action is Deny.
 	// +optional
-	DefaultAction *RuleActionType `json:"defaultAction"`
+	DefaultAction *AuthorizationAction `json:"defaultAction"`
 }
 
-// Rule defines the single authorization rule.
-// +notImplementedHide
-type Rule struct {
+// AuthorizationRule defines a single authorization rule.
+type AuthorizationRule struct {
+	// Name is a user-friendly name for the rule. It's just for display purposes.
+	// +optional
+	Name *string `json:"name,omitempty"`
+
 	// Action defines the action to be taken if the rule matches.
-	Action RuleActionType `json:"action"`
+	Action AuthorizationAction `json:"action"`
 
 	// Principal specifies the client identity of a request.
 	Principal Principal `json:"principal"`
-
-	// Permissions contains allowed HTTP methods.
-	// If empty, all methods are matching.
-	//
-	// +optional
-	// Permissions []string `json:"permissions,omitempty"`
 }
 
 // Principal specifies the client identity of a request.
-// +notImplementedHide
+// A client identity can be a client IP, a JWT claim, username from the Authorization header,
+// or any other identity that can be extracted from a custom header.
+// Currently, only the client IP is supported.
 type Principal struct {
-	// ClientCIDR is the IP CIDR range of the client.
+	// ClientCIDRs are the IP CIDR ranges of the client.
 	// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
 	//
-	// By default, the client IP is inferred from the x-forwarder-for header and proxy protocol.
-	// You can use the `EnableProxyProtocol` and `ClientIPDetection` options in
+	// The client IP is inferred from the X-Forwarded-For header, a custom header,
+	// or the proxy protocol.
+	// You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
 	// the `ClientTrafficPolicy` to configure how the client IP is detected.
-	ClientCIDR []string `json:"clientCIDR,omitempty"`
+	// +kubebuilder:validation:MinItems=1
+	ClientCIDRs []CIDR `json:"clientCIDRs"`
+
+	// TODO: Zhaohuabing the MinItems=1 validation can be relaxed to allow empty list
+	// after other principal types are supported. However, at least one principal is required
 }
 
-// RuleActionType specifies the types of authorization rule action.
+// AuthorizationAction defines the action to be taken if a rule matches.
 // +kubebuilder:validation:Enum=Allow;Deny
-// +notImplementedHide
-type RuleActionType string
+type AuthorizationAction string
 
 const (
-	// Allow is the action to allow the request.
-	Allow RuleActionType = "Allow"
-	// Deny is the action to deny the request.
-	Deny RuleActionType = "Deny"
+	// AuthorizationActionAllow is the action to allow the request.
+	AuthorizationActionAllow AuthorizationAction = "Allow"
+	// AuthorizationActionDeny is the action to deny the request.
+	AuthorizationActionDeny AuthorizationAction = "Deny"
 )
diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go
index 09ac1bcbe..a7b258551 100644
--- a/api/v1alpha1/envoyproxy_types.go
+++ b/api/v1alpha1/envoyproxy_types.go
@@ -109,6 +109,8 @@ type EnvoyProxySpec struct {
 	//
 	// - envoy.filters.http.wasm
 	//
+	// - envoy.filters.http.rbac
+	//
 	// - envoy.filters.http.local_ratelimit
 	//
 	// - envoy.filters.http.ratelimit
@@ -151,7 +153,7 @@ type FilterPosition struct {
 }
 
 // EnvoyFilter defines the type of Envoy HTTP filter.
-// +kubebuilder:validation:Enum=envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_authn;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.fault;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.wasm;envoy.filters.http.ext_proc
+// +kubebuilder:validation:Enum=envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_authn;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.fault;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.wasm;envoy.filters.http.ext_proc;envoy.filters.http.rbac
 type EnvoyFilter string
 
 const (
@@ -184,6 +186,9 @@ const (
 	// EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
 	EnvoyFilterRateLimit EnvoyFilter = "envoy.filters.http.ratelimit"
 
+	// EnvoyFilterRBAC defines the Envoy RBAC filter.
+	EnvoyFilterRBAC EnvoyFilter = "envoy.filters.http.rbac"
+
 	// EnvoyFilterRouter defines the Envoy HTTP router filter.
 	EnvoyFilterRouter EnvoyFilter = "envoy.filters.http.router"
 )
diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go
index e07c8ec15..7446ccf36 100644
--- a/api/v1alpha1/shared_types.go
+++ b/api/v1alpha1/shared_types.go
@@ -446,3 +446,8 @@ type BackendRef struct {
 	// Only service Kind is supported for now.
 	gwapiv1.BackendObjectReference `json:",inline"`
 }
+
+// CIDR defines a CIDR Address range.
+// A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64".
+// +kubebuilder:validation:Pattern=`((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))`
+type CIDR string
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 67918dabd..a8a75b949 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -156,14 +156,14 @@ func (in *Authorization) DeepCopyInto(out *Authorization) {
 	*out = *in
 	if in.Rules != nil {
 		in, out := &in.Rules, &out.Rules
-		*out = make([]Rule, len(*in))
+		*out = make([]AuthorizationRule, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
 	if in.DefaultAction != nil {
 		in, out := &in.DefaultAction, &out.DefaultAction
-		*out = new(RuleActionType)
+		*out = new(AuthorizationAction)
 		**out = **in
 	}
 }
@@ -178,6 +178,27 @@ func (in *Authorization) DeepCopy() *Authorization {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AuthorizationRule) DeepCopyInto(out *AuthorizationRule) {
+	*out = *in
+	if in.Name != nil {
+		in, out := &in.Name, &out.Name
+		*out = new(string)
+		**out = **in
+	}
+	in.Principal.DeepCopyInto(&out.Principal)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationRule.
+func (in *AuthorizationRule) DeepCopy() *AuthorizationRule {
+	if in == nil {
+		return nil
+	}
+	out := new(AuthorizationRule)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *BackOffPolicy) DeepCopyInto(out *BackOffPolicy) {
 	*out = *in
@@ -3402,9 +3423,9 @@ func (in *PerRetryPolicy) DeepCopy() *PerRetryPolicy {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Principal) DeepCopyInto(out *Principal) {
 	*out = *in
-	if in.ClientCIDR != nil {
-		in, out := &in.ClientCIDR, &out.ClientCIDR
-		*out = make([]string, len(*in))
+	if in.ClientCIDRs != nil {
+		in, out := &in.ClientCIDRs, &out.ClientCIDRs
+		*out = make([]CIDR, len(*in))
 		copy(*out, *in)
 	}
 }
@@ -4128,22 +4149,6 @@ func (in *RetryOn) DeepCopy() *RetryOn {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Rule) DeepCopyInto(out *Rule) {
-	*out = *in
-	in.Principal.DeepCopyInto(&out.Principal)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule.
-func (in *Rule) DeepCopy() *Rule {
-	if in == nil {
-		return nil
-	}
-	out := new(Rule)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *SecurityPolicy) DeepCopyInto(out *SecurityPolicy) {
 	*out = *in
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
index 8ba48c431..b3896406b 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -254,6 +254,9 @@ spec:
                   - envoy.filters.http.wasm
 
 
+                  - envoy.filters.http.rbac
+
+
                   - envoy.filters.http.local_ratelimit
 
 
@@ -280,6 +283,7 @@ spec:
                       - envoy.filters.http.ratelimit
                       - envoy.filters.http.wasm
                       - envoy.filters.http.ext_proc
+                      - envoy.filters.http.rbac
                       type: string
                     before:
                       description: |-
@@ -296,6 +300,7 @@ spec:
                       - envoy.filters.http.ratelimit
                       - envoy.filters.http.wasm
                       - envoy.filters.http.ext_proc
+                      - envoy.filters.http.rbac
                       type: string
                     name:
                       description: Name of the filter.
@@ -310,6 +315,7 @@ spec:
                       - envoy.filters.http.ratelimit
                       - envoy.filters.http.wasm
                       - envoy.filters.http.ext_proc
+                      - envoy.filters.http.rbac
                       type: string
                   required:
                   - name
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
index 00e1b791e..a7cf21754 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -70,7 +70,8 @@ spec:
                       For example, if there are two rules: the first rule allows the request
                       and the second rule denies it, when a request matches both rules, it will be allowed.
                     items:
-                      description: Rule defines the single authorization rule.
+                      description: AuthorizationRule defines a single authorization
+                        rule.
                       properties:
                         action:
                           description: Action defines the action to be taken if the
@@ -79,22 +80,34 @@ spec:
                           - Allow
                           - Deny
                           type: string
+                        name:
+                          description: Name is a user-friendly name for the rule.
+                            It's just for display purposes.
+                          type: string
                         principal:
                           description: Principal specifies the client identity of
                             a request.
                           properties:
-                            clientCIDR:
+                            clientCIDRs:
                               description: |-
-                                ClientCIDR is the IP CIDR range of the client.
+                                ClientCIDRs are the IP CIDR ranges of the client.
                                 Valid examples are "192.168.1.0/24" or "2001:db8::/64"
 
 
-                                By default, the client IP is inferred from the x-forwarder-for header and proxy protocol.
-                                You can use the `EnableProxyProtocol` and `ClientIPDetection` options in
+                                The client IP is inferred from the X-Forwarded-For header, a custom header,
+                                or the proxy protocol.
+                                You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
                                 the `ClientTrafficPolicy` to configure how the client IP is detected.
                               items:
+                                description: |-
+                                  CIDR defines a CIDR Address range.
+                                  A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64".
+                                pattern: ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))
                                 type: string
+                              minItems: 1
                               type: array
+                          required:
+                          - clientCIDRs
                           type: object
                       required:
                       - action
diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go
index 0fae4b170..3c8e27a97 100644
--- a/internal/gatewayapi/backendtrafficpolicy.go
+++ b/internal/gatewayapi/backendtrafficpolicy.go
@@ -10,7 +10,6 @@ import (
 	"fmt"
 	"math"
 	"math/big"
-	"net"
 	"sort"
 	"strings"
 	"time"
@@ -301,6 +300,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
 		to        *ir.Timeout
 		ka        *ir.TCPKeepalive
 		rt        *ir.Retry
+		bc        *ir.BackendConnection
 		err, errs error
 	)
 
@@ -348,6 +348,13 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
 		}
 	}
 
+	if policy.Spec.Connection != nil {
+		if bc, err = t.buildBackendConnection(policy); err != nil {
+			err = perr.WithMessage(err, "BackendConnection")
+			errs = errors.Join(errs, err)
+		}
+	}
+
 	// Early return if got any errors
 	if errs != nil {
 		return errs
@@ -366,17 +373,19 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
 					r.CircuitBreaker = cb
 					r.TCPKeepalive = ka
 					r.Timeout = to
+					r.BackendConnection = bc
 				}
 			}
 		}
 
 		for _, udp := range x.UDP {
 			if udp.Route != nil {
-				route := udp.Route
+				r := udp.Route
 
-				if strings.HasPrefix(route.Destination.Name, prefix) {
-					route.LoadBalancer = lb
-					route.Timeout = to
+				if strings.HasPrefix(r.Destination.Name, prefix) {
+					r.LoadBalancer = lb
+					r.Timeout = to
+					r.BackendConnection = bc
 				}
 			}
 		}
@@ -386,14 +395,15 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
 				// Apply if there is a match
 				if strings.HasPrefix(r.Name, prefix) {
 					r.Traffic = &ir.TrafficFeatures{
-						RateLimit:      rl,
-						LoadBalancer:   lb,
-						ProxyProtocol:  pp,
-						HealthCheck:    hc,
-						CircuitBreaker: cb,
-						FaultInjection: fi,
-						TCPKeepalive:   ka,
-						Retry:          rt,
+						RateLimit:         rl,
+						LoadBalancer:      lb,
+						ProxyProtocol:     pp,
+						HealthCheck:       hc,
+						CircuitBreaker:    cb,
+						FaultInjection:    fi,
+						TCPKeepalive:      ka,
+						Retry:             rt,
+						BackendConnection: bc,
 					}
 
 					// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
@@ -758,18 +768,12 @@ func buildRateLimitRule(rule egv1a1.RateLimitRule) (*ir.RateLimitRule, error) {
 				distinct = true
 			}
 
-			ip, ipn, err := net.ParseCIDR(sourceCIDR)
+			cidrMatch, err := parseCIDR(sourceCIDR)
 			if err != nil {
-				return nil, fmt.Errorf("unable to translate rateLimit")
-			}
-
-			mask, _ := ipn.Mask.Size()
-			irRule.CIDRMatch = &ir.CIDRMatch{
-				CIDR:     ipn.String(),
-				IPv6:     ip.To4() == nil,
-				MaskLen:  mask,
-				Distinct: distinct,
+				return nil, fmt.Errorf("unable to translate rateLimit: %w", err)
 			}
+			cidrMatch.Distinct = distinct
+			irRule.CIDRMatch = cidrMatch
 		}
 	}
 	return irRule, nil
@@ -1139,6 +1143,31 @@ func int64ToUint32(in int64) (uint32, bool) {
 	return 0, false
 }
 
+func (t *Translator) buildBackendConnection(policy *egv1a1.BackendTrafficPolicy) (*ir.BackendConnection, error) {
+	var (
+		bcIR = &ir.BackendConnection{}
+		bc   = &egv1a1.BackendTrafficPolicyConnection{}
+	)
+
+	if policy.Spec.Connection != nil {
+		bc = policy.Spec.Connection
+
+		if bc.BufferLimit != nil {
+			bf, ok := bc.BufferLimit.AsInt64()
+			if !ok {
+				return nil, fmt.Errorf("invalid BufferLimit value %s", bc.BufferLimit.String())
+			}
+			if bf < 0 || bf > math.MaxUint32 {
+				return nil, fmt.Errorf("BufferLimit value %s is out of range", bc.BufferLimit.String())
+			}
+
+			bcIR.BufferLimitBytes = ptr.To(uint32(bf))
+		}
+	}
+
+	return bcIR, nil
+}
+
 func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *ir.FaultInjection {
 	var fi *ir.FaultInjection
 	if policy.Spec.FaultInjection != nil {
diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go
index 2946591d4..c763d8068 100644
--- a/internal/gatewayapi/helpers.go
+++ b/internal/gatewayapi/helpers.go
@@ -8,6 +8,7 @@ package gatewayapi
 import (
 	"errors"
 	"fmt"
+	"net"
 	"strings"
 
 	v1 "k8s.io/api/core/v1"
@@ -466,3 +467,18 @@ func listenersWithSameHTTPPort(xdsIR *ir.Xds, listener *ir.HTTPListener) []strin
 	}
 	return res
 }
+
+func parseCIDR(cidr string) (*ir.CIDRMatch, error) {
+	ip, ipn, err := net.ParseCIDR(cidr)
+	if err != nil {
+		return nil, err
+	}
+
+	mask, _ := ipn.Mask.Size()
+	return &ir.CIDRMatch{
+		CIDR:    ipn.String(),
+		IP:      ip.String(),
+		MaskLen: uint32(mask),
+		IsIPv6:  ip.To4() == nil,
+	}, nil
+}
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index 29305d067..8c459a8d1 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -332,12 +332,13 @@ func (t *Translator) translateSecurityPolicyForRoute(
 ) error {
 	// Build IR
 	var (
-		cors      *ir.CORS
-		jwt       *ir.JWT
-		oidc      *ir.OIDC
-		basicAuth *ir.BasicAuth
-		extAuth   *ir.ExtAuth
-		err, errs error
+		cors          *ir.CORS
+		jwt           *ir.JWT
+		oidc          *ir.OIDC
+		basicAuth     *ir.BasicAuth
+		extAuth       *ir.ExtAuth
+		authorization *ir.Authorization
+		err, errs     error
 	)
 
 	if policy.Spec.CORS != nil {
@@ -375,6 +376,12 @@ func (t *Translator) translateSecurityPolicyForRoute(
 		}
 	}
 
+	if policy.Spec.Authorization != nil {
+		if authorization, err = t.buildAuthorization(policy); err != nil {
+			errs = errors.Join(errs, err)
+		}
+	}
+
 	// Apply IR to all relevant routes
 	// Note: there are multiple features in a security policy, even if some of them
 	// are invalid, we still want to apply the valid ones.
@@ -388,11 +395,12 @@ func (t *Translator) translateSecurityPolicyForRoute(
 					// This security policy matches the current route.
 					// It should only be accepted if it doesn't match any other route
 					r.Security = &ir.SecurityFeatures{
-						CORS:      cors,
-						JWT:       jwt,
-						OIDC:      oidc,
-						BasicAuth: basicAuth,
-						ExtAuth:   extAuth,
+						CORS:          cors,
+						JWT:           jwt,
+						OIDC:          oidc,
+						BasicAuth:     basicAuth,
+						ExtAuth:       extAuth,
+						Authorization: authorization,
 					}
 				}
 			}
@@ -407,12 +415,13 @@ func (t *Translator) translateSecurityPolicyForGateway(
 ) error {
 	// Build IR
 	var (
-		cors      *ir.CORS
-		jwt       *ir.JWT
-		oidc      *ir.OIDC
-		basicAuth *ir.BasicAuth
-		extAuth   *ir.ExtAuth
-		err, errs error
+		cors          *ir.CORS
+		jwt           *ir.JWT
+		oidc          *ir.OIDC
+		basicAuth     *ir.BasicAuth
+		extAuth       *ir.ExtAuth
+		authorization *ir.Authorization
+		err, errs     error
 	)
 
 	if policy.Spec.CORS != nil {
@@ -450,6 +459,11 @@ func (t *Translator) translateSecurityPolicyForGateway(
 		}
 	}
 
+	if policy.Spec.Authorization != nil {
+		if authorization, err = t.buildAuthorization(policy); err != nil {
+			errs = errors.Join(errs, err)
+		}
+	}
 	// Apply IR to all the routes within the specific Gateway that originated
 	// from the gateway to which this security policy was attached.
 	// If the feature is already set, then skip it, since it must have be
@@ -477,11 +491,12 @@ func (t *Translator) translateSecurityPolicyForGateway(
 			}
 
 			r.Security = &ir.SecurityFeatures{
-				CORS:      cors,
-				JWT:       jwt,
-				OIDC:      oidc,
-				BasicAuth: basicAuth,
-				ExtAuth:   extAuth,
+				CORS:          cors,
+				JWT:           jwt,
+				OIDC:          oidc,
+				BasicAuth:     basicAuth,
+				ExtAuth:       extAuth,
+				Authorization: authorization,
 			}
 		}
 	}
@@ -858,3 +873,51 @@ func irConfigName(policy *egv1a1.SecurityPolicy) string {
 		strings.ToLower(KindSecurityPolicy),
 		utils.NamespacedName(policy).String())
 }
+
+func (t *Translator) buildAuthorization(policy *egv1a1.SecurityPolicy) (*ir.Authorization, error) {
+	var (
+		authorization = policy.Spec.Authorization
+		irAuth        = &ir.Authorization{}
+		// The default action is Deny if not specified
+		defaultAction = egv1a1.AuthorizationActionDeny
+	)
+
+	if authorization.DefaultAction != nil {
+		defaultAction = *authorization.DefaultAction
+	}
+	irAuth.DefaultAction = defaultAction
+
+	for i, rule := range authorization.Rules {
+		principal := ir.Principal{}
+
+		for _, cidr := range rule.Principal.ClientCIDRs {
+			cidrMatch, err := parseCIDR(string(cidr))
+			if err != nil {
+				return nil, fmt.Errorf("unable to translate authorization rule: %w", err)
+			}
+
+			principal.ClientCIDRs = append(principal.ClientCIDRs, cidrMatch)
+		}
+
+		var name string
+		if rule.Name != nil && *rule.Name != "" {
+			name = *rule.Name
+		} else {
+			name = defaultAuthorizationRuleName(policy, i)
+		}
+		irAuth.Rules = append(irAuth.Rules, &ir.AuthorizationRule{
+			Name:      name,
+			Action:    rule.Action,
+			Principal: principal,
+		})
+	}
+
+	return irAuth, nil
+}
+
+func defaultAuthorizationRuleName(policy *egv1a1.SecurityPolicy, index int) string {
+	return fmt.Sprintf(
+		"%s/authorization/rule/%s",
+		irConfigName(policy),
+		strconv.Itoa(index))
+}
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 77505d575..6ff368f0b 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -543,6 +543,8 @@ type TrafficFeatures struct {
 	TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"`
 	// Retry settings
 	Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"`
+	// settings of upstream connection
+	BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"`
 }
 
 func (b *TrafficFeatures) Validate() error {
@@ -575,6 +577,8 @@ type SecurityFeatures struct {
 	BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"`
 	// ExtAuth defines the schema for the external authorization.
 	ExtAuth *ExtAuth `json:"extAuth,omitempty" yaml:"extAuth,omitempty"`
+	// Authorization defines the schema for the authorization.
+	Authorization *Authorization `json:"authorization,omitempty" yaml:"authorization,omitempty"`
 }
 
 func (s *SecurityFeatures) Printable() *SecurityFeatures {
@@ -784,6 +788,40 @@ type GRPCExtAuthService struct {
 	Authority string `json:"authority"`
 }
 
+// Authorization defines the schema for the authorization.
+//
+// +k8s:deepcopy-gen=true
+type Authorization struct {
+	// Rules defines the authorization rules.
+	Rules []*AuthorizationRule `json:"rules,omitempty"`
+
+	// DefaultAction defines the default action to be taken if no rules match.
+	DefaultAction egv1a1.AuthorizationAction `json:"defaultAction"`
+}
+
+// AuthorizationRule defines the schema for the authorization rule.
+//
+// +k8s:deepcopy-gen=true
+type AuthorizationRule struct {
+	// Name is a user-defined name for the rule.
+	// If not specified, a name will be generated by EG.
+	Name string `json:"name"`
+
+	// Action defines the action to be taken if the rule matches.
+	Action egv1a1.AuthorizationAction `json:"action"`
+
+	// Principal defines the principal to be matched.
+	Principal Principal `json:"principal"`
+}
+
+// Principal defines the schema for the principal.
+//
+// +k8s:deepcopy-gen=true
+type Principal struct {
+	// ClientCIDRs defines the client CIDRs to be matched.
+	ClientCIDRs []*CIDRMatch `json:"clientCIDRs,omitempty"`
+}
+
 // FaultInjection defines the schema for injecting faults into requests.
 //
 // +k8s:deepcopy-gen=true
@@ -1272,6 +1310,8 @@ type TCPRoute struct {
 	HealthCheck *HealthCheck `json:"healthCheck,omitempty" yaml:"healthCheck,omitempty"`
 	// Proxy Protocol Settings
 	ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty"`
+	// settings of upstream connection
+	BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"`
 }
 
 // TLS holds information for configuring TLS on a listener
@@ -1385,6 +1425,8 @@ type UDPRoute struct {
 	LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"`
 	// Request and connection timeout settings
 	Timeout *Timeout `json:"timeout,omitempty" yaml:"timeout,omitempty"`
+	// settings of upstream connection
+	BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"`
 }
 
 // Validate the fields within the UDPListener structure
@@ -1468,8 +1510,9 @@ type RateLimitRule struct {
 
 type CIDRMatch struct {
 	CIDR    string `json:"cidr" yaml:"cidr"`
-	IPv6    bool   `json:"ipv6" yaml:"ipv6"`
-	MaskLen int    `json:"maskLen" yaml:"maskLen"`
+	IP      string `json:"ip" yaml:"ip"`
+	MaskLen uint32 `json:"maskLen" yaml:"maskLen"`
+	IsIPv6  bool   `json:"isIPv6" yaml:"isIPv6"`
 	// Distinct means that each IP Address within the specified Source IP CIDR is treated as a distinct client selector
 	// and uses a separate rate limit bucket/counter.
 	Distinct bool `json:"distinct" yaml:"distinct"`
@@ -2024,6 +2067,13 @@ type TLSUpstreamConfig struct {
 	TLSConfig           `json:",inline"`
 }
 
+// BackendConnection settings for upstream connections
+// +k8s:deepcopy-gen=true
+type BackendConnection struct {
+	// BufferLimitBytes is the maximum number of bytes that can be buffered for a connection.
+	BufferLimitBytes *uint32 `json:"bufferLimit,omitempty" yaml:"bufferLimit,omitempty"`
+}
+
 // Connection settings for downstream connections
 // +k8s:deepcopy-gen=true
 type Connection struct {
diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go
index 7d93ad057..828363c14 100644
--- a/internal/ir/zz_generated.deepcopy.go
+++ b/internal/ir/zz_generated.deepcopy.go
@@ -124,6 +124,48 @@ func (in *AddHeader) DeepCopy() *AddHeader {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Authorization) DeepCopyInto(out *Authorization) {
+	*out = *in
+	if in.Rules != nil {
+		in, out := &in.Rules, &out.Rules
+		*out = make([]*AuthorizationRule, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(AuthorizationRule)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authorization.
+func (in *Authorization) DeepCopy() *Authorization {
+	if in == nil {
+		return nil
+	}
+	out := new(Authorization)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AuthorizationRule) DeepCopyInto(out *AuthorizationRule) {
+	*out = *in
+	in.Principal.DeepCopyInto(&out.Principal)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationRule.
+func (in *AuthorizationRule) DeepCopy() *AuthorizationRule {
+	if in == nil {
+		return nil
+	}
+	out := new(AuthorizationRule)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *BackOffPolicy) DeepCopyInto(out *BackOffPolicy) {
 	*out = *in
@@ -149,6 +191,26 @@ func (in *BackOffPolicy) DeepCopy() *BackOffPolicy {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackendConnection) DeepCopyInto(out *BackendConnection) {
+	*out = *in
+	if in.BufferLimitBytes != nil {
+		in, out := &in.BufferLimitBytes, &out.BufferLimitBytes
+		*out = new(uint32)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendConnection.
+func (in *BackendConnection) DeepCopy() *BackendConnection {
+	if in == nil {
+		return nil
+	}
+	out := new(BackendConnection)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *BasicAuth) DeepCopyInto(out *BasicAuth) {
 	*out = *in
@@ -1629,6 +1691,32 @@ func (in *PerRetryPolicy) DeepCopy() *PerRetryPolicy {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Principal) DeepCopyInto(out *Principal) {
+	*out = *in
+	if in.ClientCIDRs != nil {
+		in, out := &in.ClientCIDRs, &out.ClientCIDRs
+		*out = make([]*CIDRMatch, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(CIDRMatch)
+				**out = **in
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal.
+func (in *Principal) DeepCopy() *Principal {
+	if in == nil {
+		return nil
+	}
+	out := new(Principal)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ProxyInfra) DeepCopyInto(out *ProxyInfra) {
 	*out = *in
@@ -1971,6 +2059,11 @@ func (in *SecurityFeatures) DeepCopyInto(out *SecurityFeatures) {
 		*out = new(ExtAuth)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.Authorization != nil {
+		in, out := &in.Authorization, &out.Authorization
+		*out = new(Authorization)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityFeatures.
@@ -2202,6 +2295,11 @@ func (in *TCPRoute) DeepCopyInto(out *TCPRoute) {
 		*out = new(ProxyProtocol)
 		**out = **in
 	}
+	if in.BackendConnection != nil {
+		in, out := &in.BackendConnection, &out.BackendConnection
+		*out = new(BackendConnection)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPRoute.
@@ -2525,6 +2623,11 @@ func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) {
 		*out = new(Retry)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.BackendConnection != nil {
+		in, out := &in.BackendConnection, &out.BackendConnection
+		*out = new(BackendConnection)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures.
@@ -2575,6 +2678,11 @@ func (in *UDPRoute) DeepCopyInto(out *UDPRoute) {
 		*out = new(Timeout)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.BackendConnection != nil {
+		in, out := &in.BackendConnection, &out.BackendConnection
+		*out = new(BackendConnection)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDPRoute.
diff --git a/internal/xds/translator/authorization.go b/internal/xds/translator/authorization.go
new file mode 100644
index 000000000..cfafb2725
--- /dev/null
+++ b/internal/xds/translator/authorization.go
@@ -0,0 +1,267 @@
+// 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 translator
+
+import (
+	"errors"
+	"fmt"
+
+	cncfv3 "github.com/cncf/xds/go/xds/core/v3"
+	matcherv3 "github.com/cncf/xds/go/xds/type/matcher/v3"
+	configv3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
+	rbacconfigv3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3"
+	routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
+	rbacv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3"
+	hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
+	networkinput "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/common_inputs/network/v3"
+	ipmatcherv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/input_matchers/ip/v3"
+	"google.golang.org/protobuf/types/known/anypb"
+	"google.golang.org/protobuf/types/known/wrapperspb"
+
+	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+	"github.com/envoyproxy/gateway/internal/ir"
+	"github.com/envoyproxy/gateway/internal/xds/types"
+)
+
+func init() {
+	registerHTTPFilter(&rbac{})
+}
+
+type rbac struct{}
+
+var _ httpFilter = &rbac{}
+
+// patchHCM builds and appends the RBAC Filter to the HTTP Connection Manager if
+// applicable.
+func (*rbac) patchHCM(
+	mgr *hcmv3.HttpConnectionManager,
+	irListener *ir.HTTPListener,
+) error {
+	if mgr == nil {
+		return errors.New("hcm is nil")
+	}
+
+	if irListener == nil {
+		return errors.New("ir listener is nil")
+	}
+
+	if !listenerContainsRBAC(irListener) {
+		return nil
+	}
+
+	// Return early if filter already exists.
+	for _, f := range mgr.HttpFilters {
+		if f.Name == string(egv1a1.EnvoyFilterRBAC) {
+			return nil
+		}
+	}
+
+	rbacFilter, err := buildHCMRBACFilter()
+	if err != nil {
+		return err
+	}
+
+	mgr.HttpFilters = append([]*hcmv3.HttpFilter{rbacFilter}, mgr.HttpFilters...)
+
+	return nil
+}
+
+// buildHCMRBACFilter returns a RBAC filter from the provided IR listener.
+func buildHCMRBACFilter() (*hcmv3.HttpFilter, error) {
+	rbacProto := &rbacv3.RBAC{}
+	rbacAny, err := anypb.New(rbacProto)
+	if err != nil {
+		return nil, err
+	}
+
+	return &hcmv3.HttpFilter{
+		Name: string(egv1a1.EnvoyFilterRBAC),
+		ConfigType: &hcmv3.HttpFilter_TypedConfig{
+			TypedConfig: rbacAny,
+		},
+	}, nil
+}
+
+// listenerContainsRBAC returns true if the provided listener has RBAC
+// policies attached to its routes.
+func listenerContainsRBAC(irListener *ir.HTTPListener) bool {
+	if irListener == nil {
+		return false
+	}
+
+	for _, route := range irListener.Routes {
+		if route.Security != nil && route.Security.Authorization != nil {
+			return true
+		}
+	}
+
+	return false
+}
+
+// patchRoute patches the provided route with the RBAC config if applicable.
+func (*rbac) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
+	if route == nil {
+		return errors.New("xds route is nil")
+	}
+	if irRoute == nil {
+		return errors.New("ir route is nil")
+	}
+	if irRoute.Security == nil || irRoute.Security.Authorization == nil {
+		return nil
+	}
+
+	filterCfg := route.GetTypedPerFilterConfig()
+	if _, ok := filterCfg[string(egv1a1.EnvoyFilterRBAC)]; ok {
+		// This should not happen since this is the only place where the RBAC
+		// filter is added in a route.
+		return fmt.Errorf("route already contains rbac config: %+v", route)
+	}
+
+	var (
+		authorization = irRoute.Security.Authorization
+		allowAction   *anypb.Any
+		denyAction    *anypb.Any
+		sourceIPInput *anypb.Any
+		ipMatcher     *anypb.Any
+		matcherList   []*matcherv3.Matcher_MatcherList_FieldMatcher
+		err           error
+	)
+
+	allow := &rbacconfigv3.Action{
+		Name:   "ALLOW",
+		Action: rbacconfigv3.RBAC_ALLOW,
+	}
+	if allowAction, err = anypb.New(allow); err != nil {
+		return err
+	}
+
+	deny := &rbacconfigv3.Action{
+		Name:   "DENY",
+		Action: rbacconfigv3.RBAC_DENY,
+	}
+	if denyAction, err = anypb.New(deny); err != nil {
+		return err
+	}
+
+	// Build a list of matchers based on the rules.
+	// The matchers will be evaluated in order, and the first one that matches
+	// will be used to determine the action, the rest of the matchers will be
+	// skipped.
+	// If no matcher matches, the default action will be used.
+	for _, rule := range authorization.Rules {
+		// Build the IPMatcher based on the client CIDRs.
+		ipRangeMatcher := &ipmatcherv3.Ip{
+			StatPrefix: "client_ip",
+		}
+
+		for _, cidr := range rule.Principal.ClientCIDRs {
+			ipRangeMatcher.CidrRanges = append(ipRangeMatcher.CidrRanges, &configv3.CidrRange{
+				AddressPrefix: cidr.IP,
+				PrefixLen: &wrapperspb.UInt32Value{
+					Value: cidr.MaskLen,
+				},
+			})
+		}
+
+		if ipMatcher, err = anypb.New(ipRangeMatcher); err != nil {
+			return err
+		}
+
+		if sourceIPInput, err = anypb.New(&networkinput.SourceIPInput{}); err != nil {
+			return err
+		}
+
+		// Determine the action for the current rule.
+		ruleAction := allowAction
+		if rule.Action == egv1a1.AuthorizationActionDeny {
+			ruleAction = denyAction
+		}
+
+		// Add the matcher generated with the current rule to the matcher list.
+		matcherList = append(matcherList, &matcherv3.Matcher_MatcherList_FieldMatcher{
+			Predicate: &matcherv3.Matcher_MatcherList_Predicate{
+				MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+					SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+						Input: &cncfv3.TypedExtensionConfig{
+							Name:        "client_ip",
+							TypedConfig: sourceIPInput,
+						},
+						Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
+							CustomMatch: &cncfv3.TypedExtensionConfig{
+								Name:        "ip_matcher",
+								TypedConfig: ipMatcher,
+							},
+						},
+					},
+				},
+			},
+			OnMatch: &matcherv3.Matcher_OnMatch{
+				OnMatch: &matcherv3.Matcher_OnMatch_Action{
+					Action: &cncfv3.TypedExtensionConfig{
+						Name:        rule.Name,
+						TypedConfig: ruleAction,
+					},
+				},
+			},
+		})
+	}
+
+	// Set the default action.
+	defaultAction := denyAction
+	if authorization.DefaultAction == egv1a1.AuthorizationActionAllow {
+		defaultAction = allowAction
+	}
+
+	routeCfgProto := &rbacv3.RBACPerRoute{
+		Rbac: &rbacv3.RBAC{
+			Matcher: &matcherv3.Matcher{
+				MatcherType: &matcherv3.Matcher_MatcherList_{
+					MatcherList: &matcherv3.Matcher_MatcherList{
+						Matchers: matcherList,
+					},
+				},
+				// If no matcher matches, the default action will be used.
+				OnNoMatch: &matcherv3.Matcher_OnMatch{
+					OnMatch: &matcherv3.Matcher_OnMatch_Action{
+						Action: &cncfv3.TypedExtensionConfig{
+							Name:        "default",
+							TypedConfig: defaultAction,
+						},
+					},
+				},
+			},
+		},
+	}
+
+	// If there are no matchers, the default action will be used for all requests.
+	// Setting the matcher type to nil since Proto validation will fail if the list
+	// is empty.
+	if len(matcherList) == 0 {
+		routeCfgProto.Rbac.Matcher.MatcherType = nil
+	}
+
+	// We need to validate the RBACPerRoute message before converting it to an Any.
+	if err = routeCfgProto.ValidateAll(); err != nil {
+		return err
+	}
+
+	routeCfgAny, err := anypb.New(routeCfgProto)
+	if err != nil {
+		return err
+	}
+
+	if filterCfg == nil {
+		route.TypedPerFilterConfig = make(map[string]*anypb.Any)
+	}
+
+	route.TypedPerFilterConfig[string(egv1a1.EnvoyFilterRBAC)] = routeCfgAny
+
+	return nil
+}
+
+func (c *rbac) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error {
+	return nil
+}
diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go
index 1b5ed80d6..a918c159b 100644
--- a/internal/xds/translator/cluster.go
+++ b/internal/xds/translator/cluster.go
@@ -21,6 +21,7 @@ import (
 	xdstype "github.com/envoyproxy/go-control-plane/envoy/type/v3"
 	"github.com/envoyproxy/go-control-plane/pkg/resource/v3"
 	"github.com/envoyproxy/go-control-plane/pkg/wellknown"
+	"github.com/golang/protobuf/ptypes/wrappers"
 	"google.golang.org/protobuf/types/known/anypb"
 	"google.golang.org/protobuf/types/known/durationpb"
 	"google.golang.org/protobuf/types/known/structpb"
@@ -50,6 +51,7 @@ type xdsClusterArgs struct {
 	timeout           *ir.Timeout
 	tcpkeepalive      *ir.TCPKeepalive
 	metrics           *ir.Metrics
+	backendConnection *ir.BackendConnection
 	useClientProtocol bool
 }
 
@@ -86,11 +88,10 @@ func buildXdsCluster(args *xdsClusterArgs) *clusterv3.Cluster {
 			},
 		},
 		OutlierDetection:              &clusterv3.OutlierDetection{},
-		PerConnectionBufferLimitBytes: wrapperspb.UInt32(tcpClusterPerConnectionBufferLimitBytes),
+		PerConnectionBufferLimitBytes: buildBackandConnectionBufferLimitBytes(args.backendConnection),
 	}
 
 	cluster.ConnectTimeout = buildConnectTimeout(args.timeout)
-
 	// set peer endpoint stats
 	if args.metrics != nil && args.metrics.EnablePerEndpointStats {
 		cluster.TrackClusterStats = &clusterv3.TrackClusterStats{
@@ -627,3 +628,11 @@ func buildXdsClusterUpstreamOptions(tcpkeepalive *ir.TCPKeepalive) *clusterv3.Up
 
 	return ka
 }
+
+func buildBackandConnectionBufferLimitBytes(bc *ir.BackendConnection) *wrappers.UInt32Value {
+	if bc != nil && bc.BufferLimitBytes != nil {
+		return wrapperspb.UInt32(*bc.BufferLimitBytes)
+	}
+
+	return wrapperspb.UInt32(tcpClusterPerConnectionBufferLimitBytes)
+}
diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go
index f5a833087..cda5ae8a4 100644
--- a/internal/xds/translator/cors.go
+++ b/internal/xds/translator/cors.go
@@ -61,7 +61,6 @@ func (*cors) patchHCM(
 		return err
 	}
 
-	// Ensure the CORS filter is the first one in the filter chain.
 	mgr.HttpFilters = append([]*hcmv3.HttpFilter{corsFilter}, mgr.HttpFilters...)
 
 	return nil
diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go
index 46ce5df80..5da500ddf 100644
--- a/internal/xds/translator/extauth.go
+++ b/internal/xds/translator/extauth.go
@@ -37,7 +37,6 @@ var _ httpFilter = &extAuth{}
 // if applicable, and it does not already exist.
 // Note: this method creates an ext_authz filter for each route that contains an ExtAuthz config.
 // The filter is disabled by default. It is enabled on the route level.
-// TODO: zhaohuabing avoid duplicated HTTP filters
 func (*extAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error {
 	var errs error
 
diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go
index 22c351f81..4bcdd9d56 100644
--- a/internal/xds/translator/httpfilters.go
+++ b/internal/xds/translator/httpfilters.go
@@ -17,7 +17,7 @@ import (
 	"github.com/envoyproxy/go-control-plane/pkg/wellknown"
 	"k8s.io/utils/ptr"
 
-	"github.com/envoyproxy/gateway/api/v1alpha1"
+	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/ir"
 	"github.com/envoyproxy/gateway/internal/xds/filters"
 	"github.com/envoyproxy/gateway/internal/xds/types"
@@ -93,6 +93,7 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter {
 	// Set a rational order for all the filters.
 	// When the fault filter is configured to be at the first, the computation of
 	// the remaining filters is skipped when rejected early
+	// TODO (zhaohuabing): remove duplicate filter type constants and replace them with the type constants in the api package
 	switch {
 	case isFilterType(filter, wellknown.Fault):
 		order = 1
@@ -110,12 +111,14 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter {
 		order = 7 + mustGetFilterIndex(filter.Name)
 	case isFilterType(filter, wasmFilter):
 		order = 100 + mustGetFilterIndex(filter.Name)
-	case isFilterType(filter, localRateLimitFilter):
+	case isFilterType(filter, string(egv1a1.EnvoyFilterRBAC)):
 		order = 201
-	case isFilterType(filter, wellknown.HTTPRateLimit):
+	case isFilterType(filter, localRateLimitFilter):
 		order = 202
-	case isFilterType(filter, wellknown.Router):
+	case isFilterType(filter, wellknown.HTTPRateLimit):
 		order = 203
+	case isFilterType(filter, wellknown.Router):
+		order = 204
 	}
 
 	return &OrderedHTTPFilter{
@@ -143,7 +146,7 @@ func (o OrderedHTTPFilters) Swap(i, j int) {
 // For example, the cors filter should be put at the first to avoid unnecessary
 // processing of other filters for unauthorized cross-region access.
 // The router filter must be the last one since it's a terminal filter.
-func sortHTTPFilters(filters []*hcmv3.HttpFilter, filterOrder []v1alpha1.FilterPosition) []*hcmv3.HttpFilter {
+func sortHTTPFilters(filters []*hcmv3.HttpFilter, filterOrder []egv1a1.FilterPosition) []*hcmv3.HttpFilter {
 	// Sort the filters in the default order.
 	orderedFilters := make(OrderedHTTPFilters, len(filters))
 	for i := 0; i < len(filters); i++ {
diff --git a/internal/xds/translator/jwt.go b/internal/xds/translator/jwt.go
index 27697043a..5a2b35ca6 100644
--- a/internal/xds/translator/jwt.go
+++ b/internal/xds/translator/jwt.go
@@ -65,7 +65,6 @@ func (*jwt) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListen
 		return err
 	}
 
-	// Ensure the authn filter is the first and the terminal filter is the last in the chain.
 	mgr.HttpFilters = append([]*hcmv3.HttpFilter{jwtFilter}, mgr.HttpFilters...)
 
 	return nil
diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go
index 1a0d88d5d..231bda44f 100644
--- a/internal/xds/translator/local_ratelimit.go
+++ b/internal/xds/translator/local_ratelimit.go
@@ -249,8 +249,8 @@ func buildRouteLocalRateLimits(local *ir.LocalRateLimit) (
 
 			// Setup MaskedRemoteAddress action
 			mra := &routev3.RateLimit_Action_MaskedRemoteAddress{}
-			maskLen := &wrapperspb.UInt32Value{Value: uint32(rule.CIDRMatch.MaskLen)}
-			if rule.CIDRMatch.IPv6 {
+			maskLen := &wrapperspb.UInt32Value{Value: rule.CIDRMatch.MaskLen}
+			if rule.CIDRMatch.IsIPv6 {
 				mra.V6PrefixMaskLen = maskLen
 			} else {
 				mra.V4PrefixMaskLen = maskLen
diff --git a/internal/xds/translator/ratelimit.go b/internal/xds/translator/ratelimit.go
index 4534f303f..86a558b29 100644
--- a/internal/xds/translator/ratelimit.go
+++ b/internal/xds/translator/ratelimit.go
@@ -69,7 +69,6 @@ func (t *Translator) patchHCMWithRateLimit(mgr *hcmv3.HttpConnectionManager, irL
 	}
 
 	rateLimitFilter := t.buildRateLimitFilter(irListener)
-	// Make sure the router filter is the terminal filter in the chain.
 	mgr.HttpFilters = append([]*hcmv3.HttpFilter{rateLimitFilter}, mgr.HttpFilters...)
 }
 
@@ -225,8 +224,8 @@ func buildRouteRateLimits(descriptorPrefix string, global *ir.GlobalRateLimit) [
 		if rule.CIDRMatch != nil {
 			// Setup MaskedRemoteAddress action
 			mra := &routev3.RateLimit_Action_MaskedRemoteAddress{}
-			maskLen := &wrapperspb.UInt32Value{Value: uint32(rule.CIDRMatch.MaskLen)}
-			if rule.CIDRMatch.IPv6 {
+			maskLen := &wrapperspb.UInt32Value{Value: rule.CIDRMatch.MaskLen}
+			if rule.CIDRMatch.IsIPv6 {
 				mra.V6PrefixMaskLen = maskLen
 			} else {
 				mra.V4PrefixMaskLen = maskLen
diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go
index 6dc07bfa3..cce16d428 100644
--- a/internal/xds/translator/translator.go
+++ b/internal/xds/translator/translator.go
@@ -509,16 +509,17 @@ func processTCPListenerXdsTranslation(tCtx *types.ResourceVersionTable, tcpListe
 
 		for _, route := range tcpListener.Routes {
 			if err := addXdsCluster(tCtx, &xdsClusterArgs{
-				name:           route.Destination.Name,
-				settings:       route.Destination.Settings,
-				loadBalancer:   route.LoadBalancer,
-				proxyProtocol:  route.ProxyProtocol,
-				circuitBreaker: route.CircuitBreaker,
-				tcpkeepalive:   route.TCPKeepalive,
-				healthCheck:    route.HealthCheck,
-				timeout:        route.Timeout,
-				endpointType:   buildEndpointType(route.Destination.Settings),
-				metrics:        metrics,
+				name:              route.Destination.Name,
+				settings:          route.Destination.Settings,
+				loadBalancer:      route.LoadBalancer,
+				proxyProtocol:     route.ProxyProtocol,
+				circuitBreaker:    route.CircuitBreaker,
+				tcpkeepalive:      route.TCPKeepalive,
+				healthCheck:       route.HealthCheck,
+				timeout:           route.Timeout,
+				endpointType:      buildEndpointType(route.Destination.Settings),
+				metrics:           metrics,
+				backendConnection: route.BackendConnection,
 			}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
 				errs = errors.Join(errs, err)
 			}
@@ -577,13 +578,14 @@ func processUDPListenerXdsTranslation(tCtx *types.ResourceVersionTable, udpListe
 
 			// 1:1 between IR UDPRoute and xDS Cluster
 			if err := addXdsCluster(tCtx, &xdsClusterArgs{
-				name:         route.Destination.Name,
-				settings:     route.Destination.Settings,
-				loadBalancer: route.LoadBalancer,
-				timeout:      route.Timeout,
-				tSocket:      nil,
-				endpointType: buildEndpointType(route.Destination.Settings),
-				metrics:      metrics,
+				name:              route.Destination.Name,
+				settings:          route.Destination.Settings,
+				loadBalancer:      route.LoadBalancer,
+				timeout:           route.Timeout,
+				tSocket:           nil,
+				endpointType:      buildEndpointType(route.Destination.Settings),
+				metrics:           metrics,
+				backendConnection: route.BackendConnection,
 			}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
 				errs = errors.Join(errs, err)
 			}
@@ -697,6 +699,7 @@ func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute
 		clusterArgs.healthCheck = bt.HealthCheck
 		clusterArgs.timeout = bt.Timeout
 		clusterArgs.tcpkeepalive = bt.TCPKeepalive
+		clusterArgs.backendConnection = bt.BackendConnection
 	}
 
 	if err := addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) {
diff --git a/site/content/en/contributions/design/extending-envoy-gateway.md b/site/content/en/contributions/design/extending-envoy-gateway.md
index 84c9755b1..f7d3f3675 100644
--- a/site/content/en/contributions/design/extending-envoy-gateway.md
+++ b/site/content/en/contributions/design/extending-envoy-gateway.md
@@ -293,7 +293,7 @@ service EnvoyGatewayExtension {
   - This decision was made to solve the problem about how resources introduced by an extension get watched. If an extension server watches its own resources then it would need some way to trigger an Envoy Gateway reconfigure when a resource that Envoy Gateway is not watching gets updated. Having Envoy Gateway watch all resources removes any concern about creating race confitions or reconcile loops that would result from Envoy Gateway and the extension server both having so much separate state that needs to be synchronized.
 - The Extension Server takes ownership of producing the correct xDS configuration in the hook responses
 - The Extension Server will be responsible for ensuring the performance of the hook processing time
-- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updadated in the future to pass
+- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updated in the future to pass
 additional information to extensions as new use-cases and needs are discovered.
 - The initial design supplies the scaffolding for both "pre xDS" and "post xDS" hooks. Only the post hooks are currently implemented which operate on xDS resources after they have been generated.
 The pre hooks will be implemented at a later date along with one or more hooks in the infra manager. The infra manager level hook(s) will exist to power use-cases such as dynamically creating Deployments/Services for the extension the
diff --git a/site/content/en/contributions/design/local-envoy-gateway.md b/site/content/en/contributions/design/local-envoy-gateway.md
index aad0dc5f6..81265297e 100644
--- a/site/content/en/contributions/design/local-envoy-gateway.md
+++ b/site/content/en/contributions/design/local-envoy-gateway.md
@@ -30,7 +30,7 @@ Envoy Proxy fleet on Kubernetes.
 with two fields called `resource` and `infrastructure` to allow the user to configure
 the sub providers for providing resource configuration and an infrastructure to deploy
 the Envoy Proxy data plane in.
-* A `File` resource provider will be introduced to enable retrieveing configuration locally
+* A `File` resource provider will be introduced to enable retrieving configuration locally
 by reading from the configuration from a file.
 * A `Host` infrastructure provider will be introduced to allow Envoy Gateway to spawn a 
 Envoy Proxy child process on the host.
diff --git a/site/content/en/v0.4.0/design/extending-envoy-gateway.md b/site/content/en/v0.4.0/design/extending-envoy-gateway.md
index fd8408489..df19dcc09 100644
--- a/site/content/en/v0.4.0/design/extending-envoy-gateway.md
+++ b/site/content/en/v0.4.0/design/extending-envoy-gateway.md
@@ -292,7 +292,7 @@ service EnvoyGatewayExtension {
   - This decision was made to solve the problem about how resources introduced by an extension get watched. If an extension server watches its own resources then it would need some way to trigger an Envoy Gateway reconfigure when a resource that Envoy Gateway is not watching gets updated. Having Envoy Gateway watch all resources removes any concern about creating race confitions or reconcile loops that would result from Envoy Gateway and the extension server both having so much separate state that needs to be synchronized.
 - The Extension Server takes ownership of producing the correct xDS configuration in the hook responses
 - The Extension Server will be responsible for ensuring the performance of the hook processing time
-- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updadated in the future to pass
+- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updated in the future to pass
 additional information to extensions as new use-cases and needs are discovered.
 - The initial design supplies the scaffolding for both "pre xDS" and "post xDS" hooks. Only the post hooks are currently implemented which operate on xDS resources after they have been generated.
 The pre hooks will be implemented at a later date along with one or more hooks in the infra manager. The infra manager level hook(s) will exist to power use-cases such as dynamically creating Deployments/Services for the extension the
diff --git a/site/content/en/v0.5.0/design/extending-envoy-gateway.md b/site/content/en/v0.5.0/design/extending-envoy-gateway.md
index 04e211fa5..0caa870ff 100644
--- a/site/content/en/v0.5.0/design/extending-envoy-gateway.md
+++ b/site/content/en/v0.5.0/design/extending-envoy-gateway.md
@@ -293,7 +293,7 @@ service EnvoyGatewayExtension {
   - This decision was made to solve the problem about how resources introduced by an extension get watched. If an extension server watches its own resources then it would need some way to trigger an Envoy Gateway reconfigure when a resource that Envoy Gateway is not watching gets updated. Having Envoy Gateway watch all resources removes any concern about creating race confitions or reconcile loops that would result from Envoy Gateway and the extension server both having so much separate state that needs to be synchronized.
 - The Extension Server takes ownership of producing the correct xDS configuration in the hook responses
 - The Extension Server will be responsible for ensuring the performance of the hook processing time
-- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updadated in the future to pass
+- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updated in the future to pass
 additional information to extensions as new use-cases and needs are discovered.
 - The initial design supplies the scaffolding for both "pre xDS" and "post xDS" hooks. Only the post hooks are currently implemented which operate on xDS resources after they have been generated.
 The pre hooks will be implemented at a later date along with one or more hooks in the infra manager. The infra manager level hook(s) will exist to power use-cases such as dynamically creating Deployments/Services for the extension the
diff --git a/site/content/en/v0.5.0/design/local-envoy-gateway.md b/site/content/en/v0.5.0/design/local-envoy-gateway.md
index aad0dc5f6..81265297e 100644
--- a/site/content/en/v0.5.0/design/local-envoy-gateway.md
+++ b/site/content/en/v0.5.0/design/local-envoy-gateway.md
@@ -30,7 +30,7 @@ Envoy Proxy fleet on Kubernetes.
 with two fields called `resource` and `infrastructure` to allow the user to configure
 the sub providers for providing resource configuration and an infrastructure to deploy
 the Envoy Proxy data plane in.
-* A `File` resource provider will be introduced to enable retrieveing configuration locally
+* A `File` resource provider will be introduced to enable retrieving configuration locally
 by reading from the configuration from a file.
 * A `Host` infrastructure provider will be introduced to allow Envoy Gateway to spawn a 
 Envoy Proxy child process on the host.
diff --git a/site/content/en/v0.6.0/design/extending-envoy-gateway.md b/site/content/en/v0.6.0/design/extending-envoy-gateway.md
index d84f553ef..104bd8045 100644
--- a/site/content/en/v0.6.0/design/extending-envoy-gateway.md
+++ b/site/content/en/v0.6.0/design/extending-envoy-gateway.md
@@ -293,7 +293,7 @@ service EnvoyGatewayExtension {
   - This decision was made to solve the problem about how resources introduced by an extension get watched. If an extension server watches its own resources then it would need some way to trigger an Envoy Gateway reconfigure when a resource that Envoy Gateway is not watching gets updated. Having Envoy Gateway watch all resources removes any concern about creating race confitions or reconcile loops that would result from Envoy Gateway and the extension server both having so much separate state that needs to be synchronized.
 - The Extension Server takes ownership of producing the correct xDS configuration in the hook responses
 - The Extension Server will be responsible for ensuring the performance of the hook processing time
-- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updadated in the future to pass
+- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updated in the future to pass
 additional information to extensions as new use-cases and needs are discovered.
 - The initial design supplies the scaffolding for both "pre xDS" and "post xDS" hooks. Only the post hooks are currently implemented which operate on xDS resources after they have been generated.
 The pre hooks will be implemented at a later date along with one or more hooks in the infra manager. The infra manager level hook(s) will exist to power use-cases such as dynamically creating Deployments/Services for the extension the
diff --git a/tools/linter/codespell/.codespell.skip b/tools/linter/codespell/.codespell.skip
index 319d3a78d..00240f7e1 100644
--- a/tools/linter/codespell/.codespell.skip
+++ b/tools/linter/codespell/.codespell.skip
@@ -12,3 +12,6 @@
 go.mod
 go.sum
 bin
+./charts
+*.js
+*/testdata/*.yaml
\ No newline at end of file
diff --git a/tools/src/codespell/requirements.txt b/tools/src/codespell/requirements.txt
index e0a43e138..ab09daf9d 100644
--- a/tools/src/codespell/requirements.txt
+++ b/tools/src/codespell/requirements.txt
@@ -1,1 +1,1 @@
-codespell==2.2.6
+codespell==2.3.0


Test patch:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.in.yaml
new file mode 100644
index 000000000..fab34fa24
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.in.yaml
@@ -0,0 +1,93 @@
+gateways:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: Gateway
+    metadata:
+      namespace: envoy-gateway
+      name: gateway-1
+    spec:
+      gatewayClassName: envoy-gateway-class
+      listeners:
+        - name: http
+          protocol: HTTP
+          port: 80
+          allowedRoutes:
+            namespaces:
+              from: All
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: Gateway
+    metadata:
+      namespace: envoy-gateway
+      name: gateway-2
+    spec:
+      gatewayClassName: envoy-gateway-class
+      listeners:
+        - name: http
+          protocol: HTTP
+          port: 80
+          allowedRoutes:
+            namespaces:
+              from: All
+grpcRoutes:
+  - apiVersion: gateway.networking.k8s.io/v1alpha2
+    kind: GRPCRoute
+    metadata:
+      namespace: default
+      name: grpcroute-1
+    spec:
+      parentRefs:
+        - namespace: envoy-gateway
+          name: gateway-1
+          sectionName: http
+      rules:
+        - backendRefs:
+            - name: service-1
+              port: 8080
+httpRoutes:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: HTTPRoute
+    metadata:
+      namespace: default
+      name: httproute-1
+    spec:
+      hostnames:
+        - gateway.envoyproxy.io
+      parentRefs:
+        - namespace: envoy-gateway
+          name: gateway-2
+          sectionName: http
+      rules:
+        - matches:
+            - path:
+                value: "/"
+          backendRefs:
+            - name: service-1
+              port: 8080
+backendTrafficPolicies:
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: BackendTrafficPolicy
+    metadata:
+      namespace: envoy-gateway
+      name: policy-for-gateway
+    spec:
+      targetRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+      timeout:
+        tcp:
+          connectTimeout: 15s
+        http:
+          connectionIdleTimeout: 16s
+          maxConnectionDuration: 17s
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: BackendTrafficPolicy
+    metadata:
+      namespace: default
+      name: policy-for-route
+    spec:
+      targetRef:
+        group: gateway.networking.k8s.io
+        kind: HTTPRoute
+        name: httproute-1
+      connection:
+        bufferLimit: 1000G
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.out.yaml
new file mode 100644
index 000000000..3337fe2e9
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-out-of-range-error.out.yaml
@@ -0,0 +1,311 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-route
+    namespace: default
+  spec:
+    connection:
+      bufferLimit: 1T
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-1
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: 'BackendConnection: BufferLimit value 1T is out of range.'
+        reason: Invalid
+        status: "False"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-gateway
+    namespace: envoy-gateway
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+    timeout:
+      http:
+        connectionIdleTimeout: 16s
+        maxConnectionDuration: 17s
+      tcp:
+        connectTimeout: 15s
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-2
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+  kind: GRPCRoute
+  metadata:
+    creationTimestamp: null
+    name: grpcroute-1
+    namespace: default
+  spec:
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-1
+    namespace: default
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - name: gateway-2
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+infraIR:
+  envoy-gateway/gateway-1:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-1
+  envoy-gateway/gateway-2:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-2/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-2
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-2
+xdsIR:
+  envoy-gateway/gateway-1:
+    accessLog:
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: true
+      name: envoy-gateway/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: grpcroute/default/grpcroute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: GRPC
+            weight: 1
+        hostname: '*'
+        isHTTP2: true
+        name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+        traffic:
+          timeout:
+            http:
+              connectionIdleTimeout: 16s
+              maxConnectionDuration: 17s
+            tcp:
+              connectTimeout: 15s
+  envoy-gateway/gateway-2:
+    accessLog:
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      name: envoy-gateway/gateway-2/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: httproute/default/httproute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        hostname: gateway.envoyproxy.io
+        isHTTP2: false
+        name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.in.yaml
new file mode 100644
index 000000000..fb290963e
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.in.yaml
@@ -0,0 +1,93 @@
+gateways:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: Gateway
+    metadata:
+      namespace: envoy-gateway
+      name: gateway-1
+    spec:
+      gatewayClassName: envoy-gateway-class
+      listeners:
+        - name: http
+          protocol: HTTP
+          port: 80
+          allowedRoutes:
+            namespaces:
+              from: All
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: Gateway
+    metadata:
+      namespace: envoy-gateway
+      name: gateway-2
+    spec:
+      gatewayClassName: envoy-gateway-class
+      listeners:
+        - name: http
+          protocol: HTTP
+          port: 80
+          allowedRoutes:
+            namespaces:
+              from: All
+grpcRoutes:
+  - apiVersion: gateway.networking.k8s.io/v1alpha2
+    kind: GRPCRoute
+    metadata:
+      namespace: default
+      name: grpcroute-1
+    spec:
+      parentRefs:
+        - namespace: envoy-gateway
+          name: gateway-1
+          sectionName: http
+      rules:
+        - backendRefs:
+            - name: service-1
+              port: 8080
+httpRoutes:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: HTTPRoute
+    metadata:
+      namespace: default
+      name: httproute-1
+    spec:
+      hostnames:
+        - gateway.envoyproxy.io
+      parentRefs:
+        - namespace: envoy-gateway
+          name: gateway-2
+          sectionName: http
+      rules:
+        - matches:
+            - path:
+                value: "/"
+          backendRefs:
+            - name: service-1
+              port: 8080
+backendTrafficPolicies:
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: BackendTrafficPolicy
+    metadata:
+      namespace: envoy-gateway
+      name: policy-for-gateway
+    spec:
+      targetRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+      timeout:
+        tcp:
+          connectTimeout: 15s
+        http:
+          connectionIdleTimeout: 16s
+          maxConnectionDuration: 17s
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: BackendTrafficPolicy
+    metadata:
+      namespace: default
+      name: policy-for-route
+    spec:
+      targetRef:
+        group: gateway.networking.k8s.io
+        kind: HTTPRoute
+        name: httproute-1
+      connection:
+        bufferLimit: 100m
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.out.yaml
new file mode 100644
index 000000000..e2fd6c066
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit-with-invalid-value.out.yaml
@@ -0,0 +1,311 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-route
+    namespace: default
+  spec:
+    connection:
+      bufferLimit: 100m
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-1
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: 'BackendConnection: invalid BufferLimit value 100m.'
+        reason: Invalid
+        status: "False"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-gateway
+    namespace: envoy-gateway
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+    timeout:
+      http:
+        connectionIdleTimeout: 16s
+        maxConnectionDuration: 17s
+      tcp:
+        connectTimeout: 15s
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-2
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+  kind: GRPCRoute
+  metadata:
+    creationTimestamp: null
+    name: grpcroute-1
+    namespace: default
+  spec:
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-1
+    namespace: default
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - name: gateway-2
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+infraIR:
+  envoy-gateway/gateway-1:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-1
+  envoy-gateway/gateway-2:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-2/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-2
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-2
+xdsIR:
+  envoy-gateway/gateway-1:
+    accessLog:
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: true
+      name: envoy-gateway/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: grpcroute/default/grpcroute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: GRPC
+            weight: 1
+        hostname: '*'
+        isHTTP2: true
+        name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+        traffic:
+          timeout:
+            http:
+              connectionIdleTimeout: 16s
+              maxConnectionDuration: 17s
+            tcp:
+              connectTimeout: 15s
+  envoy-gateway/gateway-2:
+    accessLog:
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      name: envoy-gateway/gateway-2/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: httproute/default/httproute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        hostname: gateway.envoyproxy.io
+        isHTTP2: false
+        name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit.in.yaml
new file mode 100644
index 000000000..20806f8f9
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit.in.yaml
@@ -0,0 +1,93 @@
+gateways:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: Gateway
+    metadata:
+      namespace: envoy-gateway
+      name: gateway-1
+    spec:
+      gatewayClassName: envoy-gateway-class
+      listeners:
+        - name: http
+          protocol: HTTP
+          port: 80
+          allowedRoutes:
+            namespaces:
+              from: All
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: Gateway
+    metadata:
+      namespace: envoy-gateway
+      name: gateway-2
+    spec:
+      gatewayClassName: envoy-gateway-class
+      listeners:
+        - name: http
+          protocol: HTTP
+          port: 80
+          allowedRoutes:
+            namespaces:
+              from: All
+grpcRoutes:
+  - apiVersion: gateway.networking.k8s.io/v1alpha2
+    kind: GRPCRoute
+    metadata:
+      namespace: default
+      name: grpcroute-1
+    spec:
+      parentRefs:
+        - namespace: envoy-gateway
+          name: gateway-1
+          sectionName: http
+      rules:
+        - backendRefs:
+            - name: service-1
+              port: 8080
+httpRoutes:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: HTTPRoute
+    metadata:
+      namespace: default
+      name: httproute-1
+    spec:
+      hostnames:
+        - gateway.envoyproxy.io
+      parentRefs:
+        - namespace: envoy-gateway
+          name: gateway-2
+          sectionName: http
+      rules:
+        - matches:
+            - path:
+                value: "/"
+          backendRefs:
+            - name: service-1
+              port: 8080
+backendTrafficPolicies:
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: BackendTrafficPolicy
+    metadata:
+      namespace: envoy-gateway
+      name: policy-for-gateway
+    spec:
+      targetRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+      timeout:
+        tcp:
+          connectTimeout: 15s
+        http:
+          connectionIdleTimeout: 16s
+          maxConnectionDuration: 17s
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: BackendTrafficPolicy
+    metadata:
+      namespace: default
+      name: policy-for-route
+    spec:
+      targetRef:
+        group: gateway.networking.k8s.io
+        kind: HTTPRoute
+        name: httproute-1
+      connection:
+        bufferLimit: 100M
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit.out.yaml
new file mode 100644
index 000000000..2917b90f0
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-buffer-limit.out.yaml
@@ -0,0 +1,314 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-route
+    namespace: default
+  spec:
+    connection:
+      bufferLimit: 100M
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-1
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-gateway
+    namespace: envoy-gateway
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+    timeout:
+      http:
+        connectionIdleTimeout: 16s
+        maxConnectionDuration: 17s
+      tcp:
+        connectTimeout: 15s
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-2
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+  kind: GRPCRoute
+  metadata:
+    creationTimestamp: null
+    name: grpcroute-1
+    namespace: default
+  spec:
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-1
+    namespace: default
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - name: gateway-2
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+infraIR:
+  envoy-gateway/gateway-1:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-1
+  envoy-gateway/gateway-2:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-2/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-2
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-2
+xdsIR:
+  envoy-gateway/gateway-1:
+    accessLog:
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: true
+      name: envoy-gateway/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: grpcroute/default/grpcroute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: GRPC
+            weight: 1
+        hostname: '*'
+        isHTTP2: true
+        name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
+        traffic:
+          timeout:
+            http:
+              connectionIdleTimeout: 16s
+              maxConnectionDuration: 17s
+            tcp:
+              connectTimeout: 15s
+  envoy-gateway/gateway-2:
+    accessLog:
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      name: envoy-gateway/gateway-2/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: httproute/default/httproute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        hostname: gateway.envoyproxy.io
+        isHTTP2: false
+        name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /
+        traffic:
+          backendConnection:
+            bufferLimit: 100000000
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 7e3d794b7..695ab6bd7 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
@@ -196,7 +196,8 @@ xdsIR:
               - cidrMatch:
                   cidr: 192.168.0.0/16
                   distinct: false
-                  ipv6: false
+                  ip: 192.168.0.0
+                  isIPv6: false
                   maskLen: 16
                 headerMatches:
                 - distinct: false
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml
index 9ebb100f6..b7508bc79 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml
@@ -199,7 +199,8 @@ xdsIR:
               - cidrMatch:
                   cidr: 192.168.0.0/16
                   distinct: false
-                  ipv6: false
+                  ip: 192.168.0.0
+                  isIPv6: false
                   maskLen: 16
                 headerMatches:
                 - distinct: false
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
index 390752796..bdb547ffe 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml
@@ -338,7 +338,8 @@ xdsIR:
               - cidrMatch:
                   cidr: 192.168.0.0/16
                   distinct: true
-                  ipv6: false
+                  ip: 192.168.0.0
+                  isIPv6: false
                   maskLen: 16
                 headerMatches: []
                 limit:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.in.yaml
new file mode 100644
index 000000000..fe89f0dd8
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.in.yaml
@@ -0,0 +1,128 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    namespace: envoy-gateway
+    name: gateway-1
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - name: http
+      protocol: HTTP
+      port: 80
+      allowedRoutes:
+        namespaces:
+          from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-1
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/foo"
+      backendRefs:
+      - name: service-1
+        port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-2
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/bar"
+      backendRefs:
+      - name: service-1
+        port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-3
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/test"
+      backendRefs:
+      - name: service-1
+        port: 8080
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    namespace: envoy-gateway
+    name: policy-for-gateway  # This policy should attach httproute-2
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+    authorization:
+      defaultAction: Deny
+      rules:
+      - action: Allow
+        principal:
+          clientCIDRs:
+          - 10.0.1.0/24
+          - 10.0.2.0/24
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    namespace: default
+    name: policy-for-http-route-1   # This policy should attach httproute-1
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-1
+    authorization:
+      defaultAction: Allow
+      rules:
+      - name: "deny-location-1"
+        action: Deny
+        principal:
+          clientCIDRs:
+          - 192.168.1.0/24
+          - 192.168.2.0/24
+      - name: "deny-location-2"
+        action: Deny
+        principal:
+          clientCIDRs:
+          - 10.75.1.0/24
+          - 10.75.2.0/24
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    namespace: default
+    name: policy-for-http-route-3   # This policy should attach httproute-3
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-3
+    authorization: {}
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.out.yaml
new file mode 100755
index 000000000..1f6103bb2
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion.out.yaml
@@ -0,0 +1,398 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 3
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-1
+    namespace: default
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /foo
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-2
+    namespace: default
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /bar
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-3
+    namespace: default
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /test
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+infraIR:
+  envoy-gateway/gateway-1:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-http-route-1
+    namespace: default
+  spec:
+    authorization:
+      defaultAction: Allow
+      rules:
+      - action: Deny
+        name: deny-location-1
+        principal:
+          clientCIDRs:
+          - 192.168.1.0/24
+          - 192.168.2.0/24
+      - action: Deny
+        name: deny-location-2
+        principal:
+          clientCIDRs:
+          - 10.75.1.0/24
+          - 10.75.2.0/24
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-1
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-http-route-3
+    namespace: default
+  spec:
+    authorization:
+      defaultAction: null
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-3
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-gateway
+    namespace: envoy-gateway
+  spec:
+    authorization:
+      defaultAction: Deny
+      rules:
+      - action: Allow
+        principal:
+          clientCIDRs:
+          - 10.0.1.0/24
+          - 10.0.2.0/24
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: 'This policy is being overridden by other securityPolicies for these
+          routes: [default/httproute-1 default/httproute-3]'
+        reason: Overridden
+        status: "True"
+        type: Overridden
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+  envoy-gateway/gateway-1:
+    accessLog:
+      text:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      name: envoy-gateway/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: httproute/default/httproute-3/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        hostname: www.example.com
+        isHTTP2: false
+        name: httproute/default/httproute-3/rule/0/match/0/www_example_com
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /test
+        security:
+          authorization:
+            defaultAction: Deny
+      - destination:
+          name: httproute/default/httproute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        hostname: www.example.com
+        isHTTP2: false
+        name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /foo
+        security:
+          authorization:
+            defaultAction: Allow
+            rules:
+            - action: Deny
+              name: deny-location-1
+              principal:
+                clientCIDRs:
+                - cidr: 192.168.1.0/24
+                  distinct: false
+                  ip: 192.168.1.0
+                  isIPv6: false
+                  maskLen: 24
+                - cidr: 192.168.2.0/24
+                  distinct: false
+                  ip: 192.168.2.0
+                  isIPv6: false
+                  maskLen: 24
+            - action: Deny
+              name: deny-location-2
+              principal:
+                clientCIDRs:
+                - cidr: 10.75.1.0/24
+                  distinct: false
+                  ip: 10.75.1.0
+                  isIPv6: false
+                  maskLen: 24
+                - cidr: 10.75.2.0/24
+                  distinct: false
+                  ip: 10.75.2.0
+                  isIPv6: false
+                  maskLen: 24
+      - destination:
+          name: httproute/default/httproute-2/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        hostname: www.example.com
+        isHTTP2: false
+        name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /bar
+        security:
+          authorization:
+            defaultAction: Deny
+            rules:
+            - action: Allow
+              name: securitypolicy/envoy-gateway/policy-for-gateway/authorization/rule/0
+              principal:
+                clientCIDRs:
+                - cidr: 10.0.1.0/24
+                  distinct: false
+                  ip: 10.0.1.0
+                  isIPv6: false
+                  maskLen: 24
+                - cidr: 10.0.2.0/24
+                  distinct: false
+                  ip: 10.0.2.0
+                  isIPv6: false
+                  maskLen: 24
diff --git a/internal/xds/translator/httpfilters_test.go b/internal/xds/translator/httpfilters_test.go
index 2f277aa96..5516dc0d9 100644
--- a/internal/xds/translator/httpfilters_test.go
+++ b/internal/xds/translator/httpfilters_test.go
@@ -13,14 +13,14 @@ import (
 	"github.com/stretchr/testify/assert"
 	"k8s.io/utils/ptr"
 
-	"github.com/envoyproxy/gateway/api/v1alpha1"
+	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 )
 
 func Test_sortHTTPFilters(t *testing.T) {
 	tests := []struct {
 		name        string
 		filters     []*hcmv3.HttpFilter
-		filterOrder []v1alpha1.FilterPosition
+		filterOrder []egv1a1.FilterPosition
 		want        []*hcmv3.HttpFilter
 	}{
 		{
@@ -40,6 +40,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
 			want: []*hcmv3.HttpFilter{
 				httpFilterForTest(wellknown.Fault),
@@ -53,6 +54,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.HTTPRateLimit),
 				httpFilterForTest(wellknown.Router),
@@ -75,15 +77,16 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:  v1alpha1.EnvoyFilterFault,
-					After: ptr.To(v1alpha1.EnvoyFilterCORS),
+					Name:  egv1a1.EnvoyFilterFault,
+					After: ptr.To(egv1a1.EnvoyFilterCORS),
 				},
 				{
-					Name:   v1alpha1.EnvoyFilterRateLimit,
-					Before: ptr.To(v1alpha1.EnvoyFilterJWTAuthn),
+					Name:   egv1a1.EnvoyFilterRateLimit,
+					Before: ptr.To(egv1a1.EnvoyFilterJWTAuthn),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -99,6 +102,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.Router),
 			},
@@ -120,11 +124,12 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:   v1alpha1.EnvoyFilterRateLimit,
-					Before: ptr.To(v1alpha1.EnvoyFilterWasm),
+					Name:   egv1a1.EnvoyFilterRateLimit,
+					Before: ptr.To(egv1a1.EnvoyFilterWasm),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -140,6 +145,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.Router),
 			},
@@ -161,11 +167,12 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:  v1alpha1.EnvoyFilterJWTAuthn,
-					After: ptr.To(v1alpha1.EnvoyFilterWasm),
+					Name:  egv1a1.EnvoyFilterJWTAuthn,
+					After: ptr.To(egv1a1.EnvoyFilterWasm),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -180,6 +187,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"),
 				httpFilterForTest(jwtAuthn),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.HTTPRateLimit),
 				httpFilterForTest(wellknown.Router),
@@ -202,11 +210,12 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:   v1alpha1.EnvoyFilterWasm,
-					Before: ptr.To(v1alpha1.EnvoyFilterJWTAuthn),
+					Name:   egv1a1.EnvoyFilterWasm,
+					Before: ptr.To(egv1a1.EnvoyFilterJWTAuthn),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -221,6 +230,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(jwtAuthn),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.HTTPRateLimit),
 				httpFilterForTest(wellknown.Router),
@@ -243,11 +253,12 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:  v1alpha1.EnvoyFilterWasm,
-					After: ptr.To(v1alpha1.EnvoyFilterRateLimit),
+					Name:  egv1a1.EnvoyFilterWasm,
+					After: ptr.To(egv1a1.EnvoyFilterRateLimit),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -259,6 +270,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(jwtAuthn),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.HTTPRateLimit),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
@@ -284,11 +296,12 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:   v1alpha1.EnvoyFilterWasm,
-					Before: ptr.To(v1alpha1.EnvoyFilterExtProc),
+					Name:   egv1a1.EnvoyFilterWasm,
+					Before: ptr.To(egv1a1.EnvoyFilterExtProc),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -303,6 +316,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.HTTPRateLimit),
 				httpFilterForTest(wellknown.Router),
@@ -325,11 +339,12 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:  v1alpha1.EnvoyFilterExtProc,
-					After: ptr.To(v1alpha1.EnvoyFilterWasm),
+					Name:  egv1a1.EnvoyFilterExtProc,
+					After: ptr.To(egv1a1.EnvoyFilterWasm),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -344,6 +359,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wellknown.HTTPRateLimit),
 				httpFilterForTest(wellknown.Router),
@@ -366,23 +382,24 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(extProcFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/0"),
 				httpFilterForTest(localRateLimitFilter),
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/1"),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 			},
-			filterOrder: []v1alpha1.FilterPosition{
+			filterOrder: []egv1a1.FilterPosition{
 				{
-					Name:   v1alpha1.EnvoyFilterLocalRateLimit,
-					Before: ptr.To(v1alpha1.EnvoyFilterJWTAuthn),
+					Name:   egv1a1.EnvoyFilterLocalRateLimit,
+					Before: ptr.To(egv1a1.EnvoyFilterJWTAuthn),
 				},
 				{
-					Name:  v1alpha1.EnvoyFilterLocalRateLimit,
-					After: ptr.To(v1alpha1.EnvoyFilterCORS),
+					Name:  egv1a1.EnvoyFilterLocalRateLimit,
+					After: ptr.To(egv1a1.EnvoyFilterCORS),
 				},
 				{
-					Name:   v1alpha1.EnvoyFilterWasm,
-					Before: ptr.To(v1alpha1.EnvoyFilterOAuth2),
+					Name:   egv1a1.EnvoyFilterWasm,
+					Before: ptr.To(egv1a1.EnvoyFilterOAuth2),
 				},
 				{
-					Name:   v1alpha1.EnvoyFilterExtProc,
-					Before: ptr.To(v1alpha1.EnvoyFilterWasm),
+					Name:   egv1a1.EnvoyFilterExtProc,
+					Before: ptr.To(egv1a1.EnvoyFilterWasm),
 				},
 			},
 			want: []*hcmv3.HttpFilter{
@@ -398,6 +415,7 @@ func Test_sortHTTPFilters(t *testing.T) {
 				httpFilterForTest(wasmFilter + "/envoyextensionpolicy/default/policy-for-http-route-1/2"),
 				httpFilterForTest(oauth2Filter + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(jwtAuthn),
+				httpFilterForTest(string(egv1a1.EnvoyFilterRBAC) + "/securitypolicy/default/policy-for-http-route-1"),
 				httpFilterForTest(wellknown.HTTPRateLimit),
 				httpFilterForTest(wellknown.Router),
 			},
diff --git a/internal/xds/translator/testdata/in/xds-ir/authorization.yaml b/internal/xds/translator/testdata/in/xds-ir/authorization.yaml
new file mode 100644
index 000000000..d36a738a7
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/authorization.yaml
@@ -0,0 +1,112 @@
+http:
+- address: 0.0.0.0
+  hostnames:
+  - '*'
+  isHTTP2: false
+  name: envoy-gateway/gateway-1/http
+  path:
+    escapedSlashesAction: UnescapeAndRedirect
+    mergeSlashes: true
+  port: 10080
+  routes:
+  - destination:
+      name: httproute/default/httproute-3/rule/0
+      settings:
+      - addressType: IP
+        endpoints:
+        - host: 7.7.7.7
+          port: 8080
+        protocol: HTTP
+        weight: 1
+    hostname: www.example.com
+    isHTTP2: false
+    name: httproute/default/httproute-3/rule/0/match/0/www_example_com
+    pathMatch:
+      distinct: false
+      name: ""
+      prefix: /test
+    security:
+      authorization:
+        defaultAction: Deny
+  - destination:
+      name: httproute/default/httproute-1/rule/0
+      settings:
+      - addressType: IP
+        endpoints:
+        - host: 7.7.7.7
+          port: 8080
+        protocol: HTTP
+        weight: 1
+    hostname: www.example.com
+    isHTTP2: false
+    name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+    pathMatch:
+      distinct: false
+      name: ""
+      prefix: /foo
+    security:
+      authorization:
+        defaultAction: Allow
+        rules:
+        - action: Deny
+          name: deny-location-1
+          principal:
+            clientCIDRs:
+            - cidr: 192.168.1.0/24
+              distinct: false
+              ip: 192.168.1.0
+              isIPv6: false
+              maskLen: 24
+            - cidr: 192.168.2.0/24
+              distinct: false
+              ip: 192.168.2.0
+              isIPv6: false
+              maskLen: 24
+        - action: Deny
+          name: deny-location-2
+          principal:
+            clientCIDRs:
+            - cidr: 10.75.1.0/24
+              distinct: false
+              ip: 10.75.1.0
+              isIPv6: false
+              maskLen: 24
+            - cidr: 10.75.2.0/24
+              distinct: false
+              ip: 10.75.2.0
+              isIPv6: false
+              maskLen: 24
+  - destination:
+      name: httproute/default/httproute-2/rule/0
+      settings:
+      - addressType: IP
+        endpoints:
+        - host: 7.7.7.7
+          port: 8080
+        protocol: HTTP
+        weight: 1
+    hostname: www.example.com
+    isHTTP2: false
+    name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+    pathMatch:
+      distinct: false
+      name: ""
+      prefix: /bar
+    security:
+      authorization:
+        defaultAction: Deny
+        rules:
+        - action: Allow
+          name: securitypolicy/envoy-gateway/policy-for-gateway/authorization/rule/0
+          principal:
+            clientCIDRs:
+            - cidr: 10.0.1.0/24
+              distinct: false
+              ip: 10.0.1.0
+              isIPv6: false
+              maskLen: 24
+            - cidr: 10.0.2.0/24
+              distinct: false
+              ip: 10.0.2.0
+              isIPv6: false
+              maskLen: 24
diff --git a/internal/xds/translator/testdata/in/xds-ir/backend-buffer-limit.yaml b/internal/xds/translator/testdata/in/xds-ir/backend-buffer-limit.yaml
new file mode 100644
index 000000000..493180389
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/backend-buffer-limit.yaml
@@ -0,0 +1,53 @@
+http:
+  - name: "first-listener"
+    address: "0.0.0.0"
+    port: 10080
+    hostnames:
+      - "*"
+    path:
+      mergeSlashes: true
+      escapedSlashesAction: UnescapeAndRedirect
+    routes:
+      - name: "first-route"
+        hostname: "*"
+        destination:
+          name: "first-route-dest"
+          settings:
+            - endpoints:
+                - host: "1.2.3.4"
+                  port: 50000
+        traffic:
+          backendConnection:
+            bufferLimit: 100000000
+tcp:
+  - name: "second-listener"
+    address: "0.0.0.0"
+    connection:
+      bufferLimit: 1500
+    port: 10081
+    routes:
+      - name: "tcp-route-dest"
+        destination:
+          name: "tcp-route-dest"
+          settings:
+            - endpoints:
+                - host: "1.2.3.4"
+                  port: 50000
+        backendConnection:
+          bufferLimit: 100000000
+udp:
+  - name: "udp-route"
+    address: "0.0.0.0"
+    port: 10080
+    route:
+      name: "udp-route"
+      destination:
+        name: "udp-route-dest"
+        settings:
+          - endpoints:
+              - host: "1.2.3.4"
+                port: 50000
+              - host: "5.6.7.8"
+                port: 50001
+      backendConnection:
+        bufferLimit: 100000000
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization.clusters.yaml
new file mode 100644
index 000000000..b3f75f0e0
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization.clusters.yaml
@@ -0,0 +1,51 @@
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: httproute/default/httproute-3/rule/0
+  lbPolicy: LEAST_REQUEST
+  name: httproute/default/httproute-3/rule/0
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: httproute/default/httproute-1/rule/0
+  lbPolicy: LEAST_REQUEST
+  name: httproute/default/httproute-1/rule/0
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: httproute/default/httproute-2/rule/0
+  lbPolicy: LEAST_REQUEST
+  name: httproute/default/httproute-2/rule/0
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization.endpoints.yaml
new file mode 100644
index 000000000..24596d841
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization.endpoints.yaml
@@ -0,0 +1,36 @@
+- clusterName: httproute/default/httproute-3/rule/0
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 7.7.7.7
+            portValue: 8080
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: httproute/default/httproute-3/rule/0/backend/0
+- clusterName: httproute/default/httproute-1/rule/0
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 7.7.7.7
+            portValue: 8080
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 7.7.7.7
+            portValue: 8080
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization.listeners.yaml
new file mode 100644
index 000000000..746999960
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization.listeners.yaml
@@ -0,0 +1,37 @@
+- address:
+    socketAddress:
+      address: 0.0.0.0
+      portValue: 10080
+  defaultFilterChain:
+    filters:
+    - name: envoy.filters.network.http_connection_manager
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+        commonHttpProtocolOptions:
+          headersWithUnderscoresAction: REJECT_REQUEST
+        http2ProtocolOptions:
+          initialConnectionWindowSize: 1048576
+          initialStreamWindowSize: 65536
+          maxConcurrentStreams: 100
+        httpFilters:
+        - name: envoy.filters.http.rbac
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
+        - name: envoy.filters.http.router
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+            suppressEnvoyHeaders: true
+        mergeSlashes: true
+        normalizePath: true
+        pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+        rds:
+          configSource:
+            ads: {}
+            resourceApiVersion: V3
+          routeConfigName: envoy-gateway/gateway-1/http
+        serverHeaderTransformation: PASS_THROUGH
+        statPrefix: http
+        useRemoteAddress: true
+  drainType: MODIFY_ONLY
+  name: envoy-gateway/gateway-1/http
+  perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization.routes.yaml
new file mode 100644
index 000000000..141d60a15
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization.routes.yaml
@@ -0,0 +1,135 @@
+- ignorePortInHostMatching: true
+  name: envoy-gateway/gateway-1/http
+  virtualHosts:
+  - domains:
+    - www.example.com
+    name: envoy-gateway/gateway-1/http/www_example_com
+    routes:
+    - match:
+        pathSeparatedPrefix: /test
+      name: httproute/default/httproute-3/rule/0/match/0/www_example_com
+      route:
+        cluster: httproute/default/httproute-3/rule/0
+        upgradeConfigs:
+        - upgradeType: websocket
+      typedPerFilterConfig:
+        envoy.filters.http.rbac:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+          rbac:
+            matcher:
+              onNoMatch:
+                action:
+                  name: default
+                  typedConfig:
+                    '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                    action: DENY
+                    name: DENY
+    - match:
+        pathSeparatedPrefix: /foo
+      name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+      route:
+        cluster: httproute/default/httproute-1/rule/0
+        upgradeConfigs:
+        - upgradeType: websocket
+      typedPerFilterConfig:
+        envoy.filters.http.rbac:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+          rbac:
+            matcher:
+              matcherList:
+                matchers:
+                - onMatch:
+                    action:
+                      name: deny-location-1
+                      typedConfig:
+                        '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                        action: DENY
+                        name: DENY
+                  predicate:
+                    singlePredicate:
+                      customMatch:
+                        name: ip_matcher
+                        typedConfig:
+                          '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+                          cidrRanges:
+                          - addressPrefix: 192.168.1.0
+                            prefixLen: 24
+                          - addressPrefix: 192.168.2.0
+                            prefixLen: 24
+                          statPrefix: client_ip
+                      input:
+                        name: client_ip
+                        typedConfig:
+                          '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+                - onMatch:
+                    action:
+                      name: deny-location-2
+                      typedConfig:
+                        '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                        action: DENY
+                        name: DENY
+                  predicate:
+                    singlePredicate:
+                      customMatch:
+                        name: ip_matcher
+                        typedConfig:
+                          '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+                          cidrRanges:
+                          - addressPrefix: 10.75.1.0
+                            prefixLen: 24
+                          - addressPrefix: 10.75.2.0
+                            prefixLen: 24
+                          statPrefix: client_ip
+                      input:
+                        name: client_ip
+                        typedConfig:
+                          '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+              onNoMatch:
+                action:
+                  name: default
+                  typedConfig:
+                    '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                    name: ALLOW
+    - match:
+        pathSeparatedPrefix: /bar
+      name: httproute/default/httproute-2/rule/0/match/0/www_example_com
+      route:
+        cluster: httproute/default/httproute-2/rule/0
+        upgradeConfigs:
+        - upgradeType: websocket
+      typedPerFilterConfig:
+        envoy.filters.http.rbac:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+          rbac:
+            matcher:
+              matcherList:
+                matchers:
+                - onMatch:
+                    action:
+                      name: securitypolicy/envoy-gateway/policy-for-gateway/authorization/rule/0
+                      typedConfig:
+                        '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                        name: ALLOW
+                  predicate:
+                    singlePredicate:
+                      customMatch:
+                        name: ip_matcher
+                        typedConfig:
+                          '@type': type.googleapis.com/envoy.extensions.matching.input_matchers.ip.v3.Ip
+                          cidrRanges:
+                          - addressPrefix: 10.0.1.0
+                            prefixLen: 24
+                          - addressPrefix: 10.0.2.0
+                            prefixLen: 24
+                          statPrefix: client_ip
+                      input:
+                        name: client_ip
+                        typedConfig:
+                          '@type': type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
+              onNoMatch:
+                action:
+                  name: default
+                  typedConfig:
+                    '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                    action: DENY
+                    name: DENY
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.clusters.yaml
new file mode 100644
index 000000000..8b9fea622
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.clusters.yaml
@@ -0,0 +1,51 @@
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: first-route-dest
+  lbPolicy: LEAST_REQUEST
+  name: first-route-dest
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 100000000
+  type: EDS
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: tcp-route-dest
+  lbPolicy: LEAST_REQUEST
+  name: tcp-route-dest
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 100000000
+  type: EDS
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_ONLY
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: udp-route-dest
+  lbPolicy: LEAST_REQUEST
+  name: udp-route-dest
+  outlierDetection: {}
+  perConnectionBufferLimitBytes: 100000000
+  type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.endpoints.yaml
new file mode 100644
index 000000000..f6c3bfe17
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.endpoints.yaml
@@ -0,0 +1,42 @@
+- clusterName: first-route-dest
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.2.3.4
+            portValue: 50000
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: first-route-dest/backend/0
+- clusterName: tcp-route-dest
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.2.3.4
+            portValue: 50000
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: tcp-route-dest/backend/0
+- clusterName: udp-route-dest
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.2.3.4
+            portValue: 50000
+      loadBalancingWeight: 1
+    - endpoint:
+        address:
+          socketAddress:
+            address: 5.6.7.8
+            portValue: 50001
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: udp-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.listeners.yaml
new file mode 100644
index 000000000..17c3f17ad
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.listeners.yaml
@@ -0,0 +1,66 @@
+- address:
+    socketAddress:
+      address: 0.0.0.0
+      portValue: 10080
+  defaultFilterChain:
+    filters:
+    - name: envoy.filters.network.http_connection_manager
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+        commonHttpProtocolOptions:
+          headersWithUnderscoresAction: REJECT_REQUEST
+        http2ProtocolOptions:
+          initialConnectionWindowSize: 1048576
+          initialStreamWindowSize: 65536
+          maxConcurrentStreams: 100
+        httpFilters:
+        - name: envoy.filters.http.router
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+            suppressEnvoyHeaders: true
+        mergeSlashes: true
+        normalizePath: true
+        pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+        rds:
+          configSource:
+            ads: {}
+            resourceApiVersion: V3
+          routeConfigName: first-listener
+        serverHeaderTransformation: PASS_THROUGH
+        statPrefix: http
+        useRemoteAddress: true
+  drainType: MODIFY_ONLY
+  name: first-listener
+  perConnectionBufferLimitBytes: 32768
+- address:
+    socketAddress:
+      address: 0.0.0.0
+      portValue: 10081
+  drainType: MODIFY_ONLY
+  filterChains:
+  - filters:
+    - name: envoy.filters.network.tcp_proxy
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+        cluster: tcp-route-dest
+        statPrefix: tcp
+  name: second-listener
+  perConnectionBufferLimitBytes: 1500
+- address:
+    socketAddress:
+      address: 0.0.0.0
+      portValue: 10080
+      protocol: UDP
+  listenerFilters:
+  - name: envoy.filters.udp_listener.udp_proxy
+    typedConfig:
+      '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig
+      matcher:
+        onNoMatch:
+          action:
+            name: route
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route
+              cluster: udp-route-dest
+      statPrefix: service
+  name: udp-route
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.routes.yaml
new file mode 100644
index 000000000..0b5b4bee7
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-buffer-limit.routes.yaml
@@ -0,0 +1,14 @@
+- ignorePortInHostMatching: true
+  name: first-listener
+  virtualHosts:
+  - domains:
+    - '*'
+    name: first-listener/*
+    routes:
+    - match:
+        prefix: /
+      name: first-route
+      route:
+        cluster: first-route-dest
+        upgradeConfigs:
+        - upgradeType: websocket
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index d28b28339..87767fc42 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -195,13 +195,48 @@ _Appears in:_
 
 Authorization defines the authorization configuration.
 
+
+Note: if neither `Rules` nor `DefaultAction` is specified, the default action is to deny all requests.
+
 _Appears in:_
 - [SecurityPolicySpec](#securitypolicyspec)
 
 | Field | Type | Required | Description |
 | ---   | ---  | ---      | ---         |
-| `rules` | _[Rule](#rule) array_ |  false  | Rules defines a list of authorization rules.<br />These rules are evaluated in order, the first matching rule will be applied,<br />and the rest will be skipped.<br /><br />For example, if there are two rules: the first rule allows the request<br />and the second rule denies it, when a request matches both rules, it will be allowed. |
-| `defaultAction` | _[RuleActionType](#ruleactiontype)_ |  false  | DefaultAction defines the default action to be taken if no rules match.<br />If not specified, the default action is Deny. |
+| `rules` | _[AuthorizationRule](#authorizationrule) array_ |  false  | Rules defines a list of authorization rules.<br />These rules are evaluated in order, the first matching rule will be applied,<br />and the rest will be skipped.<br /><br />For example, if there are two rules: the first rule allows the request<br />and the second rule denies it, when a request matches both rules, it will be allowed. |
+| `defaultAction` | _[AuthorizationAction](#authorizationaction)_ |  false  | DefaultAction defines the default action to be taken if no rules match.<br />If not specified, the default action is Deny. |
+
+
+#### AuthorizationAction
+
+_Underlying type:_ _string_
+
+AuthorizationAction defines the action to be taken if a rule matches.
+
+_Appears in:_
+- [Authorization](#authorization)
+- [AuthorizationRule](#authorizationrule)
+
+| Value | Description |
+| ----- | ----------- |
+| `Allow` | AuthorizationActionAllow is the action to allow the request.<br /> | 
+| `Deny` | AuthorizationActionDeny is the action to deny the request.<br /> | 
+
+
+#### AuthorizationRule
+
+
+
+AuthorizationRule defines a single authorization rule.
+
+_Appears in:_
+- [Authorization](#authorization)
+
+| Field | Type | Required | Description |
+| ---   | ---  | ---      | ---         |
+| `name` | _string_ |  false  | Name is a user-friendly name for the rule. It's just for display purposes. |
+| `action` | _[AuthorizationAction](#authorizationaction)_ |  true  | Action defines the action to be taken if the rule matches. |
+| `principal` | _[Principal](#principal)_ |  true  | Principal specifies the client identity of a request. |
 
 
 #### BackOffPolicy
@@ -451,6 +486,18 @@ _Appears in:_
 | `Replace` | Replace replaces the default bootstrap with the provided one.<br /> | 
 
 
+#### CIDR
+
+_Underlying type:_ _string_
+
+CIDR defines a CIDR Address range.
+A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64".
+
+_Appears in:_
+- [Principal](#principal)
+
+
+
 #### CORS
 
 
@@ -857,6 +904,7 @@ _Appears in:_
 | `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter.<br /> | 
 | `envoy.filters.http.local_ratelimit` | EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter.<br /> | 
 | `envoy.filters.http.ratelimit` | EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.<br /> | 
+| `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter.<br /> | 
 | `envoy.filters.http.router` | EnvoyFilterRouter defines the Envoy HTTP router filter.<br /> | 
 
 
@@ -1308,7 +1356,7 @@ _Appears in:_
 | `extraArgs` | _string array_ |  false  | ExtraArgs defines additional command line options that are provided to Envoy.<br />More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options<br />Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. |
 | `mergeGateways` | _boolean_ |  false  | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure.<br />Setting this field to true would merge all Gateway Listeners under the parent Gateway Class.<br />This means that the port, protocol and hostname tuple must be unique for every listener.<br />If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. |
 | `shutdown` | _[ShutdownConfig](#shutdownconfig)_ |  false  | Shutdown defines configuration for graceful envoy shutdown process. |
-| `filterOrder` | _[FilterPosition](#filterposition) array_ |  false  | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.<br />The FilterPosition in the list will be applied in the order they are defined.<br />If unspecified, the default filter order is applied.<br />Default filter order is:<br /><br />- envoy.filters.http.fault<br /><br />- envoy.filters.http.cors<br /><br />- envoy.filters.http.ext_authz<br /><br />- envoy.filters.http.basic_authn<br /><br />- envoy.filters.http.oauth2<br /><br />- envoy.filters.http.jwt_authn<br /><br />- envoy.filters.http.ext_proc<br /><br />- envoy.filters.http.wasm<br /><br />- envoy.filters.http.local_ratelimit<br /><br />- envoy.filters.http.ratelimit<br /><br />- envoy.filters.http.router |
+| `filterOrder` | _[FilterPosition](#filterposition) array_ |  false  | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.<br />The FilterPosition in the list will be applied in the order they are defined.<br />If unspecified, the default filter order is applied.<br />Default filter order is:<br /><br />- envoy.filters.http.fault<br /><br />- envoy.filters.http.cors<br /><br />- envoy.filters.http.ext_authz<br /><br />- envoy.filters.http.basic_authn<br /><br />- envoy.filters.http.oauth2<br /><br />- envoy.filters.http.jwt_authn<br /><br />- envoy.filters.http.ext_proc<br /><br />- envoy.filters.http.wasm<br /><br />- envoy.filters.http.rbac<br /><br />- envoy.filters.http.local_ratelimit<br /><br />- envoy.filters.http.ratelimit<br /><br />- envoy.filters.http.router |
 | `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ |  false  | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends.<br />These settings are applied on backends for which TLS policies are specified. |
 
 
@@ -2450,13 +2498,16 @@ _Appears in:_
 
 
 Principal specifies the client identity of a request.
+A client identity can be a client IP, a JWT claim, username from the Authorization header,
+or any other identity that can be extracted from a custom header.
+Currently, only the client IP is supported.
 
 _Appears in:_
-- [Rule](#rule)
+- [AuthorizationRule](#authorizationrule)
 
 | Field | Type | Required | Description |
 | ---   | ---  | ---      | ---         |
-| `clientCIDR` | _string array_ |  true  | ClientCIDR is the IP CIDR range of the client.<br />Valid examples are "192.168.1.0/24" or "2001:db8::/64"<br /><br />By default, the client IP is inferred from the x-forwarder-for header and proxy protocol.<br />You can use the `EnableProxyProtocol` and `ClientIPDetection` options in<br />the `ClientTrafficPolicy` to configure how the client IP is detected. |
+| `clientCIDRs` | _[CIDR](#cidr) array_ |  true  | ClientCIDRs are the IP CIDR ranges of the client.<br />Valid examples are "192.168.1.0/24" or "2001:db8::/64"<br /><br />The client IP is inferred from the X-Forwarded-For header, a custom header,<br />or the proxy protocol.<br />You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in<br />the `ClientTrafficPolicy` to configure how the client IP is detected. |
 
 
 #### ProcessingModeOptions
@@ -3090,37 +3141,6 @@ _Appears in:_
 | `httpStatusCodes` | _[HTTPStatus](#httpstatus) array_ |  false  | HttpStatusCodes specifies the http status codes to be retried.<br />The retriable-status-codes trigger must also be configured for these status codes to trigger a retry. |
 
 
-#### Rule
-
-
-
-Rule defines the single authorization rule.
-
-_Appears in:_
-- [Authorization](#authorization)
-
-| Field | Type | Required | Description |
-| ---   | ---  | ---      | ---         |
-| `action` | _[RuleActionType](#ruleactiontype)_ |  true  | Action defines the action to be taken if the rule matches. |
-| `principal` | _[Principal](#principal)_ |  true  | Principal specifies the client identity of a request. |
-
-
-#### RuleActionType
-
-_Underlying type:_ _string_
-
-RuleActionType specifies the types of authorization rule action.
-
-_Appears in:_
-- [Authorization](#authorization)
-- [Rule](#rule)
-
-| Value | Description |
-| ----- | ----------- |
-| `Allow` | Allow is the action to allow the request.<br /> | 
-| `Deny` | Deny is the action to deny the request.<br /> | 
-
-
 #### SecurityPolicy
 
 
diff --git a/test/e2e/testdata/authorization-client-ip.yaml b/test/e2e/testdata/authorization-client-ip.yaml
new file mode 100644
index 000000000..08ead703c
--- /dev/null
+++ b/test/e2e/testdata/authorization-client-ip.yaml
@@ -0,0 +1,98 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: http-with-authorization-client-ip-1
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: same-namespace
+  rules:
+  - matches:
+    - path:
+        type: Exact
+        value: /protected1
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: http-with-authorization-client-ip-2
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: same-namespace
+  rules:
+  - matches:
+    - path:
+        type: Exact
+        value: /protected2
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: authorization-client-ip-1
+  namespace: gateway-conformance-infra
+spec:
+  targetRef:
+    group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: http-with-authorization-client-ip-1
+  authorization:
+    defaultAction: Allow
+    rules:
+    - name: "deny-location-1"  # First matching rule is applied, so 192.168.1.0/24 will be denied
+      action: Deny
+      principal:
+        clientCIDRs:
+        - 192.168.1.0/24
+    - name: "allow-location-1"
+      action: Allow
+      principal:
+        clientCIDRs:
+        - 192.168.1.0/24
+        - 192.168.2.0/24     # First matching rule is applied, so 12.168.2.0/24 will be allowed
+    - name: "deny-location-2"
+      action: Allow
+      principal:
+        clientCIDRs:
+        - 192.168.2.0/24
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: authorization-client-ip-2
+  namespace: gateway-conformance-infra
+spec:
+  targetRef:
+    group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: http-with-authorization-client-ip-2
+  authorization:
+    defaultAction: Deny
+    rules:
+    - action: Allow
+      principal:
+        clientCIDRs:
+        - 10.0.1.0/24
+        - 10.0.2.0/24
+---
+# This is a client traffic policy that enables client IP detection using the XFF header.
+# So, the client IP can be detected from the XFF header and used for authorization.
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: ClientTrafficPolicy
+metadata:
+  name: enable-client-ip-detection
+  namespace: gateway-conformance-infra
+spec:
+  clientIPDetection:
+    xForwardedFor:
+      numTrustedHops: 1
+  targetRef:
+    group: gateway.networking.k8s.io
+    kind: Gateway
+    name: same-namespace
diff --git a/test/e2e/testdata/authorization-default-action.yaml b/test/e2e/testdata/authorization-default-action.yaml
new file mode 100644
index 000000000..bc35b2ba8
--- /dev/null
+++ b/test/e2e/testdata/authorization-default-action.yaml
@@ -0,0 +1,58 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: http-with-authorization-empty
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: same-namespace
+  rules:
+  - matches:
+    - path:
+        type: Exact
+        value: /empty-authorization
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: http-with-authorization-allow-all
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: same-namespace
+  rules:
+  - matches:
+    - path:
+        type: Exact
+        value: /allow-all
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: authorization-empty
+  namespace: gateway-conformance-infra
+spec:
+  targetRef:
+    group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: http-with-authorization-empty
+  authorization: {}  # An empty authorization policy means deny all since default action is deny
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: authorization-allow-all
+  namespace: gateway-conformance-infra
+spec:
+  targetRef:
+    group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: http-with-authorization-allow-all
+  authorization:  # Allow all since default action is allow and no rules are defined
+    defaultAction: Allow
diff --git a/test/e2e/testdata/basic-auth.yaml b/test/e2e/testdata/basic-auth.yaml
index 036bb788e..db99cf2cd 100644
--- a/test/e2e/testdata/basic-auth.yaml
+++ b/test/e2e/testdata/basic-auth.yaml
@@ -74,7 +74,6 @@ spec:
     group: gateway.networking.k8s.io
     kind: HTTPRoute
     name: http-with-basic-auth-2
-    namespace: gateway-conformance-infra
   basicAuth:
     users:
       name: "basic-auth-users-secret-2"
diff --git a/test/e2e/tests/authorization-client-ip.go b/test/e2e/tests/authorization-client-ip.go
new file mode 100644
index 000000000..0a0d2056a
--- /dev/null
+++ b/test/e2e/tests/authorization-client-ip.go
@@ -0,0 +1,192 @@
+// 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.
+
+//go:build e2e
+// +build e2e
+
+package tests
+
+import (
+	"testing"
+
+	"k8s.io/apimachinery/pkg/types"
+	gwv1 "sigs.k8s.io/gateway-api/apis/v1"
+	gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+
+	"github.com/envoyproxy/gateway/internal/gatewayapi"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, AuthorizationClientIPTest)
+}
+
+var AuthorizationClientIPTest = suite.ConformanceTest{
+	ShortName:   "Authorization with client IP",
+	Description: "Authorization with client IP Allow/Deny list",
+	Manifests:   []string{"testdata/authorization-client-ip.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		route1NN := types.NamespacedName{Name: "http-with-authorization-client-ip-1", Namespace: ns}
+		route2NN := types.NamespacedName{Name: "http-with-authorization-client-ip-2", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+		gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), route1NN, route2NN)
+
+		ancestorRef := gwv1a2.ParentReference{
+			Group:     gatewayapi.GroupPtr(gwv1.GroupName),
+			Kind:      gatewayapi.KindPtr(gatewayapi.KindGateway),
+			Namespace: gatewayapi.NamespacePtr(gwNN.Namespace),
+			Name:      gwv1.ObjectName(gwNN.Name),
+		}
+		SecurityPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "authorization-client-ip-1", Namespace: ns}, suite.ControllerName, ancestorRef)
+		SecurityPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "authorization-client-ip-2", Namespace: ns}, suite.ControllerName, ancestorRef)
+
+		t.Run("first route-denied IP", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected1",
+					Headers: map[string]string{
+						"X-Forwarded-For": "192.168.1.1", // in the denied list
+					},
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+			cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+			if err != nil {
+				t.Errorf("failed to get expected response: %v", err)
+			}
+
+			if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+				t.Errorf("failed to compare request and response: %v", err)
+			}
+		})
+
+		t.Run("first route-allowed IP", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected1",
+					Headers: map[string]string{
+						"X-Forwarded-For": "192.168.2.1", // in the allowed list
+					},
+				},
+				ExpectedRequest: &http.ExpectedRequest{
+					Request: http.Request{
+						Path:    "/protected1",
+						Headers: nil, // don't check headers since Envoy will append the client IP to the X-Forwarded-For header
+					},
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+			cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+			if err != nil {
+				t.Errorf("failed to get expected response: %v", err)
+			}
+
+			if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+				t.Errorf("failed to compare request and response: %v", err)
+			}
+		})
+
+		t.Run("first route-default action: allow", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected1",
+					Headers: map[string]string{
+						"X-Forwarded-For": "192.168.3.1", // not in the denied list
+					},
+				},
+				ExpectedRequest: &http.ExpectedRequest{
+					Request: http.Request{
+						Path:    "/protected1",
+						Headers: nil, // don't check headers since Envoy will append the client IP to the X-Forwarded-For header
+					},
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+			cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+			if err != nil {
+				t.Errorf("failed to get expected response: %v", err)
+			}
+
+			if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+				t.Errorf("failed to compare request and response: %v", err)
+			}
+		})
+
+		// Test the second route
+		t.Run("second route-allowed IP", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected2",
+					Headers: map[string]string{
+						"X-Forwarded-For": "10.0.1.1", // in the allowed list
+					},
+				},
+				ExpectedRequest: &http.ExpectedRequest{
+					Request: http.Request{
+						Path:    "/protected2",
+						Headers: nil, // don't check headers since Envoy will append the client IP to the X-Forwarded-For header
+					},
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+			cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+			if err != nil {
+				t.Errorf("failed to get expected response: %v", err)
+			}
+
+			if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+				t.Errorf("failed to compare request and response: %v", err)
+			}
+		})
+
+		t.Run("second route-default action: deny", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected2",
+					Headers: map[string]string{
+						"X-Forwarded-For": "192.168.3.1", // not in the allowed list
+					},
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+			cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+			if err != nil {
+				t.Errorf("failed to get expected response: %v", err)
+			}
+
+			if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+				t.Errorf("failed to compare request and response: %v", err)
+			}
+		})
+	},
+}
diff --git a/test/e2e/tests/authorization-default-action.go b/test/e2e/tests/authorization-default-action.go
new file mode 100644
index 000000000..1a58c32e3
--- /dev/null
+++ b/test/e2e/tests/authorization-default-action.go
@@ -0,0 +1,92 @@
+// 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.
+
+//go:build e2e
+// +build e2e
+
+package tests
+
+import (
+	"testing"
+
+	"k8s.io/apimachinery/pkg/types"
+	gwv1 "sigs.k8s.io/gateway-api/apis/v1"
+	gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+
+	"github.com/envoyproxy/gateway/internal/gatewayapi"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, AuthorizationDefaultActionTest)
+}
+
+var AuthorizationDefaultActionTest = suite.ConformanceTest{
+	ShortName:   "Authorization with default actions",
+	Description: "Authorization with default actions",
+	Manifests:   []string{"testdata/authorization-default-action.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		route1NN := types.NamespacedName{Name: "http-with-authorization-empty", Namespace: ns}
+		route2NN := types.NamespacedName{Name: "http-with-authorization-allow-all", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+		gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), route1NN, route2NN)
+
+		ancestorRef := gwv1a2.ParentReference{
+			Group:     gatewayapi.GroupPtr(gwv1.GroupName),
+			Kind:      gatewayapi.KindPtr(gatewayapi.KindGateway),
+			Namespace: gatewayapi.NamespacePtr(gwNN.Namespace),
+			Name:      gwv1.ObjectName(gwNN.Name),
+		}
+		SecurityPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "authorization-empty", Namespace: ns}, suite.ControllerName, ancestorRef)
+		SecurityPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "authorization-allow-all", Namespace: ns}, suite.ControllerName, ancestorRef)
+
+		t.Run("Empty Authorization should deny all traffic", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/empty-authorization",
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+			cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+			if err != nil {
+				t.Errorf("failed to get expected response: %v", err)
+			}
+
+			if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+				t.Errorf("failed to compare request and response: %v", err)
+			}
+		})
+
+		t.Run("Authorization with empty rules and Allow default action should allow all traffic", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/allow-all",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http")
+			cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req)
+			if err != nil {
+				t.Errorf("failed to get expected response: %v", err)
+			}
+
+			if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil {
+				t.Errorf("failed to compare request and response: %v", err)
+			}
+		})
+	},
+}