{
  "properties": {
    "apiVersion": {
      "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
      "type": "string"
    },
    "kind": {
      "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
      "type": "string"
    },
    "metadata": {
      "type": "object"
    },
    "spec": {
      "description": "GatewayExtensionSpec defines the desired state of GatewayExtension.",
      "properties": {
        "extAuth": {
          "description": "ExtAuth configuration for ExtAuth extension type.",
          "properties": {
            "clearRouteCache": {
              "default": false,
              "description": "ClearRouteCache determines if the route cache should be cleared to allow the\nexternal authentication service to correctly affect routing decisions.",
              "type": "boolean"
            },
            "failOpen": {
              "default": false,
              "description": "FailOpen determines if requests are allowed when the ext auth service is unavailable.\nDefaults to false, meaning requests will be denied if the ext auth service is unavailable.",
              "type": "boolean"
            },
            "grpcService": {
              "description": "GrpcService is the GRPC service that will handle the auth.\nMutually exclusive with HttpService.",
              "properties": {
                "authority": {
                  "description": "Authority is the authority header to use for the GRPC service.",
                  "type": "string"
                },
                "backendRef": {
                  "description": "BackendRef references the backend GRPC service.",
                  "properties": {
                    "group": {
                      "default": "",
                      "description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
                      "maxLength": 253,
                      "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                      "type": "string"
                    },
                    "kind": {
                      "default": "Service",
                      "description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                      "type": "string"
                    },
                    "name": {
                      "description": "Name is the name of the referent.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "namespace": {
                      "description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                      "type": "string"
                    },
                    "port": {
                      "description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
                      "format": "int32",
                      "maximum": 65535,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "weight": {
                      "default": 1,
                      "description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
                      "format": "int32",
                      "maximum": 1000000,
                      "minimum": 0,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object",
                  "x-kubernetes-validations": [
                    {
                      "message": "Must have port for Service reference",
                      "rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
                    }
                  ],
                  "additionalProperties": false
                },
                "requestTimeout": {
                  "description": "RequestTimeout is the timeout for the gRPC request. This is the timeout for a specific request.",
                  "type": "string",
                  "x-kubernetes-validations": [
                    {
                      "message": "invalid timeout value",
                      "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                    },
                    {
                      "message": "timeout must be at least 1ms.",
                      "rule": "duration(self) >= duration('1ms')"
                    }
                  ]
                },
                "retry": {
                  "description": "Retry specifies the retry policy for gRPC streams associated with the service.",
                  "properties": {
                    "attempts": {
                      "default": 1,
                      "description": "Attempts specifies the number of retry attempts for a request.\nDefaults to 1 attempt if not set.\nA value of 0 effectively disables retries.",
                      "format": "int32",
                      "minimum": 0,
                      "type": "integer"
                    },
                    "backoff": {
                      "description": "Backoff specifies the retry backoff strategy.\nIf not set, a default backoff with a base interval of 1000ms is used. The default max interval is 10 times the base interval.",
                      "properties": {
                        "baseInterval": {
                          "description": "BaseInterval specifies the base interval used with a fully jittered exponential back-off between retries.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            },
                            {
                              "message": "retry.BaseInterval must be at least 1ms.",
                              "rule": "duration(self) >= duration('1ms')"
                            }
                          ]
                        },
                        "maxInterval": {
                          "description": "MaxInterval specifies the maximum interval between retry attempts.\nDefaults to 10 times the BaseInterval if not set.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            }
                          ]
                        }
                      },
                      "required": [
                        "baseInterval"
                      ],
                      "type": "object",
                      "x-kubernetes-validations": [
                        {
                          "message": "maxInterval must be greater than or equal to baseInterval",
                          "rule": "has(self.maxInterval) ? duration(self.maxInterval) >= duration(self.baseInterval) : true"
                        }
                      ],
                      "additionalProperties": false
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                }
              },
              "required": [
                "backendRef"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "headersToForward": {
              "description": "HeadersToForward specifies which headers from the client request should be\nforwarded to the external authorization service.\n\nHTTP services by default have the following headers forwarded: Host, Method, Path, Content-Length, Authorization.\n\nIf this field is omitted, gRPC services will have all client request headers forwarded,\nwhile HTTP services will only receive the default headers described above.\n\nCommon examples: [\"cookie\", \"authorization\", \"x-forwarded-for\"]\nMore info is available on the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_authz/v3/ext_authz.proto#envoy-v3-api-field-extensions-filters-http-ext-authz-v3-extauthz-allowed-headers)",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "httpService": {
              "description": "HttpService is the HTTP service that will handle the auth.\nMutually exclusive with GrpcService.",
              "properties": {
                "authorizationRequest": {
                  "description": "AuthorizationRequest configures the authorization request to the external service.",
                  "properties": {
                    "headersToAdd": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "HeadersToAdd specifies additional headers to add to the authorization request.\nThese headers are sent to the authorization service in addition to the original request headers.\nClient request headers with the same key will be overridden.\nThe keys are header names and values are envoy format specifiers, see https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_authz/v3/ext_authz.proto#envoy-v3-api-field-extensions-filters-http-ext-authz-v3-authorizationrequest-headers-to-add.",
                      "type": "object"
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                },
                "authorizationResponse": {
                  "description": "AuthorizationResponse configures the authorization response from the external service.",
                  "properties": {
                    "headersToBackend": {
                      "description": "HeadersToBackend specifies which headers from the authorization response\nshould be forwarded to the upstream service when the request is authorized.\nCommon examples: [\"x-current-user\", \"x-user-id\", \"x-auth-request-email\"]",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                },
                "backendRef": {
                  "description": "BackendRef references the backend HTTP service.",
                  "properties": {
                    "group": {
                      "default": "",
                      "description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
                      "maxLength": 253,
                      "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                      "type": "string"
                    },
                    "kind": {
                      "default": "Service",
                      "description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                      "type": "string"
                    },
                    "name": {
                      "description": "Name is the name of the referent.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "namespace": {
                      "description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                      "type": "string"
                    },
                    "port": {
                      "description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
                      "format": "int32",
                      "maximum": 65535,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "weight": {
                      "default": 1,
                      "description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
                      "format": "int32",
                      "maximum": 1000000,
                      "minimum": 0,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object",
                  "x-kubernetes-validations": [
                    {
                      "message": "Must have port for Service reference",
                      "rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
                    }
                  ],
                  "additionalProperties": false
                },
                "pathPrefix": {
                  "description": "PathPrefix specifies a prefix to the value of the authorization request's path header.\nThis allows customizing the path at which the authorization server expects to receive requests.\nFor example, if the authorization server expects requests at \"/verify\", set this to \"/verify\".\nIf not specified, the original request path is used.",
                  "type": "string"
                },
                "requestTimeout": {
                  "description": "RequestTimeout is the timeout for the HTTP request. Default timeout is 2 seconds.",
                  "type": "string",
                  "x-kubernetes-validations": [
                    {
                      "message": "invalid timeout value",
                      "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                    },
                    {
                      "message": "timeout must be at least 1ms.",
                      "rule": "duration(self) >= duration('1ms')"
                    }
                  ]
                },
                "retry": {
                  "description": "Retry specifies the retry policy for HTTP requests to the authorization service.",
                  "properties": {
                    "attempts": {
                      "default": 1,
                      "description": "Attempts specifies the number of retry attempts for a request.\nDefaults to 1 attempt if not set.\nA value of 0 effectively disables retries.",
                      "format": "int32",
                      "minimum": 0,
                      "type": "integer"
                    },
                    "backoff": {
                      "description": "Backoff specifies the retry backoff strategy.\nIf not set, a default backoff with a base interval of 1000ms is used. The default max interval is 10 times the base interval.",
                      "properties": {
                        "baseInterval": {
                          "description": "BaseInterval specifies the base interval used with a fully jittered exponential back-off between retries.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            },
                            {
                              "message": "retry.BaseInterval must be at least 1ms.",
                              "rule": "duration(self) >= duration('1ms')"
                            }
                          ]
                        },
                        "maxInterval": {
                          "description": "MaxInterval specifies the maximum interval between retry attempts.\nDefaults to 10 times the BaseInterval if not set.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            }
                          ]
                        }
                      },
                      "required": [
                        "baseInterval"
                      ],
                      "type": "object",
                      "x-kubernetes-validations": [
                        {
                          "message": "maxInterval must be greater than or equal to baseInterval",
                          "rule": "has(self.maxInterval) ? duration(self.maxInterval) >= duration(self.baseInterval) : true"
                        }
                      ],
                      "additionalProperties": false
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                }
              },
              "required": [
                "backendRef"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "statPrefix": {
              "description": "StatPrefix is an optional prefix to include when emitting stats from the extauthz filter,\nenabling different instances of the filter to have unique stats.",
              "minLength": 1,
              "type": "string"
            },
            "statusOnError": {
              "default": 403,
              "description": "StatusOnError sets the HTTP status response code that is returned to the client when the\nauth server returns an error or cannot be reached. Must be in the range of 100-511 inclusive.\nThe default matches the deny response code of 403 Forbidden.",
              "format": "int32",
              "maximum": 511,
              "minimum": 100,
              "type": "integer"
            },
            "withRequestBody": {
              "description": "WithRequestBody allows the request body to be buffered and sent to the auth service.\nWarning: buffering has implications for streaming and therefore performance.",
              "properties": {
                "allowPartialMessage": {
                  "default": false,
                  "description": "AllowPartialMessage determines if partial messages should be allowed.\nWhen true, requests will be sent to the auth service even if they exceed maxRequestBytes.\nThe default behavior is false.",
                  "type": "boolean"
                },
                "maxRequestBytes": {
                  "description": "MaxRequestBytes sets the maximum size of a message body to buffer.\nRequests exceeding this size will receive HTTP 413 and not be sent to the auth service.",
                  "format": "int32",
                  "minimum": 1,
                  "type": "integer"
                },
                "packAsBytes": {
                  "default": false,
                  "description": "PackAsBytes determines if the body should be sent as raw bytes.\nWhen true, the body is sent as raw bytes in the raw_body field.\nWhen false, the body is sent as UTF-8 string in the body field.\nThe default behavior is false.",
                  "type": "boolean"
                }
              },
              "required": [
                "maxRequestBytes"
              ],
              "type": "object",
              "additionalProperties": false
            }
          },
          "type": "object",
          "x-kubernetes-validations": [
            {
              "message": "exactly one of the fields in [grpcService httpService] must be set",
              "rule": "[has(self.grpcService),has(self.httpService)].filter(x,x==true).size() == 1"
            }
          ],
          "additionalProperties": false
        },
        "extProc": {
          "description": "ExtProc configuration for ExtProc extension type.",
          "properties": {
            "failOpen": {
              "default": true,
              "description": "FailOpen determines if requests are allowed when the ext proc service is unavailable.\nDefaults to true, meaning requests are allowed upstream even if the ext proc service is unavailable.",
              "type": "boolean"
            },
            "grpcService": {
              "description": "GrpcService is the GRPC service that will handle the processing.",
              "properties": {
                "authority": {
                  "description": "Authority is the authority header to use for the GRPC service.",
                  "type": "string"
                },
                "backendRef": {
                  "description": "BackendRef references the backend GRPC service.",
                  "properties": {
                    "group": {
                      "default": "",
                      "description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
                      "maxLength": 253,
                      "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                      "type": "string"
                    },
                    "kind": {
                      "default": "Service",
                      "description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                      "type": "string"
                    },
                    "name": {
                      "description": "Name is the name of the referent.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "namespace": {
                      "description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                      "type": "string"
                    },
                    "port": {
                      "description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
                      "format": "int32",
                      "maximum": 65535,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "weight": {
                      "default": 1,
                      "description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
                      "format": "int32",
                      "maximum": 1000000,
                      "minimum": 0,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object",
                  "x-kubernetes-validations": [
                    {
                      "message": "Must have port for Service reference",
                      "rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
                    }
                  ],
                  "additionalProperties": false
                },
                "requestTimeout": {
                  "description": "RequestTimeout is the timeout for the gRPC request. This is the timeout for a specific request.",
                  "type": "string",
                  "x-kubernetes-validations": [
                    {
                      "message": "invalid timeout value",
                      "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                    },
                    {
                      "message": "timeout must be at least 1ms.",
                      "rule": "duration(self) >= duration('1ms')"
                    }
                  ]
                },
                "retry": {
                  "description": "Retry specifies the retry policy for gRPC streams associated with the service.",
                  "properties": {
                    "attempts": {
                      "default": 1,
                      "description": "Attempts specifies the number of retry attempts for a request.\nDefaults to 1 attempt if not set.\nA value of 0 effectively disables retries.",
                      "format": "int32",
                      "minimum": 0,
                      "type": "integer"
                    },
                    "backoff": {
                      "description": "Backoff specifies the retry backoff strategy.\nIf not set, a default backoff with a base interval of 1000ms is used. The default max interval is 10 times the base interval.",
                      "properties": {
                        "baseInterval": {
                          "description": "BaseInterval specifies the base interval used with a fully jittered exponential back-off between retries.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            },
                            {
                              "message": "retry.BaseInterval must be at least 1ms.",
                              "rule": "duration(self) >= duration('1ms')"
                            }
                          ]
                        },
                        "maxInterval": {
                          "description": "MaxInterval specifies the maximum interval between retry attempts.\nDefaults to 10 times the BaseInterval if not set.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            }
                          ]
                        }
                      },
                      "required": [
                        "baseInterval"
                      ],
                      "type": "object",
                      "x-kubernetes-validations": [
                        {
                          "message": "maxInterval must be greater than or equal to baseInterval",
                          "rule": "has(self.maxInterval) ? duration(self.maxInterval) >= duration(self.baseInterval) : true"
                        }
                      ],
                      "additionalProperties": false
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                }
              },
              "required": [
                "backendRef"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "maxMessageTimeout": {
              "description": "MaxMessageTimeout specifies the upper bound of override_message_timeout that may be sent from the external processing server.\nThe default value 0, which effectively disables the override_message_timeout API.",
              "type": "string",
              "x-kubernetes-validations": [
                {
                  "message": "invalid timeout value",
                  "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                },
                {
                  "message": "timeout must be at least 1ms.",
                  "rule": "duration(self) >= duration('1ms')"
                }
              ]
            },
            "messageTimeout": {
              "description": "MessageTimeout is the timeout for each message sent to the external processing server.",
              "type": "string",
              "x-kubernetes-validations": [
                {
                  "message": "invalid timeout value",
                  "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                },
                {
                  "message": "timeout must be at least 1ms.",
                  "rule": "duration(self) >= duration('1ms')"
                }
              ]
            },
            "metadataOptions": {
              "description": "MetadataOptions allows configuring metadata namespaces to forwarded or received from the external\nprocessing server.",
              "properties": {
                "forwarding": {
                  "description": "Forwarding defines the typed or untyped dynamic metadata namespaces to forward to the external processing server.",
                  "properties": {
                    "typed": {
                      "items": {
                        "type": "string"
                      },
                      "minItems": 1,
                      "type": "array"
                    },
                    "untyped": {
                      "items": {
                        "type": "string"
                      },
                      "minItems": 1,
                      "type": "array"
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                }
              },
              "type": "object",
              "additionalProperties": false
            },
            "processingMode": {
              "description": "ProcessingMode defines how the filter should interact with the request/response streams.",
              "properties": {
                "requestBodyMode": {
                  "default": "NONE",
                  "description": "RequestBodyMode determines how to handle the request body",
                  "enum": [
                    "NONE",
                    "STREAMED",
                    "BUFFERED",
                    "BUFFERED_PARTIAL",
                    "FULL_DUPLEX_STREAMED"
                  ],
                  "type": "string"
                },
                "requestHeaderMode": {
                  "default": "SEND",
                  "description": "RequestHeaderMode determines how to handle the request headers",
                  "enum": [
                    "DEFAULT",
                    "SEND",
                    "SKIP"
                  ],
                  "type": "string"
                },
                "requestTrailerMode": {
                  "default": "SKIP",
                  "description": "RequestTrailerMode determines how to handle the request trailers",
                  "enum": [
                    "DEFAULT",
                    "SEND",
                    "SKIP"
                  ],
                  "type": "string"
                },
                "responseBodyMode": {
                  "default": "NONE",
                  "description": "ResponseBodyMode determines how to handle the response body",
                  "enum": [
                    "NONE",
                    "STREAMED",
                    "BUFFERED",
                    "BUFFERED_PARTIAL",
                    "FULL_DUPLEX_STREAMED"
                  ],
                  "type": "string"
                },
                "responseHeaderMode": {
                  "default": "SEND",
                  "description": "ResponseHeaderMode determines how to handle the response headers",
                  "enum": [
                    "DEFAULT",
                    "SEND",
                    "SKIP"
                  ],
                  "type": "string"
                },
                "responseTrailerMode": {
                  "default": "SKIP",
                  "description": "ResponseTrailerMode determines how to handle the response trailers",
                  "enum": [
                    "DEFAULT",
                    "SEND",
                    "SKIP"
                  ],
                  "type": "string"
                }
              },
              "type": "object",
              "additionalProperties": false
            },
            "routeCacheAction": {
              "default": "FromResponse",
              "description": "RouteCacheAction describes the route cache action to be taken when an\nexternal processor response is received in response to request headers.\nThe default behavior is \"FromResponse\" which will only clear the route cache when\nan external processing response has the clear_route_cache field set.",
              "enum": [
                "FromResponse",
                "Clear",
                "Retain"
              ],
              "type": "string"
            },
            "statPrefix": {
              "description": "StatPrefix is an optional prefix to include when emitting stats from the extproc filter,\nenabling different instances of the filter to have unique stats.",
              "minLength": 1,
              "type": "string"
            }
          },
          "required": [
            "grpcService"
          ],
          "type": "object",
          "additionalProperties": false
        },
        "jwt": {
          "description": "JWT configuration for JWT extension type.",
          "properties": {
            "providers": {
              "description": "Providers configures named JWT providers.\nIf multiple providers are specified for a given JWT policy,\nthe providers will be `OR`-ed together and will allow validation to any of the providers.",
              "items": {
                "description": "NamedJWTProvider is a named JWT provider entry.",
                "properties": {
                  "audiences": {
                    "description": "Audiences is the list of audiences to be used for the JWT provider.\nIf specified an incoming JWT must have an 'aud' claim, and it must be in this list.\nIf not specified, the audiences will not be checked in the token.",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 32,
                    "minItems": 1,
                    "type": "array"
                  },
                  "claimsToHeaders": {
                    "description": "ClaimsToHeaders is the list of claims to headers to be used for the JWT provider.\nOptionally set the claims from the JWT payload that you want to extract and add as headers\nto the request before the request is forwarded to the upstream destination.\nNote: if ClaimsToHeaders is set, the Envoy route cache will be cleared.\nThis allows the JWT filter to correctly affect routing decisions.",
                    "items": {
                      "description": "JWTClaimToHeader allows copying verified claims to headers sent upstream",
                      "properties": {
                        "header": {
                          "description": "Header is the header the claim will be copied to, for example, \"x-sub\".",
                          "maxLength": 2048,
                          "minLength": 1,
                          "type": "string"
                        },
                        "name": {
                          "description": "Name is the JWT claim name, for example, \"sub\".",
                          "maxLength": 2048,
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "header",
                        "name"
                      ],
                      "type": "object",
                      "additionalProperties": false
                    },
                    "maxItems": 32,
                    "minItems": 1,
                    "type": "array"
                  },
                  "forwardToken": {
                    "description": "ForwardToken configures if the JWT token is forwarded to the upstream backend.\nIf true, the header containing the token will be forwarded upstream.\nIf false or not set, the header containing the token will be removed.",
                    "type": "boolean"
                  },
                  "issuer": {
                    "description": "Issuer of the JWT. the 'iss' claim of the JWT must match this.",
                    "maxLength": 2048,
                    "type": "string"
                  },
                  "jwks": {
                    "description": "JWKS is the source for the JSON Web Keys to be used to validate the JWT.",
                    "properties": {
                      "local": {
                        "description": "LocalJWKS configures getting the public keys to validate the JWT from a Kubernetes configmap,\nor inline (raw string) JWKS.",
                        "properties": {
                          "configMapRef": {
                            "description": "ConfigMapRef configures storing the JWK in a Kubernetes ConfigMap in the same namespace as the GatewayExtension.\nThe ConfigMap must have a data key named 'jwks' that contains the JWKS.",
                            "properties": {
                              "name": {
                                "default": "",
                                "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names",
                                "type": "string"
                              }
                            },
                            "type": "object",
                            "x-kubernetes-map-type": "atomic",
                            "additionalProperties": false
                          },
                          "inline": {
                            "description": "Inline is the JWKS as the raw, inline JWKS string\nThis can be an individual key, a key set or a pem block public key",
                            "maxLength": 16384,
                            "minLength": 1,
                            "type": "string"
                          }
                        },
                        "type": "object",
                        "x-kubernetes-validations": [
                          {
                            "message": "exactly one of the fields in [inline configMapRef] must be set",
                            "rule": "[has(self.inline),has(self.configMapRef)].filter(x,x==true).size() == 1"
                          }
                        ],
                        "additionalProperties": false
                      },
                      "remote": {
                        "description": "RemoteJWKS configures getting the public keys to validate the JWT from a remote JWKS server.",
                        "properties": {
                          "backendRef": {
                            "description": "BackendRef is reference to the backend of the JWKS server.",
                            "properties": {
                              "group": {
                                "default": "",
                                "description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
                                "maxLength": 253,
                                "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                                "type": "string"
                              },
                              "kind": {
                                "default": "Service",
                                "description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
                                "maxLength": 63,
                                "minLength": 1,
                                "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                                "type": "string"
                              },
                              "name": {
                                "description": "Name is the name of the referent.",
                                "maxLength": 253,
                                "minLength": 1,
                                "type": "string"
                              },
                              "namespace": {
                                "description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
                                "maxLength": 63,
                                "minLength": 1,
                                "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                                "type": "string"
                              },
                              "port": {
                                "description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
                                "format": "int32",
                                "maximum": 65535,
                                "minimum": 1,
                                "type": "integer"
                              }
                            },
                            "required": [
                              "name"
                            ],
                            "type": "object",
                            "x-kubernetes-validations": [
                              {
                                "message": "Must have port for Service reference",
                                "rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
                              }
                            ],
                            "additionalProperties": false
                          },
                          "cacheDuration": {
                            "description": "Duration after which the cached JWKS expires.\nIf unspecified, the default cache duration is 5 minutes.",
                            "type": "string",
                            "x-kubernetes-validations": [
                              {
                                "message": "invalid duration value",
                                "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                              },
                              {
                                "message": "cacheDuration must be at least 1ms.",
                                "rule": "duration(self) >= duration('1ms')"
                              }
                            ]
                          },
                          "url": {
                            "description": "URL is the URL of the remote JWKS server, it must be a full FQDN with protocol, host and path.\nFor example, https://example.com/keys",
                            "maxLength": 2048,
                            "minLength": 1,
                            "type": "string"
                          }
                        },
                        "required": [
                          "backendRef",
                          "url"
                        ],
                        "type": "object",
                        "additionalProperties": false
                      }
                    },
                    "type": "object",
                    "x-kubernetes-validations": [
                      {
                        "message": "exactly one of the fields in [local remote] must be set",
                        "rule": "[has(self.local),has(self.remote)].filter(x,x==true).size() == 1"
                      }
                    ],
                    "additionalProperties": false
                  },
                  "name": {
                    "description": "Name is the unique name of the JWT provider.",
                    "maxLength": 253,
                    "minLength": 1,
                    "type": "string"
                  },
                  "tokenSource": {
                    "description": "TokenSource configures where to find the JWT of the current provider.",
                    "properties": {
                      "header": {
                        "description": "HeaderSource configures retrieving token from a header",
                        "properties": {
                          "header": {
                            "description": "Header is the name of the header. for example, \"Authorization\"",
                            "maxLength": 2048,
                            "minLength": 1,
                            "type": "string"
                          },
                          "prefix": {
                            "description": "Prefix before the token. for example, \"Bearer \"",
                            "maxLength": 2048,
                            "minLength": 1,
                            "type": "string"
                          }
                        },
                        "required": [
                          "header"
                        ],
                        "type": "object",
                        "additionalProperties": false
                      },
                      "queryParameter": {
                        "description": "QueryParameter configures retrieving token from the query parameter",
                        "type": "string"
                      }
                    },
                    "type": "object",
                    "x-kubernetes-validations": [
                      {
                        "message": "exactly one of the fields in [header queryParameter] must be set",
                        "rule": "[has(self.header),has(self.queryParameter)].filter(x,x==true).size() == 1"
                      }
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "jwks",
                  "name"
                ],
                "type": "object",
                "additionalProperties": false
              },
              "maxItems": 32,
              "type": "array",
              "x-kubernetes-list-map-keys": [
                "name"
              ],
              "x-kubernetes-list-type": "map"
            },
            "validationMode": {
              "description": "ValidationMode configures how JWT validation behaves.\nIf unset or empty, Strict mode is used (JWT is required).\nIf set to AllowMissing, unauthenticated requests without a JWT are allowed through.\nIf using this mode, make sure to consider the security implications and\nconsider using an `RBAC` policy to enforce authorization.",
              "enum": [
                "Strict",
                "AllowMissing"
              ],
              "type": "string"
            }
          },
          "type": "object",
          "additionalProperties": false
        },
        "oauth2": {
          "description": "OAuth2 configuration for OAuth2 extension type.",
          "properties": {
            "authorizationEndpoint": {
              "description": "AuthorizationEndpoint specifies the endpoint to redirect to for authorization in response to unauthorized requests.\nRefer to https://datatracker.ietf.org/doc/html/rfc6749#section-3.1 for more details.",
              "pattern": "^https://([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)*[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?(:[0-9]{1,5})?(/[a-zA-Z0-9\\-._~!$&'()*+,;=:@%]*)*/?(\\?[a-zA-Z0-9\\-._~!$&'()*+,;=:@%/?]*)?$",
              "type": "string"
            },
            "backendRef": {
              "description": "BackendRef specifies the Backend to use for the OAuth2 provider.",
              "properties": {
                "group": {
                  "default": "",
                  "description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
                  "maxLength": 253,
                  "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                  "type": "string"
                },
                "kind": {
                  "default": "Service",
                  "description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
                  "maxLength": 63,
                  "minLength": 1,
                  "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                  "type": "string"
                },
                "name": {
                  "description": "Name is the name of the referent.",
                  "maxLength": 253,
                  "minLength": 1,
                  "type": "string"
                },
                "namespace": {
                  "description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
                  "maxLength": 63,
                  "minLength": 1,
                  "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                  "type": "string"
                },
                "port": {
                  "description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
                  "format": "int32",
                  "maximum": 65535,
                  "minimum": 1,
                  "type": "integer"
                },
                "weight": {
                  "default": 1,
                  "description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
                  "format": "int32",
                  "maximum": 1000000,
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "required": [
                "name"
              ],
              "type": "object",
              "x-kubernetes-validations": [
                {
                  "message": "Must have port for Service reference",
                  "rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
                }
              ],
              "additionalProperties": false
            },
            "cookies": {
              "description": "Cookies specifies the configuration for the OAuth2 cookies.",
              "properties": {
                "domain": {
                  "description": "CookieDomain specifies the domain to set on the access and ID token cookies.\nIf set, the cookies will be set for the specified domain and all its subdomains. This is useful when requests\nto subdomains are not required to be re-authenticated after the user has logged into the parent domain.\nIf not set, the cookies will default to the host of the request, not including the subdomains.",
                  "maxLength": 253,
                  "minLength": 1,
                  "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9]))*$",
                  "type": "string"
                },
                "names": {
                  "description": "Names specifies the names of the cookies used to store the tokens.\nIf not set, the default names will be used.",
                  "properties": {
                    "accessToken": {
                      "description": "AccessToken specifies the name of the cookie used to store the access token.",
                      "minLength": 1,
                      "type": "string"
                    },
                    "idToken": {
                      "description": "IDToken specifies the name of the cookie used to store the ID token.",
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                },
                "sameSite": {
                  "description": "SameSite specifies the SameSite attribute for the OAuth2 cookies.\nIf not set, the default is Lax.",
                  "enum": [
                    "Lax",
                    "Strict",
                    "None"
                  ],
                  "type": "string"
                }
              },
              "type": "object",
              "additionalProperties": false
            },
            "credentials": {
              "description": "Credentials specifies the Oauth2 client credentials to use for authentication.",
              "properties": {
                "clientID": {
                  "description": "ClientID specifies the client ID issued to the client during the registration process.\nRefer to https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1 for more details.",
                  "minLength": 1,
                  "type": "string"
                },
                "clientSecretRef": {
                  "description": "ClientSecretRef specifies a Secret that contains the client secret stored in the key 'client-secret'\nto use in the authentication request to obtain the access token.\nRefer to https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1 for more details.",
                  "properties": {
                    "name": {
                      "default": "",
                      "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names",
                      "type": "string"
                    }
                  },
                  "type": "object",
                  "x-kubernetes-map-type": "atomic",
                  "additionalProperties": false
                }
              },
              "required": [
                "clientID",
                "clientSecretRef"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "denyRedirect": {
              "description": "DenyRedirectMatcher specifies the matcher to match requests that should be denied redirects to the authorization endpoint.\nMatching requests will receive a 401 Unauthorized response instead of being redirected.\nThis is useful for AJAX requests where redirects should be avoided.",
              "properties": {
                "headers": {
                  "description": "Headers specifies the list of HTTP headers to match on requests that should be denied redirects.",
                  "items": {
                    "description": "HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request\nheaders.",
                    "properties": {
                      "name": {
                        "description": "Name is the name of the HTTP Header to be matched. Name matching MUST be\ncase-insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).\n\nIf multiple entries specify equivalent header names, only the first\nentry with an equivalent name MUST be considered for a match. Subsequent\nentries with an equivalent header name MUST be ignored. Due to the\ncase-insensitivity of header names, \"foo\" and \"Foo\" are considered\nequivalent.\n\nWhen a header is repeated in an HTTP request, it is\nimplementation-specific behavior as to how this is represented.\nGenerally, proxies should follow the guidance from the RFC:\nhttps://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding\nprocessing a repeated header, with special handling for \"Set-Cookie\".",
                        "maxLength": 256,
                        "minLength": 1,
                        "pattern": "^[A-Za-z0-9!#$%&'*+\\-.^_\\x60|~]+$",
                        "type": "string"
                      },
                      "type": {
                        "default": "Exact",
                        "description": "Type specifies how to match against the value of the header.\n\nSupport: Core (Exact)\n\nSupport: Implementation-specific (RegularExpression)\n\nSince RegularExpression HeaderMatchType has implementation-specific\nconformance, implementations can support POSIX, PCRE or any other dialects\nof regular expressions. Please read the implementation's documentation to\ndetermine the supported dialect.",
                        "enum": [
                          "Exact",
                          "RegularExpression"
                        ],
                        "type": "string"
                      },
                      "value": {
                        "description": "Value is the value of HTTP Header to be matched.",
                        "maxLength": 4096,
                        "minLength": 1,
                        "type": "string"
                      }
                    },
                    "required": [
                      "name",
                      "value"
                    ],
                    "type": "object",
                    "additionalProperties": false
                  },
                  "maxItems": 16,
                  "minItems": 1,
                  "type": "array"
                }
              },
              "type": "object",
              "additionalProperties": false
            },
            "endSessionEndpoint": {
              "description": "EndSessionEndpoint specifies the URL that redirects a user's browser to in order to initiate a single logout\nacross all applications and the OpenID provider. Users are directed to this endpoint when they access the logout path.\nThis should only be set when the OpenID provider supports RP-Initiated Logout and \"openid\" is included in the list of scopes.\nRefer to https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout for more details.",
              "pattern": "^https://([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)*[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?(:[0-9]{1,5})?(/[a-zA-Z0-9\\-._~!$&'()*+,;=:@%]*)*/?(\\?[a-zA-Z0-9\\-._~!$&'()*+,;=:@%/?]*)?$",
              "type": "string"
            },
            "forwardAccessToken": {
              "description": "ForwardAccessToken specifies whether to forward the access token to the backend service.\nIf set to true, the token is forwarded over a cookie named BearerToken and is also set in the Authorization header.\nDefaults to false.",
              "type": "boolean"
            },
            "issuerURI": {
              "description": "IssuerURI specifies the OpenID provider's issuer URL to discover the OpenID provider's configuration.\nThe Issuer must be a URI RFC 3986 [RFC3986] with a scheme component that must be https, a host component,\nand optionally, port and path components and no query or fragment components.\nIt discovers the authorizationEndpoint, tokenEndpoint, and endSessionEndpoint if specified in the discovery response.\nRefer to https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig for more details.\nNote that the OpenID provider configuration is cached and only refreshed periodically when the GatewayExtension object\nis reprocessed.",
              "pattern": "^https://([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)*[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?(:[0-9]{1,5})?(/[a-zA-Z0-9\\-._~!$&'()*+,;=:@%]*)*/?$",
              "type": "string"
            },
            "logoutPath": {
              "default": "/logout",
              "description": "LogoutPath specifies the path to log out a user, clearing their credential cookies.\nDefaults to /logout.",
              "minLength": 1,
              "type": "string"
            },
            "redirectURI": {
              "description": "RedirectURI specifies the URL passed to the authorization endpoint.\nDefaults to <request-scheme>://<host>/oauth2/redirect, where the URL scheme and host are derived from the original request.\nRefer to https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2 for more details.",
              "type": "string"
            },
            "scopes": {
              "description": "List of OAuth scopes to be claimed in the authentication request.\nDefaults to \"user\" scope if not specified.\nWhen using OpenID, the \"openid\" scope must be included.\nRefer to https://datatracker.ietf.org/doc/html/rfc6749#section-3.3 for more details.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "tokenEndpoint": {
              "description": "TokenEndpoint specifies the endpoint on the authorization server to retrieve the access token from.\nRefer to https://datatracker.ietf.org/doc/html/rfc6749#section-3.2 for more details.",
              "pattern": "^https://([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)*[a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?(:[0-9]{1,5})?(/[a-zA-Z0-9\\-._~!$&'()*+,;=:@%]*)*/?(\\?[a-zA-Z0-9\\-._~!$&'()*+,;=:@%/?]*)?$",
              "type": "string"
            }
          },
          "required": [
            "backendRef",
            "credentials"
          ],
          "type": "object",
          "x-kubernetes-validations": [
            {
              "message": "Either issuerURI, or both authorizationEndpoint and tokenEndpoint must be specified",
              "rule": "has(self.issuerURI) || (has(self.authorizationEndpoint) && has(self.tokenEndpoint))"
            }
          ],
          "additionalProperties": false
        },
        "rateLimit": {
          "description": "RateLimit configuration for RateLimit extension type.",
          "properties": {
            "domain": {
              "description": "Domain identifies a rate limiting configuration for the rate limit service.\nAll rate limit requests must specify a domain, which enables the configuration\nto be per application without fear of overlap (e.g., \"api\", \"web\", \"admin\").",
              "type": "string"
            },
            "failOpen": {
              "default": true,
              "description": "FailOpen determines if requests are limited when the rate limit service is unavailable.\nDefaults to true, meaning requests are allowed upstream and not limited if the rate limit service is unavailable.",
              "type": "boolean"
            },
            "grpcService": {
              "description": "GrpcService is the GRPC service that will handle the rate limiting.",
              "properties": {
                "authority": {
                  "description": "Authority is the authority header to use for the GRPC service.",
                  "type": "string"
                },
                "backendRef": {
                  "description": "BackendRef references the backend GRPC service.",
                  "properties": {
                    "group": {
                      "default": "",
                      "description": "Group is the group of the referent. For example, \"gateway.networking.k8s.io\".\nWhen unspecified or empty string, core API group is inferred.",
                      "maxLength": 253,
                      "pattern": "^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$",
                      "type": "string"
                    },
                    "kind": {
                      "default": "Service",
                      "description": "Kind is the Kubernetes resource kind of the referent. For example\n\"Service\".\n\nDefaults to \"Service\" when not specified.\n\nExternalName services can refer to CNAME DNS records that may live\noutside of the cluster and as such are difficult to reason about in\nterms of conformance. They also may not be safe to forward to (see\nCVE-2021-25740 for more information). Implementations SHOULD NOT\nsupport ExternalName Services.\n\nSupport: Core (Services with a type other than ExternalName)\n\nSupport: Implementation-specific (Services with type ExternalName)",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$",
                      "type": "string"
                    },
                    "name": {
                      "description": "Name is the name of the referent.",
                      "maxLength": 253,
                      "minLength": 1,
                      "type": "string"
                    },
                    "namespace": {
                      "description": "Namespace is the namespace of the backend. When unspecified, the local\nnamespace is inferred.\n\nNote that when a namespace different than the local namespace is specified,\na ReferenceGrant object is required in the referent namespace to allow that\nnamespace's owner to accept the reference. See the ReferenceGrant\ndocumentation for details.\n\nSupport: Core",
                      "maxLength": 63,
                      "minLength": 1,
                      "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
                      "type": "string"
                    },
                    "port": {
                      "description": "Port specifies the destination port number to use for this resource.\nPort is required when the referent is a Kubernetes Service. In this\ncase, the port number is the service port number, not the target port.\nFor other resources, destination port might be derived from the referent\nresource or this field.",
                      "format": "int32",
                      "maximum": 65535,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "weight": {
                      "default": 1,
                      "description": "Weight specifies the proportion of requests forwarded to the referenced\nbackend. This is computed as weight/(sum of all weights in this\nBackendRefs list). For non-zero values, there may be some epsilon from\nthe exact proportion defined here depending on the precision an\nimplementation supports. Weight is not a percentage and the sum of\nweights does not need to equal 100.\n\nIf only one backend is specified and it has a weight greater than 0, 100%\nof the traffic is forwarded to that backend. If weight is set to 0, no\ntraffic should be forwarded for this entry. If unspecified, weight\ndefaults to 1.\n\nSupport for this field varies based on the context where used.",
                      "format": "int32",
                      "maximum": 1000000,
                      "minimum": 0,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object",
                  "x-kubernetes-validations": [
                    {
                      "message": "Must have port for Service reference",
                      "rule": "(size(self.group) == 0 && self.kind == 'Service') ? has(self.port) : true"
                    }
                  ],
                  "additionalProperties": false
                },
                "requestTimeout": {
                  "description": "RequestTimeout is the timeout for the gRPC request. This is the timeout for a specific request.",
                  "type": "string",
                  "x-kubernetes-validations": [
                    {
                      "message": "invalid timeout value",
                      "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                    },
                    {
                      "message": "timeout must be at least 1ms.",
                      "rule": "duration(self) >= duration('1ms')"
                    }
                  ]
                },
                "retry": {
                  "description": "Retry specifies the retry policy for gRPC streams associated with the service.",
                  "properties": {
                    "attempts": {
                      "default": 1,
                      "description": "Attempts specifies the number of retry attempts for a request.\nDefaults to 1 attempt if not set.\nA value of 0 effectively disables retries.",
                      "format": "int32",
                      "minimum": 0,
                      "type": "integer"
                    },
                    "backoff": {
                      "description": "Backoff specifies the retry backoff strategy.\nIf not set, a default backoff with a base interval of 1000ms is used. The default max interval is 10 times the base interval.",
                      "properties": {
                        "baseInterval": {
                          "description": "BaseInterval specifies the base interval used with a fully jittered exponential back-off between retries.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            },
                            {
                              "message": "retry.BaseInterval must be at least 1ms.",
                              "rule": "duration(self) >= duration('1ms')"
                            }
                          ]
                        },
                        "maxInterval": {
                          "description": "MaxInterval specifies the maximum interval between retry attempts.\nDefaults to 10 times the BaseInterval if not set.",
                          "type": "string",
                          "x-kubernetes-validations": [
                            {
                              "message": "invalid duration value",
                              "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                            }
                          ]
                        }
                      },
                      "required": [
                        "baseInterval"
                      ],
                      "type": "object",
                      "x-kubernetes-validations": [
                        {
                          "message": "maxInterval must be greater than or equal to baseInterval",
                          "rule": "has(self.maxInterval) ? duration(self.maxInterval) >= duration(self.baseInterval) : true"
                        }
                      ],
                      "additionalProperties": false
                    }
                  },
                  "type": "object",
                  "additionalProperties": false
                }
              },
              "required": [
                "backendRef"
              ],
              "type": "object",
              "additionalProperties": false
            },
            "timeout": {
              "default": "100ms",
              "description": "Timeout provides an optional timeout value for requests to the rate limit service.\nFor rate limiting, prefer using this timeout rather than setting the generic `timeout` on the `GrpcService`.\nSee [envoy issue](https://github.com/envoyproxy/envoy/issues/20070) for more info.",
              "type": "string",
              "x-kubernetes-validations": [
                {
                  "message": "invalid duration value",
                  "rule": "matches(self, '^([0-9]{1,5}(h|m|s|ms)){1,4}$')"
                }
              ]
            },
            "xRateLimitHeaders": {
              "default": "Off",
              "description": "XRateLimitHeaders configures the standard version to use for X-RateLimit headers emitted.\nSee [envoy docs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ratelimit/v3/rate_limit.proto#envoy-v3-api-field-extensions-filters-http-ratelimit-v3-ratelimit-enable-x-ratelimit-headers) for more info.\nDisabled by default.",
              "enum": [
                "Off",
                "DraftVersion03"
              ],
              "type": "string"
            }
          },
          "required": [
            "domain",
            "grpcService"
          ],
          "type": "object",
          "additionalProperties": false
        },
        "type": {
          "description": "Deprecated: Setting this field has no effect.\nType indicates the type of the GatewayExtension to be used.",
          "enum": [
            "ExtAuth",
            "ExtProc",
            "RateLimit",
            "JWT",
            "OAuth2"
          ],
          "type": "string"
        }
      },
      "type": "object",
      "x-kubernetes-validations": [
        {
          "message": "extAuth must be set when type is ExtAuth",
          "rule": "has(self.type) && self.type == 'ExtAuth' ? has(self.extAuth) : true"
        },
        {
          "message": "extProc must be set when type is ExtProc",
          "rule": "has(self.type) && self.type == 'ExtProc' ? has(self.extProc) : true"
        },
        {
          "message": "rateLimit must be set when type is RateLimit",
          "rule": "has(self.type) && self.type == 'RateLimit' ? has(self.rateLimit) : true"
        },
        {
          "message": "JWT must be set when type is JWT",
          "rule": "has(self.type) && self.type == 'JWT' ? has(self.jwt) : true"
        },
        {
          "message": "oauth2 must be set when type is OAuth2",
          "rule": "has(self.type) && self.type == 'OAuth2' ? has(self.oauth2) : true"
        },
        {
          "message": "exactly one of the fields in [extAuth extProc rateLimit jwt oauth2] must be set",
          "rule": "[has(self.extAuth),has(self.extProc),has(self.rateLimit),has(self.jwt),has(self.oauth2)].filter(x,x==true).size() == 1"
        }
      ],
      "additionalProperties": false
    },
    "status": {
      "description": "GatewayExtensionStatus defines the observed state of GatewayExtension.",
      "properties": {
        "conditions": {
          "description": "Conditions is the list of conditions for the GatewayExtension.",
          "items": {
            "description": "Condition contains details for one aspect of the current state of this API Resource.",
            "properties": {
              "lastTransitionTime": {
                "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.",
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
                "maxLength": 32768,
                "type": "string"
              },
              "observedGeneration": {
                "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
                "format": "int64",
                "minimum": 0,
                "type": "integer"
              },
              "reason": {
                "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
                "type": "string"
              },
              "status": {
                "description": "status of the condition, one of True, False, Unknown.",
                "enum": [
                  "True",
                  "False",
                  "Unknown"
                ],
                "type": "string"
              },
              "type": {
                "description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
                "maxLength": 316,
                "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
                "type": "string"
              }
            },
            "required": [
              "lastTransitionTime",
              "message",
              "reason",
              "status",
              "type"
            ],
            "type": "object",
            "additionalProperties": false
          },
          "maxItems": 8,
          "type": "array",
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        }
      },
      "type": "object",
      "additionalProperties": false
    }
  },
  "required": [
    "spec"
  ],
  "type": "object"
}
