Repository: envoyproxy/gateway
Pull request #3497 (2024-05-29 03:02:47)

fix api nit
xref: https://github.com/envoyproxy/gateway/pull/3469#discussion_r1618090041

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/3497?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.34%. Comparing base [(`78fe57a`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/78fe57ab58deb32b985a7ca6d8390194c4a5ef3b?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`270e9d9`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/270e9d92e84410cedf799a8cff744dc9ad7cd9e2?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    #3497      +/-   ##
==========================================
- Coverage   67.36%   67.34%   -0.02%     
==========================================
  Files         167      167              
  Lines       19925    19925              
==========================================
- Hits        13422    13419       -3     
- Misses       5538     5540       +2     
- Partials      965      966       +1     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/3497?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).


Patch:
diff --git a/api/v1alpha1/accesslogging_types.go b/api/v1alpha1/accesslogging_types.go
index 8aafbe9ac..4d075bfed 100644
--- a/api/v1alpha1/accesslogging_types.go
+++ b/api/v1alpha1/accesslogging_types.go
@@ -171,7 +171,7 @@ type OpenTelemetryEnvoyProxyAccessLog struct {
 	Port int32 `json:"port,omitempty"`
 	// BackendRefs references a Kubernetes object that represents the
 	// backend server to which the access log will be sent.
-	// Only service Kind is supported for now.
+	// Only Service kind is supported for now.
 	//
 	// +optional
 	// +kubebuilder:validation:MaxItems=1
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_metric_types.go b/api/v1alpha1/envoyproxy_metric_types.go
index 10ba5ad91..bf321febc 100644
--- a/api/v1alpha1/envoyproxy_metric_types.go
+++ b/api/v1alpha1/envoyproxy_metric_types.go
@@ -70,7 +70,7 @@ type ProxyOpenTelemetrySink struct {
 	Port int32 `json:"port,omitempty"`
 	// BackendRefs references a Kubernetes object that represents the
 	// backend server to which the metric will be sent.
-	// Only service Kind is supported for now.
+	// Only Service kind is supported for now.
 	//
 	// +optional
 	// +kubebuilder:validation:MaxItems=1
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/ext_auth_types.go b/api/v1alpha1/ext_auth_types.go
index 906f13c40..a1cd40bb1 100644
--- a/api/v1alpha1/ext_auth_types.go
+++ b/api/v1alpha1/ext_auth_types.go
@@ -59,13 +59,14 @@ type ExtAuth struct {
 type GRPCExtAuthService struct {
 	// BackendRef references a Kubernetes object that represents the
 	// backend server to which the authorization request will be sent.
-	// Only service Kind is supported for now.
+	// Only Service kind is supported for now.
+	//
 	// Deprecated: Use BackendRefs instead.
 	BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
 
 	// BackendRefs references a Kubernetes object that represents the
 	// backend server to which the authorization request will be sent.
-	// Only service Kind is supported for now.
+	// Only Service kind is supported for now.
 	//
 	// +optional
 	// +kubebuilder:validation:MaxItems=1
@@ -79,13 +80,14 @@ type GRPCExtAuthService struct {
 type HTTPExtAuthService struct {
 	// BackendRef references a Kubernetes object that represents the
 	// backend server to which the authorization request will be sent.
-	// Only service Kind is supported for now.
+	// Only Service kind is supported for now.
+	//
 	// Deprecated: Use BackendRefs instead.
 	BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
 
 	// BackendRefs references a Kubernetes object that represents the
 	// backend server to which the authorization request will be sent.
-	// Only service Kind is supported for now.
+	// Only Service kind is supported for now.
 	//
 	// +optional
 	// +kubebuilder:validation:MaxItems=1
diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go
index ecce79576..b1de7097f 100644
--- a/api/v1alpha1/oidc_types.go
+++ b/api/v1alpha1/oidc_types.go
@@ -30,6 +30,12 @@ type OIDC struct {
 	// +kubebuilder:validation:Required
 	ClientSecret gwapiv1b1.SecretObjectReference `json:"clientSecret"`
 
+	// The optional cookie name overrides to be used for Bearer and IdToken cookies in the
+	// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
+	// If not specified, uses a randomly generated suffix
+	// +optional
+	CookieNames *OIDCCookieNames `json:"cookieNames,omitempty"`
+
 	// The OIDC scopes to be used in the
 	// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
 	// The "openid" scope is always added to the list of scopes if not already
@@ -75,3 +81,17 @@ type OIDCProvider struct {
 	// +optional
 	TokenEndpoint *string `json:"tokenEndpoint,omitempty"`
 }
+
+// OIDCCookieNames defines the names of cookies to use in the Envoy OIDC filter.
+type OIDCCookieNames struct {
+	// The name of the cookie used to store the AccessToken in the
+	// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
+	// If not specified, defaults to "AccessToken-(randomly generated uid)"
+	// +optional
+	AccessToken *string `json:"accessToken,omitempty"`
+	// The name of the cookie used to store the IdToken in the
+	// [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
+	// If not specified, defaults to "IdToken-(randomly generated uid)"
+	// +optional
+	IDToken *string `json:"idToken,omitempty"`
+}
diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go
index e07c8ec15..4511bd3e8 100644
--- a/api/v1alpha1/shared_types.go
+++ b/api/v1alpha1/shared_types.go
@@ -443,6 +443,11 @@ type KubernetesPatchSpec struct {
 // BackendRef defines how an ObjectReference that is specific to BackendRef.
 type BackendRef struct {
 	// BackendObjectReference references a Kubernetes object that represents the backend.
-	// Only service Kind is supported for now.
+	// 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/tracing_types.go b/api/v1alpha1/tracing_types.go
index ffa33a8c0..a2a3f7b56 100644
--- a/api/v1alpha1/tracing_types.go
+++ b/api/v1alpha1/tracing_types.go
@@ -51,7 +51,7 @@ type TracingProvider struct {
 	Port int32 `json:"port,omitempty"`
 	// BackendRefs references a Kubernetes object that represents the
 	// backend server to which the trace will be sent.
-	// Only service Kind is supported for now.
+	// Only Service kind is supported for now.
 	//
 	// +optional
 	// +kubebuilder:validation:MaxItems=1
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 67918dabd..45afe9ffa 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
@@ -3208,6 +3229,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) {
 	*out = *in
 	in.Provider.DeepCopyInto(&out.Provider)
 	in.ClientSecret.DeepCopyInto(&out.ClientSecret)
+	if in.CookieNames != nil {
+		in, out := &in.CookieNames, &out.CookieNames
+		*out = new(OIDCCookieNames)
+		(*in).DeepCopyInto(*out)
+	}
 	if in.Scopes != nil {
 		in, out := &in.Scopes, &out.Scopes
 		*out = make([]string, len(*in))
@@ -3240,6 +3266,31 @@ func (in *OIDC) DeepCopy() *OIDC {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OIDCCookieNames) DeepCopyInto(out *OIDCCookieNames) {
+	*out = *in
+	if in.AccessToken != nil {
+		in, out := &in.AccessToken, &out.AccessToken
+		*out = new(string)
+		**out = **in
+	}
+	if in.IDToken != nil {
+		in, out := &in.IDToken, &out.IDToken
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCCookieNames.
+func (in *OIDCCookieNames) DeepCopy() *OIDCCookieNames {
+	if in == nil {
+		return nil
+	}
+	out := new(OIDCCookieNames)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *OIDCProvider) DeepCopyInto(out *OIDCProvider) {
 	*out = *in
@@ -3402,9 +3453,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 +4179,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..c8d074519 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
@@ -10400,7 +10406,7 @@ spec:
                                         description: |-
                                           BackendRefs references a Kubernetes object that represents the
                                           backend server to which the access log will be sent.
-                                          Only service Kind is supported for now.
+                                          Only Service kind is supported for now.
                                         items:
                                           description: BackendRef defines how an ObjectReference
                                             that is specific to BackendRef.
@@ -10627,7 +10633,7 @@ spec:
                                   description: |-
                                     BackendRefs references a Kubernetes object that represents the
                                     backend server to which the metric will be sent.
-                                    Only service Kind is supported for now.
+                                    Only Service kind is supported for now.
                                   items:
                                     description: BackendRef defines how an ObjectReference
                                       that is specific to BackendRef.
@@ -10823,7 +10829,7 @@ spec:
                             description: |-
                               BackendRefs references a Kubernetes object that represents the
                               backend server to which the trace will be sent.
-                              Only service Kind is supported for now.
+                              Only Service kind is supported for now.
                             items:
                               description: BackendRef defines how an ObjectReference
                                 that is specific to BackendRef.
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..30e1b5ffb 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
@@ -246,7 +259,9 @@ spec:
                         description: |-
                           BackendRef references a Kubernetes object that represents the
                           backend server to which the authorization request will be sent.
-                          Only service Kind is supported for now.
+                          Only Service kind is supported for now.
+
+
                           Deprecated: Use BackendRefs instead.
                         properties:
                           group:
@@ -326,7 +341,7 @@ spec:
                         description: |-
                           BackendRefs references a Kubernetes object that represents the
                           backend server to which the authorization request will be sent.
-                          Only service Kind is supported for now.
+                          Only Service kind is supported for now.
                         items:
                           description: BackendRef defines how an ObjectReference that
                             is specific to BackendRef.
@@ -438,7 +453,9 @@ spec:
                         description: |-
                           BackendRef references a Kubernetes object that represents the
                           backend server to which the authorization request will be sent.
-                          Only service Kind is supported for now.
+                          Only Service kind is supported for now.
+
+
                           Deprecated: Use BackendRefs instead.
                         properties:
                           group:
@@ -518,7 +535,7 @@ spec:
                         description: |-
                           BackendRefs references a Kubernetes object that represents the
                           backend server to which the authorization request will be sent.
-                          Only service Kind is supported for now.
+                          Only Service kind is supported for now.
                         items:
                           description: BackendRef defines how an ObjectReference that
                             is specific to BackendRef.
@@ -849,6 +866,25 @@ spec:
                     required:
                     - name
                     type: object
+                  cookieNames:
+                    description: |-
+                      The optional cookie name overrides to be used for Bearer and IdToken cookies in the
+                      [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
+                      If not specified, uses a randomly generated suffix
+                    properties:
+                      accessToken:
+                        description: |-
+                          The name of the cookie used to store the AccessToken in the
+                          [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
+                          If not specified, defaults to "AccessToken-(randomly generated uid)"
+                        type: string
+                      idToken:
+                        description: |-
+                          The name of the cookie used to store the IdToken in the
+                          [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
+                          If not specified, defaults to "IdToken-(randomly generated uid)"
+                        type: string
+                    type: object
                   logoutPath:
                     description: |-
                       The path to log a user out, clearing their credential cookies.
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..cbb9aa0d8 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,
 			}
 		}
 	}
@@ -589,7 +604,9 @@ func (t *Translator) buildOIDC(
 		logoutPath = *oidc.LogoutPath
 	}
 
-	// Generate a unique cookie suffix for oauth filters
+	// Generate a unique cookie suffix for oauth filters.
+	// This is to avoid cookie name collision when multiple security policies are applied
+	// to the same route.
 	suffix := utils.Digest32(string(policy.UID))
 
 	// Get the HMAC secret.
@@ -607,17 +624,18 @@ func (t *Translator) buildOIDC(
 	}
 
 	return &ir.OIDC{
-		Name:         irConfigName(policy),
-		Provider:     *provider,
-		ClientID:     oidc.ClientID,
-		ClientSecret: clientSecretBytes,
-		Scopes:       scopes,
-		Resources:    oidc.Resources,
-		RedirectURL:  redirectURL,
-		RedirectPath: redirectPath,
-		LogoutPath:   logoutPath,
-		CookieSuffix: suffix,
-		HMACSecret:   hmacData,
+		Name:                irConfigName(policy),
+		Provider:            *provider,
+		ClientID:            oidc.ClientID,
+		ClientSecret:        clientSecretBytes,
+		Scopes:              scopes,
+		Resources:           oidc.Resources,
+		RedirectURL:         redirectURL,
+		RedirectPath:        redirectPath,
+		LogoutPath:          logoutPath,
+		CookieSuffix:        suffix,
+		CookieNameOverrides: policy.Spec.OIDC.CookieNames,
+		HMACSecret:          hmacData,
 	}, nil
 }
 
@@ -858,3 +876,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..078f70b72 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 {
@@ -686,9 +690,12 @@ type OIDC struct {
 
 	// CookieSuffix will be added to the name of the cookies set by the oauth filter.
 	// Adding a suffix avoids multiple oauth filters from overwriting each other's cookies.
-	// These cookies are set by the oauth filter, including: BearerToken,
+	// These cookies are set by the oauth filter, including: AccessToken,
 	// OauthHMAC, OauthExpires, IdToken, and RefreshToken.
 	CookieSuffix string `json:"cookieSuffix,omitempty"`
+
+	// CookieNameOverrides can optionally override the generated name of the cookies set by the oauth filter.
+	CookieNameOverrides *egv1a1.OIDCCookieNames `json:"cookieNameOverrides,omitempty"`
 }
 
 type OIDCProvider struct {
@@ -784,6 +791,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 +1313,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 +1428,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 +1513,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 +2070,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..27d5679b6 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
@@ -1492,6 +1554,11 @@ func (in *OIDC) DeepCopyInto(out *OIDC) {
 		*out = make([]string, len(*in))
 		copy(*out, *in)
 	}
+	if in.CookieNameOverrides != nil {
+		in, out := &in.CookieNameOverrides, &out.CookieNameOverrides
+		*out = new(v1alpha1.OIDCCookieNames)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDC.
@@ -1629,6 +1696,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 +2064,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 +2300,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 +2628,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 +2683,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/oidc.go b/internal/xds/translator/oidc.go
index 183fb7944..ae54603f5 100644
--- a/internal/xds/translator/oidc.go
+++ b/internal/xds/translator/oidc.go
@@ -159,7 +159,7 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) {
 					},
 				},
 				CookieNames: &oauth2v3.OAuth2Credentials_CookieNames{
-					BearerToken:  fmt.Sprintf("BearerToken-%s", oidc.CookieSuffix),
+					BearerToken:  fmt.Sprintf("AccessToken-%s", oidc.CookieSuffix),
 					OauthHmac:    fmt.Sprintf("OauthHMAC-%s", oidc.CookieSuffix),
 					OauthExpires: fmt.Sprintf("OauthExpires-%s", oidc.CookieSuffix),
 					IdToken:      fmt.Sprintf("IdToken-%s", oidc.CookieSuffix),
@@ -172,6 +172,17 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) {
 			Resources:  oidc.Resources,
 		},
 	}
+
+	if oidc.CookieNameOverrides != nil &&
+		oidc.CookieNameOverrides.AccessToken != nil {
+		oauth2.Config.Credentials.CookieNames.BearerToken = *oidc.CookieNameOverrides.AccessToken
+	}
+
+	if oidc.CookieNameOverrides != nil &&
+		oidc.CookieNameOverrides.IDToken != nil {
+		oauth2.Config.Credentials.CookieNames.IdToken = *oidc.CookieNameOverrides.IDToken
+	}
+
 	return oauth2, nil
 }
 
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/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.in.yaml
new file mode 100644
index 000000000..13ce562de
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.in.yaml
@@ -0,0 +1,73 @@
+secrets:
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    namespace: envoy-gateway
+    name: client1-secret
+  data:
+    client-secret: Y2xpZW50MTpzZWNyZXQK
+- apiVersion: v1
+  kind: Secret
+  metadata:
+    namespace: envoy-gateway-system
+    name: envoy-oidc-hmac
+  data:
+    hmac-secret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+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
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    namespace: envoy-gateway
+    name: policy-for-gateway  # This policy should attach httproute-2
+    uid: b8284d0f-de82-4c65-b204-96a0d3f258a1
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+    oidc:
+      provider:
+        issuer: "https://accounts.google.com"
+      clientID: "client1.apps.googleusercontent.com"
+      clientSecret:
+        name: "client1-secret"
+      redirectURL: "https://www.example.com/bar/oauth2/callback"
+      logoutPath: "/bar/logout"
+      cookieNames:
+        idToken: "CustomIdTokenCookie"
+        accessToken: "CustomAccessTokenCookie"
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.out.yaml
new file mode 100755
index 000000000..07ceea24f
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-custom-cookies.out.yaml
@@ -0,0 +1,186 @@
+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
+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
+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-gateway
+    namespace: envoy-gateway
+    uid: b8284d0f-de82-4c65-b204-96a0d3f258a1
+  spec:
+    oidc:
+      clientID: client1.apps.googleusercontent.com
+      clientSecret:
+        group: null
+        kind: null
+        name: client1-secret
+      cookieNames:
+        accessToken: CustomAccessTokenCookie
+        idToken: CustomIdTokenCookie
+      logoutPath: /bar/logout
+      provider:
+        issuer: https://accounts.google.com
+      redirectURL: https://www.example.com/bar/oauth2/callback
+    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
+      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-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:
+          oidc:
+            clientID: client1.apps.googleusercontent.com
+            clientSecret: Y2xpZW50MTpzZWNyZXQK
+            cookieNameOverrides:
+              accessToken: CustomAccessTokenCookie
+              idToken: CustomIdTokenCookie
+            cookieSuffix: b0a1b740
+            hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY=
+            logoutPath: /bar/logout
+            name: securitypolicy/envoy-gateway/policy-for-gateway
+            provider:
+              authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth
+              tokenEndpoint: https://oauth2.googleapis.com/token
+            redirectPath: /bar/oauth2/callback
+            redirectURL: https://www.example.com/bar/oauth2/callback
+            scopes:
+            - openid
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/in/xds-ir/oidc.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml
index b2e395f83..68e36bffa 100644
--- a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml
@@ -66,3 +66,6 @@ http:
         redirectPath: "/bar/oauth2/callback"
         logoutPath: "/bar/logout"
         cookieSuffix: 5f93c2e4
+        cookieNameOverrides:
+          idToken: "CustomIdTokenOverride"
+          accessToken: "CustomAccessTokenOverride"
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/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
index 1365c290c..a06b72653 100755
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
@@ -117,7 +117,7 @@
               credentials:
                 clientId: client.oauth.foo.com
                 cookieNames:
-                  bearerToken: BearerToken-5F93C2E4
+                  bearerToken: AccessToken-5F93C2E4
                   idToken: IdToken-5F93C2E4
                   oauthExpires: OauthExpires-5F93C2E4
                   oauthHmac: OauthHMAC-5F93C2E4
diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml
index 95e075f04..ab8556ba1 100644
--- a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml
@@ -28,7 +28,7 @@
               credentials:
                 clientId: client.oauth.foo.com
                 cookieNames:
-                  bearerToken: BearerToken-5F93C2E4
+                  bearerToken: AccessToken-5F93C2E4
                   idToken: IdToken-5F93C2E4
                   oauthExpires: OauthExpires-5F93C2E4
                   oauthHmac: OauthHMAC-5F93C2E4
@@ -71,8 +71,8 @@
               credentials:
                 clientId: client.oauth.bar.com
                 cookieNames:
-                  bearerToken: BearerToken-5f93c2e4
-                  idToken: IdToken-5f93c2e4
+                  bearerToken: CustomAccessTokenOverride
+                  idToken: CustomIdTokenOverride
                   oauthExpires: OauthExpires-5f93c2e4
                   oauthHmac: OauthHMAC-5f93c2e4
                   refreshToken: RefreshToken-5f93c2e4
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index d28b28339..2652b19b7 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. |
 
 
@@ -1591,8 +1639,8 @@ _Appears in:_
 
 | Field | Type | Required | Description |
 | ---   | ---  | ---      | ---         |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ |  true  | BackendRef references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only service Kind is supported for now.<br />Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only service Kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ |  true  | BackendRef references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only Service kind is supported for now.<br /><br />Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only Service kind is supported for now. |
 
 
 #### Gateway
@@ -1754,8 +1802,8 @@ _Appears in:_
 
 | Field | Type | Required | Description |
 | ---   | ---  | ---      | ---         |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ |  true  | BackendRef references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only service Kind is supported for now.<br />Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only service Kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ |  true  | BackendRef references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only Service kind is supported for now.<br /><br />Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the authorization request will be sent.<br />Only Service kind is supported for now. |
 | `path` | _string_ |  true  | Path is the path of the HTTP External Authorization service.<br />If path is specified, the authorization request will be sent to that path,<br />or else the authorization request will be sent to the root path. |
 | `headersToBackend` | _string array_ |  false  | HeadersToBackend are the authorization response headers that will be added<br />to the original client request before sending it to the backend server.<br />Note that coexisting headers will be overridden.<br />If not specified, no authorization response headers will be added to the<br />original client request. |
 
@@ -2313,12 +2361,28 @@ _Appears in:_
 | `provider` | _[OIDCProvider](#oidcprovider)_ |  true  | The OIDC Provider configuration. |
 | `clientID` | _string_ |  true  | The client ID to be used in the OIDC<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
 | `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ |  true  | The Kubernetes secret which contains the OIDC client secret to be used in the<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).<br /><br />This is an Opaque secret. The client secret should be stored in the key<br />"client-secret". |
+| `cookieNames` | _[OIDCCookieNames](#oidccookienames)_ |  false  | The optional cookie name overrides to be used for Bearer and IdToken cookies in the<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).<br />If not specified, uses a randomly generated suffix |
 | `scopes` | _string array_ |  false  | The OIDC scopes to be used in the<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).<br />The "openid" scope is always added to the list of scopes if not already<br />specified. |
 | `resources` | _string array_ |  false  | The OIDC resources to be used in the<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). |
 | `redirectURL` | _string_ |  true  | The redirect URL to be used in the OIDC<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).<br />If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" |
 | `logoutPath` | _string_ |  true  | The path to log a user out, clearing their credential cookies.<br />If not specified, uses a default logout path "/logout" |
 
 
+#### OIDCCookieNames
+
+
+
+OIDCCookieNames defines the names of cookies to use in the Envoy OIDC filter.
+
+_Appears in:_
+- [OIDC](#oidc)
+
+| Field | Type | Required | Description |
+| ---   | ---  | ---      | ---         |
+| `accessToken` | _string_ |  false  | The name of the cookie used to store the AccessToken in the<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).<br />If not specified, defaults to "AccessToken-(randomly generated uid)" |
+| `idToken` | _string_ |  false  | The name of the cookie used to store the IdToken in the<br />[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).<br />If not specified, defaults to "IdToken-(randomly generated uid)" |
+
+
 #### OIDCProvider
 
 
@@ -2348,7 +2412,7 @@ _Appears in:_
 | ---   | ---  | ---      | ---         |
 | `host` | _string_ |  false  | Host define the extension service hostname.<br />Deprecated: Use BackendRefs instead. |
 | `port` | _integer_ |  false  | Port defines the port the extension service is exposed on.<br />Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the access log will be sent.<br />Only service Kind is supported for now. |
+| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the access log will be sent.<br />Only Service kind is supported for now. |
 | `resources` | _object (keys:string, values:string)_ |  false  | Resources is a set of labels that describe the source of a log entry, including envoy node info.<br />It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). |
 
 
@@ -2450,13 +2514,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
@@ -2683,7 +2750,7 @@ _Appears in:_
 | ---   | ---  | ---      | ---         |
 | `host` | _string_ |  false  | Host define the service hostname.<br />Deprecated: Use BackendRefs instead. |
 | `port` | _integer_ |  false  | Port defines the port the service is exposed on.<br />Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the metric will be sent.<br />Only service Kind is supported for now. |
+| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the metric will be sent.<br />Only Service kind is supported for now. |
 
 
 #### ProxyPrometheusProvider
@@ -3090,37 +3157,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
 
 
@@ -3432,7 +3468,7 @@ _Appears in:_
 | `type` | _[TracingProviderType](#tracingprovidertype)_ |  true  | Type defines the tracing provider type.<br />EG currently only supports OpenTelemetry. |
 | `host` | _string_ |  false  | Host define the provider service hostname.<br />Deprecated: Use BackendRefs instead. |
 | `port` | _integer_ |  false  | Port defines the port the provider service is exposed on.<br />Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the trace will be sent.<br />Only service Kind is supported for now. |
+| `backendRefs` | _[BackendRef](#backendref) array_ |  false  | BackendRefs references a Kubernetes object that represents the<br />backend server to which the trace will be sent.<br />Only Service kind is supported for now. |
 
 
 #### TracingProviderType
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)
+			}
+		})
+	},
+}