diff --git a/gradle.properties b/gradle.properties index f941e99..f9e420b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ -version=1.35.8-2 +version=1.37.5-1 org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 diff --git a/src/main/proto/cel/expr/conformance/conformance_service.proto b/src/main/proto/cel/expr/conformance/conformance_service.proto index 0b4740b..2564c10 100644 --- a/src/main/proto/cel/expr/conformance/conformance_service.proto +++ b/src/main/proto/cel/expr/conformance/conformance_service.proto @@ -19,7 +19,6 @@ package cel.expr.conformance; import "cel/expr/checked.proto"; import "cel/expr/eval.proto"; import "cel/expr/syntax.proto"; -import "google/rpc/status.proto"; option cc_enable_arenas = true; option go_package = "cel.dev/expr/conformance"; @@ -69,7 +68,7 @@ message ParseResponse { cel.expr.ParsedExpr parsed_expr = 1; // Any number of issues with [StatusDetails][] as the details. - repeated google.rpc.Status issues = 2; + cel.expr.ErrorSet issues = 2; } // Request message for the Check method. @@ -86,7 +85,7 @@ message CheckRequest { // Language Definition. string container = 3; - // If true, use only the declarations in [type_env][google.api.expr.conformance.v1alpha1.CheckRequest.type_env]. If false (default), + // If true, use only the declarations in [type_env][cel.expr.conformance.CheckRequest.type_env]. If false (default), // add declarations for the standard definitions to the type environment. See // "Standard Definitions" in the Language Definition. bool no_std_env = 4; @@ -98,7 +97,7 @@ message CheckResponse { cel.expr.CheckedExpr checked_expr = 1; // Any number of issues with [StatusDetails][] as the details. - repeated google.rpc.Status issues = 2; + cel.expr.ErrorSet issues = 2; } // Request message for the Eval method. @@ -113,10 +112,10 @@ message EvalRequest { } // Bindings for the external variables. The types SHOULD be compatible - // with the type environment in [CheckRequest][google.api.expr.conformance.v1alpha1.CheckRequest], if checked. + // with the type environment in [CheckRequest][cel.expr.conformance.CheckRequest], if checked. map bindings = 3; - // SHOULD be the same container as used in [CheckRequest][google.api.expr.conformance.v1alpha1.CheckRequest], if checked. + // SHOULD be the same container as used in [CheckRequest][cel.expr.conformance.CheckRequest], if checked. string container = 4; } @@ -129,7 +128,7 @@ message EvalResponse { // Note that CEL execution errors are reified into [ExprValue][]. // Nevertheless, we'll allow out-of-band issues to be raised, // which also makes the replies more regular. - repeated google.rpc.Status issues = 2; + cel.expr.ErrorSet issues = 2; } // A specific position in source. diff --git a/src/main/proto/cel/expr/conformance/proto2/test_all_types.proto b/src/main/proto/cel/expr/conformance/proto2/test_all_types.proto index 7a68093..620a1e4 100644 --- a/src/main/proto/cel/expr/conformance/proto2/test_all_types.proto +++ b/src/main/proto/cel/expr/conformance/proto2/test_all_types.proto @@ -319,6 +319,25 @@ message TestAllTypes { optional string single_name = 405; } + // Field names formerly defined as reserved CEL identifiers. + optional bool as = 500; + optional bool break = 501; + optional bool const = 502; + optional bool continue = 503; + optional bool else = 504; + optional bool for = 505; + optional bool function = 506; + optional bool if = 507; + optional bool import = 508; + optional bool let = 509; + optional bool loop = 510; + optional bool package = 511; + optional bool namespace = 512; + optional bool return = 513; + optional bool var = 514; + optional bool void = 515; + optional bool while = 516; + extensions 1000 to max; } diff --git a/src/main/proto/cel/expr/conformance/proto3/test_all_types.proto b/src/main/proto/cel/expr/conformance/proto3/test_all_types.proto index c4b59fe..ff6f31a 100644 --- a/src/main/proto/cel/expr/conformance/proto3/test_all_types.proto +++ b/src/main/proto/cel/expr/conformance/proto3/test_all_types.proto @@ -315,6 +315,25 @@ message TestAllTypes { NestedMessage oneof_msg = 401; bool oneof_bool = 402; } + + // Field names formerly defined as reserved CEL identifiers. + bool as = 500; + bool break = 501; + bool const = 502; + bool continue = 503; + bool else = 504; + bool for = 505; + bool function = 506; + bool if = 507; + bool import = 508; + bool let = 509; + bool loop = 510; + bool package = 511; + bool namespace = 512; + bool return = 513; + bool var = 514; + bool void = 515; + bool while = 516; } // This proto includes a recursively nested message. diff --git a/src/main/proto/cel/policy/policy.proto b/src/main/proto/cel/policy/policy.proto new file mode 100644 index 0000000..e6a45f9 --- /dev/null +++ b/src/main/proto/cel/policy/policy.proto @@ -0,0 +1,80 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package cel.policy; + +option cc_enable_arenas = true; +option go_package = "cel.dev/policy"; +option java_multiple_files = true; +option java_package = "dev.cel.policy"; + +message PolicySpec { + message Import { + string name = 1; + } + + message Variable { + string name = 1; + + string description = 2; + + string expression = 3; + } + + message Rule { + string id = 1; + + string description = 2; + + repeated Variable variables = 3; + + repeated Match match = 4; + } + + message Match { + // If unset, the default is "true". + optional string condition = 1; + + oneof action { + string output = 2; + + Rule rule = 3; + } + + string explanation = 4; + } + + string name = 1; + + repeated Import imports = 2; + + // If set, [PolicySpec][match] and [PolicySpec][rule] must be unset. + repeated Variable variables = 3; + // If set, [PolicySpec][match] and [PolicySpec][rule] must be unset. + optional string output = 4; + // If set, [PolicySpec][match] and [PolicySpec][rule] must be unset. + optional string description = 5; + // If set, [PolicySpec][match] and [PolicySpec][rule] must be unset. + optional string explanation = 6; + + // If set, [PolicySpec][variables], [PolicySpec][output], [PolicySpec][description], + // [PolicySpec][explanation], and [PolicySpec][rule] must be unset. + repeated Match match = 7; + + // If set, [PolicySpec][variables], [PolicySpec][output], [PolicySpec][description], + // [PolicySpec][explanation], and [PolicySpec][match] must be unset. + Rule rule = 8; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/common/workload_discovery/v3/discovery.proto b/src/main/proto/contrib/envoy/extensions/filters/common/workload_discovery/v3/discovery.proto new file mode 100644 index 0000000..f64ebdf --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/common/workload_discovery/v3/discovery.proto @@ -0,0 +1,249 @@ +syntax = "proto3"; + +package istio.workload; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.istio.workload"; +option java_outer_classname = "DiscoveryProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/istio/workload"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// +// Warning: Derived from +// https://github.com/istio/ztunnel/blob/e36680f1534fae3d158964500ae9185495ec5d7b/proto/workload.proto +// with the following changes: +// +// 1) change go_package; +// 2) append bootstrap extension stub; + +// NetworkMode indicates how the addresses of the workload should be treated. +enum NetworkMode { + // STANDARD means that the workload is uniquely identified by its address (within its network). + STANDARD = 0; + + // HOST_NETWORK means the workload has an IP address that is shared by many workloads. The data plane should avoid + // attempting to lookup these workloads by IP address (which could return the wrong result). + HOST_NETWORK = 1; +} + +enum WorkloadStatus { + // Workload is healthy and ready to serve traffic. + HEALTHY = 0; + + // Workload is unhealthy and NOT ready to serve traffic. + UNHEALTHY = 1; +} + +enum WorkloadType { + DEPLOYMENT = 0; + CRONJOB = 1; + POD = 2; + JOB = 3; +} + +// TunnelProtocol indicates the tunneling protocol for requests. +enum TunnelProtocol { + // NONE means requests should be forwarded as-is, without tunneling. + NONE = 0; + + // HBONE means requests should be tunneled over HTTP. + // This does not dictate HTTP/1.1 vs HTTP/2; ALPN should be used for that purpose. + HBONE = 1; + // Future options may include things like QUIC/HTTP3, etc. +} + +// Workload represents a workload - an endpoint (or collection behind a hostname). +// The xds primary key is "uid" as defined on the workload below. +// Secondary (alias) keys are the unique ``network/IP`` pairs that the workload can be reached at. +// [#next-free-field: 26] +message Workload { + reserved 15; + + // UID represents a globally unique opaque identifier for this workload. + // For k8s resources, it is recommended to use the more readable format: + // + // cluster/group/kind/namespace/name/section-name + // + // As an example, a ServiceEntry with two WorkloadEntries inlined could become + // two Workloads with the following UIDs: + // - cluster1/networking.istio.io/v1alpha3/ServiceEntry/default/external-svc/endpoint1 + // - cluster1/networking.istio.io/v1alpha3/ServiceEntry/default/external-svc/endpoint2 + // + // For VMs and other workloads other formats are also supported; for example, + // a single UID string: "0ae5c03d-5fb3-4eb9-9de8-2bd4b51606ba" + string uid = 20; + + // Name represents the name for the workload. + // For Kubernetes, this is the pod name. + // This is just for debugging and may be elided as an optimization. + string name = 1; + + // Namespace represents the namespace for the workload. + // This is just for debugging and may be elided as an optimization. + string namespace = 2; + + // Address represents the IPv4/IPv6 address for the workload. + // This should be globally unique. + // This should not have a port number. + // Each workload must have at least either an address or hostname; not both. + repeated bytes addresses = 3; + + // The hostname for the workload to be resolved by the ztunnel. + // DNS queries are sent on-demand by default. + // If the resolved DNS query has several endpoints, the request will be forwarded + // to the first response. + // + // At a minimum, each workload must have either an address or hostname. For example, + // a workload that backs a Kubernetes service will typically have only endpoints. A + // workload that backs a headless Kubernetes service, however, will have both + // addresses as well as a hostname used for direct access to the headless endpoint. + string hostname = 21; + + // Network represents the network this workload is on. This may be elided for the default network. + // A (network,address) pair makeup a unique key for a workload *at a point in time*. + string network = 4; + + // Protocol that should be used to connect to this workload. + TunnelProtocol tunnel_protocol = 5; + + // The SPIFFE identity of the workload. The identity is joined to form spiffe:///ns//sa/. + // TrustDomain of the workload. May be elided if this is the mesh wide default (typically cluster.local) + string trust_domain = 6; + + // ServiceAccount of the workload. May be elided if this is "default" + string service_account = 7; + + // If present, the waypoint proxy for this workload. + // All incoming requests must go through the waypoint. + GatewayAddress waypoint = 8; + + // If present, East West network gateway this workload can be reached through. + // Requests from remote networks should traverse this gateway. + GatewayAddress network_gateway = 19; + + // Name of the node the workload runs on + string node = 9; + + // CanonicalName for the workload. Used for telemetry. + string canonical_name = 10; + + // CanonicalRevision for the workload. Used for telemetry. + string canonical_revision = 11; + + // WorkloadType represents the type of the workload. Used for telemetry. + WorkloadType workload_type = 12; + + // WorkloadName represents the name for the workload (of type WorkloadType). Used for telemetry. + string workload_name = 13; + + // If set, this indicates a workload expects to directly receive tunnel traffic. + // In ztunnel, this means: + // * Requests *from* this workload do not need to be tunneled if they already are tunneled by the tunnel_protocol. + // * Requests *to* this workload, via the tunnel_protocol, do not need to be de-tunneled. + bool native_tunnel = 14; + + // If an application, such as a sandwiched waypoint proxy, supports directly + // receiving information from zTunnel they can set application_protocol. + ApplicationTunnel application_tunnel = 23; + + // The services for which this workload is an endpoint. + // The key is the NamespacedHostname string of the format namespace/hostname. + map services = 22; + + // A list of authorization policies applicable to this workload. + // NOTE: this *only* includes Selector based policies. Namespace and global polices + // are returned out of band. + // Authorization policies are only valid for workloads with ``addresses`` rather than ``hostname``. + repeated string authorization_policies = 16; + + WorkloadStatus status = 17; + + // The cluster ID that the workload instance belongs to + string cluster_id = 18; + + // The Locality defines information about where a workload is geographically deployed + Locality locality = 24; + + NetworkMode network_mode = 25; +} + +message Locality { + string region = 1; + + string zone = 2; + + string subzone = 3; +} + +// This represents the ports for a service +message PortList { + repeated Port ports = 1; +} + +message Port { + // Port the service is reached at (frontend). + uint32 service_port = 1; + + // Port the service forwards to (backend). + uint32 target_port = 2; +} + +// ApplicationProtocol specifies a workload (application or gateway) can +// consume tunnel information. +message ApplicationTunnel { + enum Protocol { + // Bytes are copied from the inner stream without modification. + NONE = 0; + + // Prepend PROXY protocol headers before copying bytes + // Standard PROXY source and destination information + // is included, along with potential extra TLV headers: + // 0xD0 - The SPIFFE identity of the source workload + // 0xD1 - The FQDN or Hostname of the targeted Service + PROXY = 1; + } + + // A target natively handles this type of traffic. + Protocol protocol = 1; + + // optional: if set, traffic should be sent to this port after the last zTunnel hop + uint32 port = 2; +} + +// GatewayAddress represents the address of a gateway +message GatewayAddress { + reserved 4; + + reserved "hbone_single_tls_port"; + + // address can either be a hostname (ex: gateway.example.com) or an IP (ex: 1.2.3.4). + oneof destination { + // TODO: add support for hostname lookup + NamespacedHostname hostname = 1; + + NetworkAddress address = 2; + } + + // port to reach the gateway at for mTLS HBONE connections + uint32 hbone_mtls_port = 3; +} + +// NetworkAddress represents an address bound to a specific network. +message NetworkAddress { + // Network represents the network this address is on. + string network = 1; + + // Address presents the IP (v4 or v6). + bytes address = 2; +} + +// NamespacedHostname represents a service bound to a specific namespace. +message NamespacedHostname { + // The namespace the service is in. + string namespace = 1; + + // hostname (ex: gateway.example.com) + string hostname = 2; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/common/workload_discovery/v3/extension.proto b/src/main/proto/contrib/envoy/extensions/filters/common/workload_discovery/v3/extension.proto new file mode 100644 index 0000000..1b6c114 --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/common/workload_discovery/v3/extension.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package istio.workload; + +import "envoy/config/core/v3/config_source.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.istio.workload"; +option java_outer_classname = "ExtensionProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/istio/workload"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +message BootstrapExtension { + envoy.config.core.v3.ConfigSource config_source = 1; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/http/alpn/v3/alpn.proto b/src/main/proto/contrib/envoy/extensions/filters/http/alpn/v3/alpn.proto new file mode 100644 index 0000000..bb3ec50 --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/http/alpn/v3/alpn.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package istio.envoy.config.filter.http.alpn.v2alpha1; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.istio.envoy.config.filter.http.alpn.v2alpha1"; +option java_outer_classname = "AlpnProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/istio/envoy/config/filter/http/alpn/v2alpha1"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: ALPN HTTP filter] +// +// ALPN HTTP filter from Istio. +// +// [#extension: envoy.filters.http.alpn] + +// FilterConfig is the config for Istio-specific filter. +message FilterConfig { + // Upstream protocols + enum Protocol { + HTTP10 = 0; + HTTP11 = 1; + HTTP2 = 2; + } + + message AlpnOverride { + // Upstream protocol + Protocol upstream_protocol = 1; + + // A list of ALPN that will override the ALPN for upstream TLS connections. + repeated string alpn_override = 2; + } + + // Map from upstream protocol to list of ALPN + repeated AlpnOverride alpn_override = 1; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/http/istio_stats/v3/istio_stats.proto b/src/main/proto/contrib/envoy/extensions/filters/http/istio_stats/v3/istio_stats.proto new file mode 100644 index 0000000..27c528d --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/http/istio_stats/v3/istio_stats.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; + +package stats; + +import "google/protobuf/duration.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.stats"; +option java_outer_classname = "IstioStatsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/stats"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Istio stats HTTP filter] +// +// Istio stats HTTP filter for collecting and reporting metrics. +// [#extension: envoy.filters.http.istio_stats] + +enum MetricType { + COUNTER = 0; + GAUGE = 1; + HISTOGRAM = 2; +} + +// Specifies the proxy deployment type. +enum Reporter { + // Default value is inferred from the listener direction, as either client or + // server sidecar. + UNSPECIFIED = 0; + + // Shared server gateway, e.g. "waypoint". + SERVER_GATEWAY = 1; +} + +// Metric instance configuration overrides. +// The metric value and the metric type are optional and permit changing the +// reported value for an existing metric. +// The standard metrics are optimized and reported through a "fast-path". +// The customizations allow full configurability, at the cost of a "slower" +// path. +// [#next-free-field: 6] +message MetricConfig { + // (Optional) Collection of tag names and tag expressions to include in the + // metric. Conflicts are resolved by the tag name by overriding previously + // supplied values. + map dimensions = 1; + + // (Optional) Metric name to restrict the override to a metric. If not + // specified, applies to all. + string name = 2; + + // (Optional) A list of tags to remove. + repeated string tags_to_remove = 3; + + // NOT IMPLEMENTED. (Optional) Conditional enabling the override. + string match = 4; + + // (Optional) If this is set to true, the metric(s) selected by this + // configuration will not be generated or reported. + bool drop = 5; +} + +message MetricDefinition { + // Metric name. + string name = 1; + + // Metric value expression. + string value = 2; + + // Metric type. + MetricType type = 3; +} + +// [#next-free-field: 13] +message PluginConfig { + reserved 1, 2, 3, 4, 5; + + reserved "debug", "max_peer_cache_size", "stat_prefix", "field_separator", "value_separator"; + + // Optional: Disable using host header as a fallback if destination service is + // not available from the control plane. Disable the fallback if the host + // header originates outsides the mesh, like at ingress. + bool disable_host_header_fallback = 6; + + // Optional. Allows configuration of the time between calls out to for TCP + // metrics reporting. The default duration is ``5s``. + google.protobuf.Duration tcp_reporting_duration = 7; + + // Metric overrides. + repeated MetricConfig metrics = 8; + + // Metric definitions. + repeated MetricDefinition definitions = 9; + + // Proxy deployment type. + Reporter reporter = 10; + + // Metric scope rotation interval. Set to 0 to disable the metric scope rotation. + // Defaults to 0. + // DEPRECATED. + google.protobuf.Duration rotation_interval = 11; + + // Metric expiry graceful deletion interval. No-op if the metric rotation is disabled. + // Defaults to 5m. Must be >=1s. + // DEPRECATED. + google.protobuf.Duration graceful_deletion_interval = 12; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/http/peak_ewma/v3alpha/peak_ewma.proto b/src/main/proto/contrib/envoy/extensions/filters/http/peak_ewma/v3alpha/peak_ewma.proto new file mode 100644 index 0000000..4c989b9 --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/http/peak_ewma/v3alpha/peak_ewma.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.peak_ewma.v3alpha; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.peak_ewma.v3alpha"; +option java_outer_classname = "PeakEwmaProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/http/peak_ewma/v3alpha"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: Peak EWMA HTTP Filter] +// Configuration for the Peak EWMA HTTP filter. +// This filter measures request RTT and provides timing data to the Peak EWMA load balancer. + +// [#extension: envoy.filters.http.peak_ewma] +message PeakEwmaConfig { + option (xds.annotations.v3.message_status).work_in_progress = true; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/http/peer_metadata/v3/peer_metadata.proto b/src/main/proto/contrib/envoy/extensions/filters/http/peer_metadata/v3/peer_metadata.proto new file mode 100644 index 0000000..099daf2 --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/http/peer_metadata/v3/peer_metadata.proto @@ -0,0 +1,83 @@ +syntax = "proto3"; + +package io.istio.http.peer_metadata; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.io.istio.http.peer_metadata"; +option java_outer_classname = "PeerMetadataProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/io/istio/http/peer_metadata"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Peer metadata HTTP filter] +// +// Peer metadata HTTP filter for deriving and propagating peer telemetry attributes. +// [#extension: envoy.filters.http.peer_metadata] + +// Peer metadata provider filter. This filter encapsulates the discovery of the +// peer telemetry attributes for consumption by the telemetry filters. +// [#next-free-field: 7] +message Config { + // DEPRECATED. + // This method uses ``baggage`` header encoding. + message Baggage { + } + + // This method uses the workload metadata xDS. Requires that the bootstrap extension is enabled. + // For downstream discovery, the remote address is the lookup key in xDS. + // For upstream discovery: + // + // * If the upstream host address is an IP, this IP is used as the lookup key; + // * If the upstream host address is internal, uses the + // ``filter_metadata.tunnel.destination`` dynamic metadata value as the lookup key. + // + message WorkloadDiscovery { + } + + // This method uses Istio HTTP metadata exchange headers, e.g. ``x-envoy-peer-metadata``. Removes these headers if found. + message IstioHeaders { + // Strip ``x-envoy-peer-metadata`` and ``x-envoy-peer-metadata-id`` headers on HTTP requests to services outside the mesh. + // Detects upstream clusters with ``istio`` and ``external`` filter metadata fields + bool skip_external_clusters = 1; + } + + // An exhaustive list of the derivation methods. + message DiscoveryMethod { + oneof method_specifier { + Baggage baggage = 1; + + WorkloadDiscovery workload_discovery = 2; + + IstioHeaders istio_headers = 3; + } + } + + // An exhaustive list of the metadata propagation methods. + message PropagationMethod { + oneof method_specifier { + IstioHeaders istio_headers = 1; + } + } + + // The order of the derivation of the downstream peer metadata, in the precedence order. + // First successful lookup wins. + repeated DiscoveryMethod downstream_discovery = 1; + + // The order of the derivation of the upstream peer metadata, in the precedence order. + // First successful lookup wins. + repeated DiscoveryMethod upstream_discovery = 2; + + // Downstream injection of the metadata via a response header. + repeated PropagationMethod downstream_propagation = 3; + + // Upstream injection of the metadata via a request header. + repeated PropagationMethod upstream_propagation = 4; + + // True to enable sharing with the upstream. + bool shared_with_upstream = 5; + + // Additional labels to be added to the peer metadata to help your understand the traffic. + // e.g. ``role``, ``location`` etc. + repeated string additional_labels = 6; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/listener/postgres_inspector/v3alpha/postgres_inspector.proto b/src/main/proto/contrib/envoy/extensions/filters/listener/postgres_inspector/v3alpha/postgres_inspector.proto new file mode 100644 index 0000000..6063d3c --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/listener/postgres_inspector/v3alpha/postgres_inspector.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; + +package envoy.extensions.filters.listener.postgres_inspector.v3alpha; + +import "google/protobuf/duration.proto"; +import "google/protobuf/wrappers.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.listener.postgres_inspector.v3alpha"; +option java_outer_classname = "PostgresInspectorProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/listener/postgres_inspector/v3alpha"; +option (udpa.annotations.file_status).work_in_progress = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Postgres Inspector] +// Postgres Inspector :ref:`configuration overview `. +// [#extension: envoy.filters.listener.postgres_inspector] + +message PostgresInspector { + // Enable extraction of connection metadata (user, database, application name) from + // the startup message. This metadata is made available for access logging and stats. + // + // Defaults to ``true``. + google.protobuf.BoolValue enable_metadata_extraction = 1; + + // The maximum size of the startup message that the postgres inspector will accept. + // Messages larger than this will be rejected. If not specified, defaults to 10KB. + // + // PostgreSQL defines MAX_STARTUP_PACKET_LENGTH as 10KB. + // Valid range is 256 bytes to 10KB. + google.protobuf.UInt32Value max_startup_message_size = 2 + [(validate.rules).uint32 = {lte: 10000 gte: 256}]; + + // Timeout for the inspector to receive and process the startup message. + // The timeout starts when the connection is accepted by the listener. + // If the timeout is reached before the startup message is fully received and processed, + // the connection will be closed. + // + // If not specified, defaults to 10 seconds. Minimum is 1 second. + google.protobuf.Duration startup_timeout = 3 [(validate.rules).duration = {gte {seconds: 1}}]; +} + +// StartupMetadata stores connection attributes extracted from the PostgreSQL startup message. +// This is attached as typed dynamic metadata under the key ``envoy.postgres_inspector``. +message StartupMetadata { + // The username supplied in the startup message. + string user = 1; + + // The database name supplied in the startup message. If not provided, it may default to the user name. + string database = 2; + + // The application name supplied in the startup message. + string application_name = 3; +} diff --git a/src/main/proto/contrib/envoy/extensions/filters/network/metadata_exchange/v3/metadata_exchange.proto b/src/main/proto/contrib/envoy/extensions/filters/network/metadata_exchange/v3/metadata_exchange.proto new file mode 100644 index 0000000..2eb8171 --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/filters/network/metadata_exchange/v3/metadata_exchange.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package envoy.tcp.metadataexchange.config; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.tcp.metadataexchange.config"; +option java_outer_classname = "MetadataExchangeProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/tcp/metadataexchange/config"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Metadata exchange TCP filter] +// +// Metadata exchange TCP filter for deriving and propagating peer telemetry attributes. +// [#extension: envoy.filters.network.metadata_exchange] + +// [#protodoc-title: MetadataExchange protocol match and data transfer] +// MetadataExchange protocol match and data transfer +message MetadataExchange { + // Protocol that Alpn should support on the server. + // [#comment:TODO(GargNupur): Make it a list.] + string protocol = 1; + + // If true, will attempt to use WDS in case the prefix peer metadata is not available. + bool enable_discovery = 2; + + // Additional labels to be added to the peer metadata to help your understand the traffic. + // e.g. ``role``, ``location`` etc. + repeated string additional_labels = 3; +} diff --git a/src/main/proto/contrib/envoy/extensions/load_balancing_policies/peak_ewma/v3alpha/peak_ewma.proto b/src/main/proto/contrib/envoy/extensions/load_balancing_policies/peak_ewma/v3alpha/peak_ewma.proto new file mode 100644 index 0000000..09886bd --- /dev/null +++ b/src/main/proto/contrib/envoy/extensions/load_balancing_policies/peak_ewma/v3alpha/peak_ewma.proto @@ -0,0 +1,100 @@ +syntax = "proto3"; + +package envoy.extensions.load_balancing_policies.peak_ewma.v3alpha; + +import "google/protobuf/duration.proto"; +import "google/protobuf/wrappers.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.load_balancing_policies.peak_ewma.v3alpha"; +option java_outer_classname = "PeakEwmaProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/load_balancing_policies/peak_ewma/v3alpha"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: Peak EWMA Load Balancer Configuration] +// Configuration for the Peak EWMA (Exponentially Weighted Moving Average) load balancing policy. +// +// This policy implements a latency-aware variant of the Power of Two Choices (P2C) algorithm. +// It selects the best host from two randomly chosen candidates based on a cost function: +// `Cost = RTT_peak_ewma * (active_requests + 1)`. +// +// The Peak EWMA algorithm is designed to: +// - Automatically route traffic away from slow or overloaded hosts +// - Adapt to changing host performance without manual configuration +// - Provide low-latency request routing with O(1) host selection complexity +// - Work effectively in heterogeneous environments with varying host capabilities +// +// RTT measurements are automatically collected from HTTP request timing and used to update +// the EWMA for each host. This provides real-time performance feedback for routing decisions. +// +// Important: This load balancer only considers latency and load when selecting hosts. It does +// not handle host health or error responses - these should be managed by Envoy's health checking +// and outlier detection systems. Peak EWMA operates on the pool of healthy hosts as determined +// by these other systems. +// +// [#extension: envoy.load_balancing_policies.peak_ewma] +// [#next-free-field: 6] +message PeakEwma { + option (xds.annotations.v3.message_status).work_in_progress = true; + + // The decay time for the RTT EWMA calculation. This specifies the time window over which + // latency observations are considered relevant. After this duration, older measurements + // have exponentially decayed to half their original weight. + // + // The Peak EWMA algorithm uses this to calculate the EWMA time constant (tau): + // `tau = decay_time_nanos`, and the EWMA reaches its half-life after `tau * ln(2)`. + // + // This parameter is more intuitive than a raw smoothing factor as it directly relates + // to the time duration over which you want to observe latency trends. + // + // If not specified, defaults to 10 seconds (following Finagle's default). + google.protobuf.Duration decay_time = 1; + + // The interval at which EWMA data is aggregated from worker threads to the main thread. + // This controls the frequency of cross-thread synchronization for the per-thread aggregation model. + // + // A shorter interval provides more up-to-date cross-worker information but increases + // synchronization overhead. A longer interval reduces overhead but may cause workers + // to operate with staler information about other workers' latency observations. + // + // If not specified, defaults to 100 milliseconds. + google.protobuf.Duration aggregation_interval = 2; + + // Maximum RTT samples to buffer per host per worker thread before overwriting oldest samples. + // This bounds memory usage while allowing burst traffic handling. + // + // Buffer capacity formula: max_samples_per_host / aggregation_interval = RPS capacity per host per worker + // Memory formula: max_samples_per_host × num_hosts × num_workers × 16 bytes + // Memory usage per worker = max_samples_per_host × num_hosts × 16 bytes + // + // If not specified, defaults to 1,000 samples per host per worker. + google.protobuf.UInt32Value max_samples_per_host = 3; + + // Default RTT value to use for hosts that don't have measured RTT yet. + // This provides a baseline for cost calculations until actual measurements are available. + // + // This value is critical for initial load balancing decisions when hosts first join + // the cluster or when RTT measurements are temporarily unavailable. It should reflect + // the expected baseline latency for your environment: + // + // If not specified, defaults to 10 milliseconds. + google.protobuf.Duration default_rtt = 4; + + // Penalty cost assigned to hosts that cannot provide valid cost calculations. + // This is used when a host has no RTT measurements or is unhealthy, ensuring + // the Power of Two Choices algorithm will prefer hosts with known performance. + // + // You probably should not change this value. + // + // The penalty should be significantly higher than any realistic RTT-based cost + // to ensure hosts with unknown performance are strongly deprioritized while + // still allowing them to receive traffic if no better alternatives exist. + // + // If not specified, defaults to 1,000,000.0 (1 million). + google.protobuf.DoubleValue penalty_value = 5; +} diff --git a/src/main/proto/contrib/envoy/extensions/network/connection_balance/dlb/v3alpha/dlb.proto b/src/main/proto/contrib/envoy/extensions/network/connection_balance/dlb/v3alpha/dlb.proto index 234a9f9..71a17ca 100644 --- a/src/main/proto/contrib/envoy/extensions/network/connection_balance/dlb/v3alpha/dlb.proto +++ b/src/main/proto/contrib/envoy/extensions/network/connection_balance/dlb/v3alpha/dlb.proto @@ -13,6 +13,15 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Dlb connection balancer configuration] // DLB :ref:`configuration overview `. // [#extension: envoy.network.connection_balance.dlb] +// [#not-implemented-hide:] +// +// The envoy.network.connection_balance.dlb extension is currently disabled +// at the Bazel layer — see https://github.com/envoyproxy/envoy/issues/45491. +// The ``[#not-implemented-hide:]`` annotation above suppresses docs +// generation for this file so protodoc does not try to look the extension +// up in extensions_metadata.yaml (which has been removed in lockstep with +// the ``contrib_build_config.bzl`` entry). Drop the annotation when the +// upstream ``@dlb`` mirror is healthy again. // The Dlb is a hardware managed system of queues and arbiters connecting producers and consumers. It is a PCIE device // in the CPU package. It interacts with software running on cores and potentially other devices. The Dlb implements the diff --git a/src/main/proto/envoy/admin/v3/server_info.proto b/src/main/proto/envoy/admin/v3/server_info.proto index adf5ab4..6614ce4 100644 --- a/src/main/proto/envoy/admin/v3/server_info.proto +++ b/src/main/proto/envoy/admin/v3/server_info.proto @@ -59,7 +59,7 @@ message ServerInfo { config.core.v3.Node node = 7; } -// [#next-free-field: 42] +// [#next-free-field: 43] message CommandLineOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.admin.v2alpha.CommandLineOptions"; @@ -161,6 +161,9 @@ message CommandLineOptions { // See :option:`--file-flush-interval-msec` for details. google.protobuf.Duration file_flush_interval = 16; + // See :option:`--file-flush-min-size-kb` for details. + uint32 file_flush_min_size = 42; + // See :option:`--drain-time-s` for details. google.protobuf.Duration drain_time = 17; diff --git a/src/main/proto/envoy/config/accesslog/v3/accesslog.proto b/src/main/proto/envoy/config/accesslog/v3/accesslog.proto index 6753ab6..f273f2e 100644 --- a/src/main/proto/envoy/config/accesslog/v3/accesslog.proto +++ b/src/main/proto/envoy/config/accesslog/v3/accesslog.proto @@ -108,6 +108,9 @@ message ComparisonFilter { // <= LE = 2; + + // != + NE = 3; } // Comparison operator. diff --git a/src/main/proto/envoy/config/bootstrap/v3/bootstrap.proto b/src/main/proto/envoy/config/bootstrap/v3/bootstrap.proto index bf65f3d..7b862c1 100644 --- a/src/main/proto/envoy/config/bootstrap/v3/bootstrap.proto +++ b/src/main/proto/envoy/config/bootstrap/v3/bootstrap.proto @@ -16,6 +16,7 @@ import "envoy/config/metrics/v3/stats.proto"; import "envoy/config/overload/v3/overload.proto"; import "envoy/config/trace/v3/http_tracer.proto"; import "envoy/extensions/transport_sockets/tls/v3/secret.proto"; +import "envoy/type/matcher/v3/string.proto"; import "envoy/type/v3/percent.proto"; import "google/protobuf/duration.proto"; @@ -41,7 +42,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // ` for more detail. // Bootstrap :ref:`configuration overview `. -// [#next-free-field: 42] +// [#next-free-field: 43] message Bootstrap { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Bootstrap"; @@ -76,7 +77,7 @@ message Bootstrap { // :ref:`LDS ` configuration source. core.v3.ConfigSource lds_config = 1; - // xdstp:// resource locator for listener collection. + // ``xdstp://`` resource locator for listener collection. // [#not-implemented-hide:] string lds_resources_locator = 5; @@ -85,7 +86,7 @@ message Bootstrap { // configuration source. core.v3.ConfigSource cds_config = 2; - // xdstp:// resource locator for cluster collection. + // ``xdstp://`` resource locator for cluster collection. // [#not-implemented-hide:] string cds_resources_locator = 6; @@ -126,17 +127,19 @@ message Bootstrap { // When the flag is enabled, Envoy will lazily initialize a subset of the stats (see below). // This will save memory and CPU cycles when creating the objects that own these stats, if those // stats are never referenced throughout the lifetime of the process. However, it will incur additional - // memory overhead for these objects, and a small increase of CPU usage when a at least one of the stats + // memory overhead for these objects, and a small increase of CPU usage when at least one of the stats // is updated for the first time. + // // Groups of stats that will be lazily initialized: + // // - Cluster traffic stats: a subgroup of the :ref:`cluster statistics ` - // that are used when requests are routed to the cluster. + // that are used when requests are routed to the cluster. bool enable_deferred_creation_stats = 1; } message GrpcAsyncClientManagerConfig { // Optional field to set the expiration time for the cached gRPC client object. - // The minimal value is 5s and the default is 50s. + // The minimal value is ``5s`` and the default is ``50s``. google.protobuf.Duration max_cached_entry_idle_duration = 1 [(validate.rules).duration = {gte {seconds: 5}}]; } @@ -151,25 +154,25 @@ message Bootstrap { // A list of :ref:`Node ` field names // that will be included in the context parameters of the effective - // xdstp:// URL that is sent in a discovery request when resource + // ``xdstp://`` URL that is sent in a discovery request when resource // locators are used for LDS/CDS. Any non-string field will have its JSON // encoding set as the context parameter value, with the exception of // metadata, which will be flattened (see example below). The supported field // names are: - // - "cluster" - // - "id" - // - "locality.region" - // - "locality.sub_zone" - // - "locality.zone" - // - "metadata" - // - "user_agent_build_version.metadata" - // - "user_agent_build_version.version" - // - "user_agent_name" - // - "user_agent_version" + // - ``cluster`` + // - ``id`` + // - ``locality.region`` + // - ``locality.sub_zone`` + // - ``locality.zone`` + // - ``metadata`` + // - ``user_agent_build_version.metadata`` + // - ``user_agent_build_version.version`` + // - ``user_agent_name`` + // - ``user_agent_version`` // // The node context parameters act as a base layer dictionary for the context // parameters (i.e. more specific resource specific context parameters will - // override). Field names will be prefixed with “udpa.node.” when included in + // override). Field names will be prefixed with ````"udpa.node."```` when included in // context parameters. // // For example, if node_context_params is ``["user_agent_name", "metadata"]``, @@ -211,10 +214,10 @@ message Bootstrap { // Optional duration between flushes to configured stats sinks. For // performance reasons Envoy latches counters and only flushes counters and - // gauges at a periodic interval. If not specified the default is 5000ms (5 - // seconds). Only one of ``stats_flush_interval`` or ``stats_flush_on_admin`` + // gauges at a periodic interval. If not specified the default is ``5000ms`` (``5`` seconds). + // Only one of ``stats_flush_interval`` or ``stats_flush_on_admin`` // can be set. - // Duration must be at least 1ms and at most 5 min. + // Duration must be at least ``1ms`` and at most ``5 min``. google.protobuf.Duration stats_flush_interval = 7 [ (validate.rules).duration = { lt {seconds: 300} @@ -230,6 +233,14 @@ message Bootstrap { bool stats_flush_on_admin = 29 [(validate.rules).bool = {const: true}]; } + oneof stats_eviction { + // Optional duration to perform metric eviction. At every interval, during the stats flush + // the unused metrics are removed from the worker caches and the used metrics + // are marked as unused. Must be a multiple of the ``stats_flush_interval``. + google.protobuf.Duration stats_eviction_interval = 42 + [(validate.rules).duration = {gte {nanos: 1000000}}]; + } + // Optional watchdog configuration. // This is for a single watchdog configuration for the entire system. // Deprecated in favor of ``watchdogs`` which has finer granularity. @@ -263,23 +274,28 @@ message Bootstrap { (udpa.annotations.security).configure_for_untrusted_upstream = true ]; - // Enable :ref:`stats for event dispatcher `, defaults to false. - // Note that this records a value for each iteration of the event loop on every thread. This - // should normally be minimal overhead, but when using - // :ref:`statsd `, it will send each observed value - // over the wire individually because the statsd protocol doesn't have any way to represent a - // histogram summary. Be aware that this can be a very large volume of data. + // Enable :ref:`stats for event dispatcher `. Defaults to ``false``. + // + // .. note:: + // + // This records a value for each iteration of the event loop on every thread. This + // should normally be minimal overhead, but when using + // :ref:`statsd `, it will send each observed value + // over the wire individually because the statsd protocol doesn't have any way to represent a + // histogram summary. Be aware that this can be a very large volume of data. bool enable_dispatcher_stats = 16; - // Optional string which will be used in lieu of x-envoy in prefixing headers. + // Optional string which will be used in lieu of ``x-envoy`` in prefixing headers. // - // For example, if this string is present and set to X-Foo, then x-envoy-retry-on will be - // transformed into x-foo-retry-on etc. + // For example, if this string is present and set to ``X-Foo``, then ``x-envoy-retry-on`` will be + // transformed into ``x-foo-retry-on`` etc. // - // Note this applies to the headers Envoy will generate, the headers Envoy will sanitize, and the - // headers Envoy will trust for core code and core extensions only. Be VERY careful making - // changes to this string, especially in multi-layer Envoy deployments or deployments using - // extensions which are not upstream. + // .. note:: + // + // This applies to the headers Envoy will generate, the headers Envoy will sanitize, and the + // headers Envoy will trust for core code and core extensions only. Be VERY careful making + // changes to this string, especially in multi-layer Envoy deployments or deployments using + // extensions which are not upstream. string header_prefix = 18; // Optional proxy version which will be used to set the value of :ref:`server.version statistic @@ -287,8 +303,8 @@ message Bootstrap { // :ref:`stats sinks `. google.protobuf.UInt64Value stats_server_version_override = 19; - // Always use TCP queries instead of UDP queries for DNS lookups. - // This may be overridden on a per-cluster basis in cds_config, + // Always use ``TCP`` queries instead of ``UDP`` queries for DNS lookups. + // This may be overridden on a per-cluster basis in ``cds_config``, // when :ref:`dns_resolvers ` and // :ref:`use_tcp_for_dns_lookups ` are // specified. @@ -297,8 +313,8 @@ message Bootstrap { bool use_tcp_for_dns_lookups = 20 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // DNS resolution configuration which includes the underlying dns resolver addresses and options. - // This may be overridden on a per-cluster basis in cds_config, when + // DNS resolution configuration which includes the underlying DNS resolver addresses and options. + // This may be overridden on a per-cluster basis in ``cds_config``, when // :ref:`dns_resolution_config ` // is specified. // This field is deprecated in favor of @@ -306,14 +322,15 @@ message Bootstrap { core.v3.DnsResolutionConfig dns_resolution_config = 30 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // DNS resolver type configuration extension. This extension can be used to configure c-ares, apple, + // DNS resolver type configuration extension. This extension can be used to configure ``c-ares``, ``apple``, // or any other DNS resolver types and the related parameters. // For example, an object of // :ref:`CaresDnsResolverConfig ` // can be packed into this ``typed_dns_resolver_config``. This configuration replaces the // :ref:`dns_resolution_config ` // configuration. - // During the transition period when both ``dns_resolution_config`` and ``typed_dns_resolver_config`` exists, + // + // During the transition period when both ``dns_resolution_config`` and ``typed_dns_resolver_config`` exist, // when ``typed_dns_resolver_config`` is in place, Envoy will use it and ignore ``dns_resolution_config``. // When ``typed_dns_resolver_config`` is missing, the default behavior is in place. // [#extension-category: envoy.network.dns_resolver] @@ -329,9 +346,10 @@ message Bootstrap { repeated FatalAction fatal_actions = 28; // Configuration sources that will participate in - // xdstp:// URL authority resolution. The algorithm is as + // ``xdstp://`` URL authority resolution. The algorithm is as // follows: - // 1. The authority field is taken from the xdstp:// URL, call + // + // 1. The authority field is taken from the ``xdstp://`` URL, call // this ``resource_authority``. // 2. ``resource_authority`` is compared against the authorities in any peer // ``ConfigSource``. The peer ``ConfigSource`` is the configuration source @@ -347,7 +365,7 @@ message Bootstrap { // [#not-implemented-hide:] repeated core.v3.ConfigSource config_sources = 22; - // Default configuration source for xdstp:// URLs if all + // Default configuration source for ``xdstp://`` URLs if all // other resolution fails. // [#not-implemented-hide:] core.v3.ConfigSource default_config_source = 23; @@ -367,28 +385,30 @@ message Bootstrap { // allows users to customize the inline headers on-demand at Envoy startup without modifying // Envoy's source code. // - // Note that the 'set-cookie' header cannot be registered as inline header. + // .. note:: + // + // The ``set-cookie`` header cannot be registered as inline header. repeated CustomInlineHeader inline_headers = 32; - // Optional path to a file with performance tracing data created by "Perfetto" SDK in binary - // ProtoBuf format. The default value is "envoy.pftrace". + // Optional path to a file with performance tracing data created by ``Perfetto`` SDK in binary + // ProtoBuf format. The default value is ``envoy.pftrace``. string perf_tracing_file_path = 33; // Optional overriding of default regex engine. - // If the value is not specified, Google RE2 will be used by default. + // If the value is not specified, ``Google RE2`` will be used by default. // [#extension-category: envoy.regex_engines] core.v3.TypedExtensionConfig default_regex_engine = 34; // Optional XdsResourcesDelegate configuration, which allows plugging custom logic into both // fetch and load events during xDS processing. - // If a value is not specified, no XdsResourcesDelegate will be used. + // If a value is not specified, no ``XdsResourcesDelegate`` will be used. // TODO(abeyad): Add public-facing documentation. // [#not-implemented-hide:] core.v3.TypedExtensionConfig xds_delegate_extension = 35; // Optional XdsConfigTracker configuration, which allows tracking xDS responses in external components, // e.g., external tracer or monitor. It provides the process point when receive, ingest, or fail to - // process xDS resources and messages. If a value is not specified, no XdsConfigTracker will be used. + // process xDS resources and messages. If a value is not specified, no ``XdsConfigTracker`` will be used. // // .. note:: // @@ -400,14 +420,14 @@ message Bootstrap { // [#not-implemented-hide:] // This controls the type of listener manager configured for Envoy. Currently - // Envoy only supports ListenerManager for this field and Envoy Mobile - // supports ApiListenerManager. + // Envoy only supports ``ListenerManager`` for this field and Envoy Mobile + // supports ``ApiListenerManager``. core.v3.TypedExtensionConfig listener_manager = 37; // Optional application log configuration. ApplicationLogConfig application_log_config = 38; - // Optional gRPC async manager config. + // Optional gRPC async client manager config. GrpcAsyncClientManagerConfig grpc_async_client_manager_config = 40; // Optional configuration for memory allocation manager. @@ -417,7 +437,7 @@ message Bootstrap { // Administration interface :ref:`operations documentation // `. -// [#next-free-field: 7] +// [#next-free-field: 8] message Admin { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Admin"; @@ -426,14 +446,14 @@ message Admin { repeated accesslog.v3.AccessLog access_log = 5; // The path to write the access log for the administration server. If no - // access log is desired specify ‘/dev/null’. This is only required if + // access log is desired specify ``/dev/null``. This is only required if // :ref:`address ` is set. // Deprecated in favor of ``access_log`` which offers more options. string access_log_path = 1 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // The cpu profiler output path for the administration server. If no profile - // path is specified, the default is ‘/var/log/envoy/envoy.prof’. + // The CPU profiler output path for the administration server. If no profile + // path is specified, the default is ``/var/log/envoy/envoy.prof``. string profile_path = 2; // The TCP address that the administration server will listen on. @@ -447,6 +467,21 @@ message Admin { // Indicates whether :ref:`global_downstream_max_connections ` // should apply to the admin interface or not. bool ignore_global_conn_limit = 6; + + // List of admin paths that are accessible. If not specified, all admin endpoints are accessible. + // + // When specified, only paths in this list will be accessible, all others will return ``HTTP 403 Forbidden``. + // + // Example: + // + // .. code-block:: yaml + // + // allow_paths: + // - exact: /stats + // - exact: /ready + // - prefix: /healthcheck + // + repeated type.matcher.v3.StringMatcher allow_paths = 7; } // Cluster manager :ref:`architecture overview `. @@ -483,7 +518,7 @@ message ClusterManager { OutlierDetection outlier_detection = 2; // Optional configuration used to bind newly established upstream connections. - // This may be overridden on a per-cluster basis by upstream_bind_config in the cds_config. + // This may be overridden on a per-cluster basis by ``upstream_bind_config`` in the ``cds_config``. core.v3.BindConfig upstream_bind_config = 3; // A management server endpoint to stream load stats to via @@ -494,7 +529,7 @@ message ClusterManager { // Whether the ClusterManager will create clusters on the worker threads // inline during requests. This will save memory and CPU cycles in cases where - // there are lots of inactive clusters and > 1 worker thread. + // there are lots of inactive clusters and ``> 1`` worker thread. bool enable_deferred_cluster_creation = 5; } @@ -517,12 +552,12 @@ message Watchdog { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Watchdog"; message WatchdogAction { - // The events are fired in this order: KILL, MULTIKILL, MEGAMISS, MISS. + // The events are fired in this order: ``KILL``, ``MULTIKILL``, ``MEGAMISS``, ``MISS``. // Within an event type, actions execute in the order they are configured. - // For KILL/MULTIKILL there is a default PANIC that will run after the + // For ``KILL``/``MULTIKILL`` there is a default ``PANIC`` that will run after the // registered actions and kills the process if it wasn't already killed. // It might be useful to specify several debug actions, and possibly an - // alternate FATAL action. + // alternate ``FATAL`` action. enum WatchdogEvent { UNKNOWN = 0; KILL = 1; @@ -537,46 +572,48 @@ message Watchdog { WatchdogEvent event = 2 [(validate.rules).enum = {defined_only: true}]; } - // Register actions that will fire on given WatchDog events. - // See ``WatchDogAction`` for priority of events. + // Register actions that will fire on given Watchdog events. + // See ``WatchdogAction`` for priority of events. repeated WatchdogAction actions = 7; // The duration after which Envoy counts a nonresponsive thread in the - // ``watchdog_miss`` statistic. If not specified the default is 200ms. + // ``watchdog_miss`` statistic. If not specified the default is ``200ms``. google.protobuf.Duration miss_timeout = 1; // The duration after which Envoy counts a nonresponsive thread in the - // ``watchdog_mega_miss`` statistic. If not specified the default is - // 1000ms. + // ``watchdog_mega_miss`` statistic. If not specified the default is ``1000ms``. google.protobuf.Duration megamiss_timeout = 2; // If a watched thread has been nonresponsive for this duration, assume a - // programming error and kill the entire Envoy process. Set to 0 to disable - // kill behavior. If not specified the default is 0 (disabled). + // programming error and kill the entire Envoy process. Set to ``0`` to disable + // kill behavior. If not specified the default is ``0`` (disabled). google.protobuf.Duration kill_timeout = 3; // Defines the maximum jitter used to adjust the ``kill_timeout`` if ``kill_timeout`` is // enabled. Enabling this feature would help to reduce risk of synchronized - // watchdog kill events across proxies due to external triggers. Set to 0 to - // disable. If not specified the default is 0 (disabled). + // watchdog kill events across proxies due to external triggers. Set to ``0`` to + // disable. If not specified the default is ``0`` (disabled). google.protobuf.Duration max_kill_timeout_jitter = 6 [(validate.rules).duration = {gte {}}]; - // If ``max(2, ceil(registered_threads * Fraction(*multikill_threshold*)))`` + // If ``max(2, ceil(registered_threads * Fraction(multikill_threshold)))`` // threads have been nonresponsive for at least this duration kill the entire - // Envoy process. Set to 0 to disable this behavior. If not specified the - // default is 0 (disabled). + // Envoy process. Set to ``0`` to disable this behavior. If not specified the + // default is ``0`` (disabled). google.protobuf.Duration multikill_timeout = 4; // Sets the threshold for ``multikill_timeout`` in terms of the percentage of // nonresponsive threads required for the ``multikill_timeout``. - // If not specified the default is 0. + // If not specified the default is ``0``. type.v3.Percent multikill_threshold = 5; } // Fatal actions to run while crashing. Actions can be safe (meaning they are // async-signal safe) or unsafe. We run all safe actions before we run unsafe actions. -// If using an unsafe action that could get stuck or deadlock, it important to -// have an out of band system to terminate the process. +// +// .. note:: +// +// If using an unsafe action that could get stuck or deadlock, it is important to +// have an out of band system to terminate the process. // // The interface for the extension is ``Envoy::Server::Configuration::FatalAction``. // ``FatalAction`` extensions live in the ``envoy.extensions.fatal_actions`` API @@ -659,7 +696,7 @@ message RuntimeLayer { option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.RuntimeLayer.RtdsLayer"; - // Resource to subscribe to at ``rtds_config`` for the RTDS layer. + // Resource to subscribe to at the ``rtds_config`` for the RTDS layer. string name = 1; // RTDS configuration source. @@ -700,11 +737,11 @@ message LayeredRuntime { // Used to specify the header that needs to be registered as an inline header. // // If request or response contain multiple headers with the same name and the header -// name is registered as an inline header. Then multiple headers will be folded +// name is registered as an inline header, then multiple headers will be folded // into one, and multiple header values will be concatenated by a suitable delimiter. // The delimiter is generally a comma. // -// For example, if 'foo' is registered as an inline header, and the headers contains +// For example, if ``foo`` is registered as an inline header, and the headers contain // the following two headers: // // .. code-block:: text @@ -744,6 +781,6 @@ message MemoryAllocatorManager { // Interval in milliseconds for memory releasing. If specified, during every // interval Envoy will try to release ``bytes_to_release`` of free memory back to operating system for reuse. - // Defaults to 1000 milliseconds. + // Defaults to ``1000`` milliseconds. google.protobuf.Duration memory_release_interval = 2; } diff --git a/src/main/proto/envoy/config/cluster/v3/cluster.proto b/src/main/proto/envoy/config/cluster/v3/cluster.proto index c511245..1924090 100644 --- a/src/main/proto/envoy/config/cluster/v3/cluster.proto +++ b/src/main/proto/envoy/config/cluster/v3/cluster.proto @@ -22,6 +22,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "xds/core/v3/collection_entry.proto"; +import "xds/type/matcher/v3/matcher.proto"; import "envoy/annotations/deprecation.proto"; import "udpa/annotations/migrate.proto"; @@ -45,7 +46,7 @@ message ClusterCollection { } // Configuration for a single upstream cluster. -// [#next-free-field: 59] +// [#next-free-field: 60] message Cluster { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Cluster"; @@ -747,6 +748,9 @@ message Cluster { // If both this and preconnect_ratio are set, Envoy will make sure both predicted needs are met, // basically preconnecting max(predictive-preconnect, per-upstream-preconnect), for each // upstream. + // + // This is limited somewhat arbitrarily to 3 because preconnecting too aggressively can + // harm latency more than the preconnecting helps. google.protobuf.DoubleValue predictive_preconnect_ratio = 2 [(validate.rules).double = {lte: 3.0 gte: 1.0}]; } @@ -809,6 +813,41 @@ message Cluster { // [#comment:TODO(incfly): add a detailed architecture doc on intended usage.] repeated TransportSocketMatch transport_socket_matches = 43; + // Optional matcher that selects a transport socket from + // :ref:`transport_socket_matches `. + // + // This matcher uses the generic xDS matcher framework to select a named transport socket + // based on various inputs available at transport socket selection time. + // + // Supported matching inputs: + // + // * ``endpoint_metadata``: Extract values from the selected endpoint's metadata. + // * ``locality_metadata``: Extract values from the endpoint's locality metadata. + // * ``transport_socket_filter_state``: Extract values from filter state that was explicitly shared from + // downstream to upstream via ``TransportSocketOptions``. This enables flexible + // downstream-connection-based matching, such as: + // + // - Network namespace matching. + // - Custom connection attributes. + // - Any data explicitly passed via filter state. + // + // .. note:: + // Filter state sharing follows the same pattern as tunneling in Envoy. Filters must explicitly + // share data by setting filter state with the appropriate sharing mode. The filter state is + // then accessible via the ``transport_socket_filter_state`` input during transport socket selection. + // + // If this field is set, it takes precedence over legacy metadata-based selection + // performed by :ref:`transport_socket_matches + // ` alone. + // If the matcher does not yield a match, Envoy uses the default transport socket + // configured for the cluster. + // + // When using this field, each entry in + // :ref:`transport_socket_matches ` + // must have a unique ``name``. The matcher outcome is expected to reference one of + // these names. + xds.type.matcher.v3.Matcher transport_socket_matcher = 59; + // Supplies the name of the cluster which must be unique across all clusters. // The cluster name is used when emitting // :ref:`statistics ` if :ref:`alt_stat_name diff --git a/src/main/proto/envoy/config/common/mutation_rules/v3/mutation_rules.proto b/src/main/proto/envoy/config/common/mutation_rules/v3/mutation_rules.proto index d129ef1..c015db2 100644 --- a/src/main/proto/envoy/config/common/mutation_rules/v3/mutation_rules.proto +++ b/src/main/proto/envoy/config/common/mutation_rules/v3/mutation_rules.proto @@ -4,6 +4,7 @@ package envoy.config.common.mutation_rules.v3; import "envoy/config/core/v3/base.proto"; import "envoy/type/matcher/v3/regex.proto"; +import "envoy/type/matcher/v3/string.proto"; import "google/protobuf/wrappers.proto"; @@ -90,6 +91,12 @@ message HeaderMutationRules { // The HeaderMutation structure specifies an action that may be taken on HTTP // headers. message HeaderMutation { + message RemoveOnMatch { + // A string matcher that will be applied to the header key. If the header key + // matches, the header will be removed. + type.matcher.v3.StringMatcher key_matcher = 1 [(validate.rules).message = {required: true}]; + } + oneof action { option (validate.required) = true; @@ -99,5 +106,8 @@ message HeaderMutation { // Append new header by the specified HeaderValueOption. core.v3.HeaderValueOption append = 2; + + // Remove the header if the key matches the specified string matcher. + RemoveOnMatch remove_on_match = 3; } } diff --git a/src/main/proto/envoy/config/core/v3/address.proto b/src/main/proto/envoy/config/core/v3/address.proto index 56796fc..17a6826 100644 --- a/src/main/proto/envoy/config/core/v3/address.proto +++ b/src/main/proto/envoy/config/core/v3/address.proto @@ -105,9 +105,6 @@ message SocketAddress { // .. note:: // Setting this parameter requires Envoy to run with the ``CAP_NET_ADMIN`` capability. // - // .. note:: - // Currently only used for Listener sockets. - // // .. attention:: // Network namespaces are only configurable on Linux. Otherwise, this field has no effect. string network_namespace_filepath = 7; @@ -118,16 +115,18 @@ message TcpKeepalive { // Maximum number of keepalive probes to send without response before deciding // the connection is dead. Default is to use the OS level configuration (unless - // overridden, Linux defaults to 9.) + // overridden, Linux defaults to 9.) Setting this to ``0`` disables TCP keepalive. google.protobuf.UInt32Value keepalive_probes = 1; // The number of seconds a connection needs to be idle before keep-alive probes // start being sent. Default is to use the OS level configuration (unless - // overridden, Linux defaults to 7200s (i.e., 2 hours.) + // overridden, Linux defaults to 7200s (i.e., 2 hours.) Setting this to ``0`` disables + // TCP keepalive. google.protobuf.UInt32Value keepalive_time = 2; // The number of seconds between keep-alive probes. Default is to use the OS - // level configuration (unless overridden, Linux defaults to 75s.) + // level configuration (unless overridden, Linux defaults to 75s.) Setting this to + // ``0`` disables TCP keepalive. google.protobuf.UInt32Value keepalive_interval = 3; } diff --git a/src/main/proto/envoy/config/core/v3/cel.proto b/src/main/proto/envoy/config/core/v3/cel.proto new file mode 100644 index 0000000..940a66d --- /dev/null +++ b/src/main/proto/envoy/config/core/v3/cel.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; + +package envoy.config.core.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.config.core.v3"; +option java_outer_classname = "CelProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/config/core/v3;corev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: CEL Expression Configuration] + +// CEL expression evaluation configuration. +// These options control the behavior of the Common Expression Language runtime for +// individual CEL expressions. +message CelExpressionConfig { + // Enable string conversion functions for CEL expressions. When enabled, CEL expressions + // can convert values to strings using the ``string()`` function. + // + // .. attention:: + // + // This option is disabled by default to avoid unbounded memory allocation. + // CEL evaluation cost is typically bounded by the expression size, but converting + // arbitrary values (e.g., large messages, lists, or maps) to strings may allocate + // memory proportional to input data size, which can be unbounded and lead to + // memory exhaustion. + bool enable_string_conversion = 1; + + // Enable string concatenation for CEL expressions. When enabled, CEL expressions + // can concatenate strings using the ``+`` operator. + // + // .. attention:: + // + // This option is disabled by default to avoid unbounded memory allocation. + // While CEL normally bounds evaluation by expression size, enabling string + // concatenation allows building outputs whose size depends on input data, + // potentially causing large intermediate allocations and memory exhaustion. + bool enable_string_concat = 2; + + // Enable string manipulation functions for CEL expressions. When enabled, CEL + // expressions can use additional string functions: + // + // * ``replace(old, new)`` - Replaces all occurrences of ``old`` with ``new``. + // * ``split(separator)`` - Splits a string into a list of substrings. + // * ``lowerAscii()`` - Converts ASCII characters to lowercase. + // * ``upperAscii()`` - Converts ASCII characters to uppercase. + // + // .. note:: + // + // Standard CEL string functions like ``contains()``, ``startsWith()``, and + // ``endsWith()`` are always available regardless of this setting. + // + // .. attention:: + // + // This option is disabled by default to avoid unbounded memory allocation. + // Although CEL generally bounds evaluation by expression size, functions such as + // ``replace``, ``split``, ``lowerAscii()``, and ``upperAscii()`` can allocate memory + // proportional to input data size. Under adversarial inputs this can lead to + // unbounded allocations and memory exhaustion. + bool enable_string_functions = 3; +} diff --git a/src/main/proto/envoy/config/core/v3/config_source.proto b/src/main/proto/envoy/config/core/v3/config_source.proto index f0effd9..430562a 100644 --- a/src/main/proto/envoy/config/core/v3/config_source.proto +++ b/src/main/proto/envoy/config/core/v3/config_source.proto @@ -276,7 +276,8 @@ message ExtensionConfigSource { // to be supplied. bool apply_default_config_without_warming = 3; - // A set of permitted extension type URLs. Extension configuration updates are rejected - // if they do not match any type URL in the set. + // A set of permitted extension type URLs for the type encoded inside of the + // :ref:`TypedExtensionConfig `. Extension + // configuration updates are rejected if they do not match any type URL in the set. repeated string type_urls = 4 [(validate.rules).repeated = {min_items: 1}]; } diff --git a/src/main/proto/envoy/config/core/v3/grpc_service.proto b/src/main/proto/envoy/config/core/v3/grpc_service.proto index 5fd7921..9c44006 100644 --- a/src/main/proto/envoy/config/core/v3/grpc_service.proto +++ b/src/main/proto/envoy/config/core/v3/grpc_service.proto @@ -45,10 +45,20 @@ message GrpcService { [(validate.rules).string = {min_len: 0 max_bytes: 16384 well_known_regex: HTTP_HEADER_VALUE strict: false}]; - // Indicates the retry policy for re-establishing the gRPC stream - // This field is optional. If max interval is not provided, it will be set to ten times the provided base interval. - // Currently only supported for xDS gRPC streams. - // If not set, xDS gRPC streams default base interval:500ms, maximum interval:30s will be applied. + // Specifies the retry backoff policy for re-establishing long‑lived xDS gRPC streams. + // + // This field is optional. If ``retry_back_off.max_interval`` is not provided, it will be set to + // ten times the configured ``retry_back_off.base_interval``. + // + // .. note:: + // + // This field is only honored for management‑plane xDS gRPC streams created from + // :ref:`ApiConfigSource ` that use + // ``envoy_grpc``. Data‑plane gRPC clients (for example external authorization or external + // processing filters) must use :ref:`GrpcService.retry_policy + // ` instead. + // + // If not set, xDS gRPC streams default to a base interval of 500ms and a maximum interval of 30s. RetryPolicy retry_policy = 3; // Maximum gRPC message size that is allowed to be received. @@ -64,7 +74,7 @@ message GrpcService { bool skip_envoy_headers = 5; } - // [#next-free-field: 9] + // [#next-free-field: 11] message GoogleGrpc { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.GrpcService.GoogleGrpc"; @@ -249,16 +259,31 @@ message GrpcService { } // The target URI when using the `Google C++ gRPC client - // `_. SSL credentials will be supplied in - // :ref:`channel_credentials `. + // `_. string target_uri = 1 [(validate.rules).string = {min_len: 1}]; + // The channel credentials to use. See `channel credentials + // `_. + // Ignored if ``channel_credentials_plugin`` is set. ChannelCredentials channel_credentials = 2; - // A set of call credentials that can be composed with `channel credentials + // A list of channel credentials plugins. + // The data plane will iterate over the list in order and stop at the first credential type + // that it supports. This provides a mechanism for starting to use new credential types that + // are not yet supported by all data planes. + // [#not-implemented-hide:] + repeated google.protobuf.Any channel_credentials_plugin = 9; + + // The call credentials to use. See `channel credentials // `_. + // Ignored if ``call_credentials_plugin`` is set. repeated CallCredentials call_credentials = 3; + // A list of call credentials plugins. All supported plugins will be used. + // Unsupported plugin types will be ignored. + // [#not-implemented-hide:] + repeated google.protobuf.Any call_credentials_plugin = 10; + // The human readable prefix to use when emitting statistics for the gRPC // service. // @@ -314,7 +339,17 @@ message GrpcService { // `. repeated HeaderValue initial_metadata = 5; - // Optional default retry policy for streams toward the service. - // If an async stream doesn't have retry policy configured in its stream options, this retry policy is used. + // Optional default retry policy for RPCs or streams initiated toward this gRPC service. + // + // If an async stream does not have a retry policy configured in its per‑stream options, this + // policy is used as the default. + // + // .. note:: + // + // This field is only applied by Envoy gRPC (``envoy_grpc``) clients. Google gRPC + // (``google_grpc``) clients currently ignore this field. + // + // If not specified, no default retry policy is applied at the client level and retries only occur + // when explicitly configured in per‑stream options. RetryPolicy retry_policy = 6; } diff --git a/src/main/proto/envoy/config/core/v3/health_check.proto b/src/main/proto/envoy/config/core/v3/health_check.proto index fd4440d..a4ed6e9 100644 --- a/src/main/proto/envoy/config/core/v3/health_check.proto +++ b/src/main/proto/envoy/config/core/v3/health_check.proto @@ -102,7 +102,8 @@ message HealthCheck { // ``/healthcheck``. string path = 2 [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_VALUE}]; - // [#not-implemented-hide:] HTTP specific payload. + // HTTP specific payload to be sent as the request body during health checking. + // If specified, the method should support a request body (POST, PUT, PATCH, etc.). Payload send = 3; // Specifies a list of HTTP expected responses to match in the first ``response_buffer_size`` bytes of the response body. @@ -161,7 +162,8 @@ message HealthCheck { type.matcher.v3.StringMatcher service_name_matcher = 11; // HTTP Method that will be used for health checking, default is "GET". - // GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH methods are supported, but making request body is not supported. + // GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH methods are supported. + // Request body payloads are supported for POST, PUT, PATCH, and OPTIONS methods only. // CONNECT method is disallowed because it is not appropriate for health check request. // If a non-200 response is expected by the method, it needs to be set in :ref:`expected_statuses `. RequestMethod method = 13 [(validate.rules).enum = {defined_only: true not_in: 6}]; diff --git a/src/main/proto/envoy/config/core/v3/protocol.proto b/src/main/proto/envoy/config/core/v3/protocol.proto index 147caa2..63e189e 100644 --- a/src/main/proto/envoy/config/core/v3/protocol.proto +++ b/src/main/proto/envoy/config/core/v3/protocol.proto @@ -31,10 +31,13 @@ message TcpProtocolOptions { } // Config for keepalive probes in a QUIC connection. -// Note that QUIC keep-alive probing packets work differently from HTTP/2 keep-alive PINGs in a sense that the probing packet -// itself doesn't timeout waiting for a probing response. Quic has a shorter idle timeout than TCP, so it doesn't rely on such probing to discover dead connections. If the peer fails to respond, the connection will idle timeout eventually. Thus, they are configured differently from :ref:`connection_keepalive `. +// +// .. note:: +// +// QUIC keep-alive probing packets work differently from HTTP/2 keep-alive PINGs in a sense that the probing packet +// itself doesn't timeout waiting for a probing response. QUIC has a shorter idle timeout than TCP, so it doesn't rely on such probing to discover dead connections. If the peer fails to respond, the connection will idle timeout eventually. Thus, they are configured differently from :ref:`connection_keepalive `. message QuicKeepAliveSettings { - // The max interval for a connection to send keep-alive probing packets (with PING or PATH_RESPONSE). The value should be smaller than :ref:`connection idle_timeout ` to prevent idle timeout while not less than 1s to avoid throttling the connection or flooding the peer with probes. + // The max interval for a connection to send keep-alive probing packets (with ``PING`` or ``PATH_RESPONSE``). The value should be smaller than :ref:`connection idle_timeout ` to prevent idle timeout while not less than ``1s`` to avoid throttling the connection or flooding the peer with probes. // // If :ref:`initial_interval ` is absent or zero, a client connection will use this value to start probing. // @@ -54,20 +57,53 @@ message QuicKeepAliveSettings { } // QUIC protocol options which apply to both downstream and upstream connections. -// [#next-free-field: 10] +// [#next-free-field: 12] message QuicProtocolOptions { - // Maximum number of streams that the client can negotiate per connection. 100 + // Config for QUIC connection migration across network interfaces, i.e. cellular to WIFI, upon + // network change events from the platform, i.e. the current network gets + // disconnected, or upon the QUIC detecting a bad connection. After migration, the + // connection may be on a different network other than the default network + // picked by the platform. Both iOS and Android will use a default network to interact with the internet, usually prefer unmetered network (WIFI) + // over metered ones (cellular). And users can specify which network to be used as the default. A connection on non-default network is only allowed to + // serve new requests for a certain period of time before being drained, and + // meanwhile, QUIC will try to migrate to the default network if possible. + message ConnectionMigrationSettings { + // Config for options to migrate idle connections which aren't serving any requests. + message MigrateIdleConnectionSettings { + // If idle connections are allowed to be migrated, only migrate the connection + // if it hasn't been idle for longer than this idle period. Otherwise, the + // connection will be closed instead. + // Default to 30s. + google.protobuf.Duration max_idle_time_before_migration = 1 + [(validate.rules).duration = {gte {seconds: 1}}]; + } + + // Config whether and how to migrate idle connections. + // If absent, idle connections will not be migrated but be closed upon + // migration signals. + MigrateIdleConnectionSettings migrate_idle_connections = 1; + + // After migrating to a non-default network interface, the connection will + // only be allowed to stay on that network for up to this period of time before + // being drained unless it migrates to the default network or that network + // gets picked as the default by the device by then. + // Default to 128s. + google.protobuf.Duration max_time_on_non_default_network = 2 + [(validate.rules).duration = {gte {seconds: 1}}]; + } + + // Maximum number of streams that the client can negotiate per connection. ``100`` // if not specified. google.protobuf.UInt32Value max_concurrent_streams = 1 [(validate.rules).uint32 = {gte: 1}]; // `Initial stream-level flow-control receive window // `_ size. Valid values range from - // 1 to 16777216 (2^24, maximum supported by QUICHE) and defaults to 16777216 (16 * 1024 * 1024). + // ``1`` to ``16777216`` (``2^24``, maximum supported by QUICHE) and defaults to ``16777216`` (``16 * 1024 * 1024``). // // .. note:: // - // 16384 (2^14) is the minimum window size supported in Google QUIC. If configured smaller than it, we will use - // 16384 instead. QUICHE IETF Quic implementation supports 1 bytes window. We only support increasing the default + // ``16384`` (``2^14``) is the minimum window size supported in Google QUIC. If configured smaller than it, we will use + // ``16384`` instead. QUICHE IETF QUIC implementation supports ``1`` byte window. We only support increasing the default // window size now, so it's also the minimum. // // This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the @@ -77,26 +113,26 @@ message QuicProtocolOptions { [(validate.rules).uint32 = {lte: 16777216 gte: 1}]; // Similar to ``initial_stream_window_size``, but for connection-level - // flow-control. Valid values rage from 1 to 25165824 (24MB, maximum supported by QUICHE) and defaults - // to 25165824 (24 * 1024 * 1024). + // flow-control. Valid values range from ``1`` to ``25165824`` (``24MB``, maximum supported by QUICHE) and defaults + // to ``25165824`` (``24 * 1024 * 1024``). // // .. note:: // - // 16384 (2^14) is the minimum window size supported in Google QUIC. We only support increasing the default + // ``16384`` (``2^14``) is the minimum window size supported in Google QUIC. We only support increasing the default // window size now, so it's also the minimum. // google.protobuf.UInt32Value initial_connection_window_size = 3 [(validate.rules).uint32 = {lte: 25165824 gte: 1}]; // The number of timeouts that can occur before port migration is triggered for QUIC clients. - // This defaults to 4. If set to 0, port migration will not occur on path degrading. - // Timeout here refers to QUIC internal path degrading timeout mechanism, such as PTO. + // This defaults to ``4``. If set to ``0``, port migration will not occur on path degrading. + // Timeout here refers to QUIC internal path degrading timeout mechanism, such as ``PTO``. // This has no effect on server sessions. google.protobuf.UInt32Value num_timeouts_to_trigger_port_migration = 4 [(validate.rules).uint32 = {lte: 5 gte: 0}]; - // Probes the peer at the configured interval to solicit traffic, i.e. ACK or PATH_RESPONSE, from the peer to push back connection idle timeout. - // If absent, use the default keepalive behavior of which a client connection sends PINGs every 15s, and a server connection doesn't do anything. + // Probes the peer at the configured interval to solicit traffic, i.e. ``ACK`` or ``PATH_RESPONSE``, from the peer to push back connection idle timeout. + // If absent, use the default keepalive behavior of which a client connection sends ``PING``s every ``15s``, and a server connection doesn't do anything. QuicKeepAliveSettings connection_keepalive = 5; // A comma-separated list of strings representing QUIC connection options defined in @@ -108,17 +144,35 @@ message QuicProtocolOptions { string client_connection_options = 7; // The duration that a QUIC connection stays idle before it closes itself. If this field is not present, QUICHE - // default 600s will be applied. + // default ``600s`` will be applied. // For internal corporate network, a long timeout is often fine. - // But for client facing network, 30s is usually a good choice. - google.protobuf.Duration idle_network_timeout = 8 [(validate.rules).duration = { - lte {seconds: 600} - gte {seconds: 1} - }]; + // But for client facing network, ``30s`` is usually a good choice. + // Do not add an upper bound here. A long idle timeout is useful for maintaining warm connections at non-front-line proxy for low QPS services. + google.protobuf.Duration idle_network_timeout = 8 + [(validate.rules).duration = {gte {seconds: 1}}]; // Maximum packet length for QUIC connections. It refers to the largest size of a QUIC packet that can be transmitted over the connection. // If not specified, one of the `default values in QUICHE `_ is used. google.protobuf.UInt64Value max_packet_length = 9; + + // A customized UDP socket and a QUIC packet writer using the socket for + // client connections. i.e. Mobile uses its own implementation to interact + // with platform socket APIs. + // If not present, the default platform-independent socket and writer will be used. + // [#extension-category: envoy.quic.client_packet_writer] + TypedExtensionConfig client_packet_writer = 10; + + // Enable QUIC `connection migration + // ` + // to a different network interface when the current network is degrading or + // has become bad. + // In order to use a different network interface other than the platform's default one, + // a customized :ref:`client_packet_writer ` needs to be configured to + // create UDP sockets on non-default networks. + // Only takes effect when runtime key ``envoy.reloadable_features.use_migration_in_quiche`` is true. + // If absent, the feature will be disabled. + // [#not-implemented-hide:] + ConnectionMigrationSettings connection_migration = 11; } message UpstreamHttpProtocolOptions { @@ -188,9 +242,9 @@ message AlternateProtocolsCacheOptions { // not the case. string name = 1 [(validate.rules).string = {min_len: 1}]; - // The maximum number of entries that the cache will hold. If not specified defaults to 1024. + // The maximum number of entries that the cache will hold. If not specified defaults to ``1024``. // - // .. note: + // .. note:: // // The implementation is approximate and enforced independently on each worker thread, thus // it is possible for the maximum entries in the cache to go slightly above the configured @@ -233,14 +287,14 @@ message HttpProtocolOptions { // Allow headers with underscores. This is the default behavior. ALLOW = 0; - // Reject client request. HTTP/1 requests are rejected with the 400 status. HTTP/2 requests - // end with the stream reset. The "httpN.requests_rejected_with_underscores_in_headers" counter + // Reject client request. HTTP/1 requests are rejected with ``HTTP 400`` status. HTTP/2 requests + // end with the stream reset. The ``httpN.requests_rejected_with_underscores_in_headers`` counter // is incremented for each rejected request. REJECT_REQUEST = 1; // Drop the client header with name containing underscores. The header is dropped before the filter chain is // invoked and as such filters will not see dropped headers. The - // "httpN.dropped_headers_with_underscores" is incremented for each dropped header. + // ``httpN.dropped_headers_with_underscores`` is incremented for each dropped header. DROP_HEADER = 2; } @@ -250,8 +304,12 @@ message HttpProtocolOptions { // downstream connection a drain sequence will occur prior to closing the connection, see // :ref:`drain_timeout // `. - // Note that request based timeouts mean that HTTP/2 PINGs will not keep the connection alive. - // If not specified, this defaults to 1 hour. To disable idle timeouts explicitly set this to 0. + // + // .. note:: + // + // Request based timeouts mean that HTTP/2 PINGs will not keep the connection alive. + // + // If not specified, this defaults to ``1 hour``. To disable idle timeouts explicitly set this to ``0``. // // .. warning:: // Disabling this timeout has a highly likelihood of yielding connection leaks due to lost TCP @@ -271,19 +329,19 @@ message HttpProtocolOptions { // The maximum number of headers (request headers if configured on HttpConnectionManager, // response headers when configured on a cluster). - // If unconfigured, the default maximum number of headers allowed is 100. + // If unconfigured, the default maximum number of headers allowed is ``100``. // The default value for requests can be overridden by setting runtime key ``envoy.reloadable_features.max_request_headers_count``. // The default value for responses can be overridden by setting runtime key ``envoy.reloadable_features.max_response_headers_count``. - // Downstream requests that exceed this limit will receive a 431 response for HTTP/1.x and cause a stream + // Downstream requests that exceed this limit will receive a ``HTTP 431`` response for HTTP/1.x and cause a stream // reset for HTTP/2. - // Upstream responses that exceed this limit will result in a 502 response. + // Upstream responses that exceed this limit will result in a ``HTTP 502`` response. google.protobuf.UInt32Value max_headers_count = 2 [(validate.rules).uint32 = {gte: 1}]; // The maximum size of response headers. - // If unconfigured, the default is 60 KiB, except for HTTP/1 response headers which have a default - // of 80KiB. + // If unconfigured, the default is ``60 KiB``, except for HTTP/1 response headers which have a default + // of ``80 KiB``. // The default value can be overridden by setting runtime key ``envoy.reloadable_features.max_response_headers_size_kb``. - // Responses that exceed this limit will result in a 503 response. + // Responses that exceed this limit will result in a ``HTTP 503`` response. // In Envoy, this setting is only valid when configured on an upstream cluster, not on the // :ref:`HTTP Connection Manager // `. @@ -292,8 +350,8 @@ message HttpProtocolOptions { // // Currently some protocol codecs impose limits on the maximum size of a single header. // - // * HTTP/2 (when using nghttp2) limits a single header to around 100kb. - // * HTTP/3 limits a single header to around 1024kb. + // * HTTP/2 (when using ``nghttp2``) limits a single header to around ``100kb``. + // * HTTP/3 limits a single header to around ``1024kb``. // google.protobuf.UInt32Value max_response_headers_kb = 7 [(validate.rules).uint32 = {lte: 8192 gt: 0}]; @@ -303,7 +361,7 @@ message HttpProtocolOptions { google.protobuf.Duration max_stream_duration = 4; // Action to take when a client request with a header name containing underscore characters is received. - // If this setting is not specified, the value defaults to ALLOW. + // If this setting is not specified, the value defaults to ``ALLOW``. // // .. note:: // @@ -317,7 +375,7 @@ message HttpProtocolOptions { // Optional maximum requests for both upstream and downstream connections. // If not specified, there is no limit. - // Setting this parameter to 1 will effectively disable keep alive. + // Setting this parameter to ``1`` will effectively disable keep alive. // For HTTP/2 and HTTP/3, due to concurrent stream processing, the limit is approximate. google.protobuf.UInt32Value max_requests_per_connection = 6; } @@ -342,9 +400,12 @@ message Http1ProtocolOptions { // Formats the header by proper casing words: the first character and any character following // a special character will be capitalized if it's an alpha character. For example, - // "content-type" becomes "Content-Type", and "foo$b#$are" becomes "Foo$B#$Are". - // Note that while this results in most headers following conventional casing, certain headers - // are not covered. For example, the "TE" header will be formatted as "Te". + // ``"content-type"`` becomes ``"Content-Type"``, and ``"foo$b#$are"`` becomes ``"Foo$B#$Are"``. + // + // .. note:: + // + // While this results in most headers following conventional casing, certain headers + // are not covered. For example, the ``"TE"`` header will be formatted as ``"Te"``. ProperCaseWords proper_case_words = 1; // Configuration for stateful formatter extensions that allow using received headers to @@ -360,7 +421,7 @@ message Http1ProtocolOptions { // ``http_proxy`` environment variable. google.protobuf.BoolValue allow_absolute_url = 1; - // Handle incoming HTTP/1.0 and HTTP 0.9 requests. + // Handle incoming HTTP/1.0 and HTTP/0.9 requests. // This is off by default, and not fully standards compliant. There is support for pre-HTTP/1.1 // style connect logic, dechunking, and handling lack of client host iff // ``default_host_for_http_10`` is configured. @@ -379,19 +440,20 @@ message Http1ProtocolOptions { // // .. attention:: // - // Note that this only happens when Envoy is chunk encoding which occurs when: + // This only happens when Envoy is chunk encoding which occurs when: // - The request is HTTP/1.1. - // - Is neither a HEAD only request nor a HTTP Upgrade. - // - Not a response to a HEAD request. - // - The content length header is not present. + // - Is neither a ``HEAD`` only request nor a HTTP Upgrade. + // - Not a response to a ``HEAD`` request. + // - The ``Content-Length`` header is not present. bool enable_trailers = 5; // Allows Envoy to process requests/responses with both ``Content-Length`` and ``Transfer-Encoding`` // headers set. By default such messages are rejected, but if option is enabled - Envoy will - // remove Content-Length header and process message. + // remove ``Content-Length`` header and process message. // See `RFC7230, sec. 3.3.3 `_ for details. // // .. attention:: + // // Enabling this option might lead to request smuggling vulnerability, especially if traffic // is proxied via multiple layers of proxies. // [#comment:TODO: This field is ignored when the @@ -450,9 +512,12 @@ message KeepaliveSettings { google.protobuf.Duration interval = 1 [(validate.rules).duration = {gte {nanos: 1000000}}]; // How long to wait for a response to a keepalive PING. If a response is not received within this - // time period, the connection will be aborted. Note that in order to prevent the influence of - // Head-of-line (HOL) blocking the timeout period is extended when *any* frame is received on - // the connection, under the assumption that if a frame is received the connection is healthy. + // time period, the connection will be aborted. + // + // .. note:: + // + // In order to prevent the influence of Head-of-line (HOL) blocking the timeout period is extended when *any* frame is received on + // the connection, under the assumption that if a frame is received the connection is healthy. google.protobuf.Duration timeout = 2 [(validate.rules).duration = { required: true gte {nanos: 1000000} @@ -460,7 +525,7 @@ message KeepaliveSettings { // A random jitter amount as a percentage of interval that will be added to each interval. // A value of zero means there will be no jitter. - // The default value is 15%. + // The default value is ``15%``. type.v3.Percent interval_jitter = 3; // If the connection has been idle for this duration, send a HTTP/2 ping ahead @@ -474,7 +539,7 @@ message KeepaliveSettings { [(validate.rules).duration = {gte {nanos: 1000000}}]; } -// [#next-free-field: 18] +// [#next-free-field: 19] message Http2ProtocolOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.Http2ProtocolOptions"; @@ -497,13 +562,13 @@ message Http2ProtocolOptions { // `Maximum table size `_ // (in octets) that the encoder is permitted to use for the dynamic HPACK table. Valid values - // range from 0 to 4294967295 (2^32 - 1) and defaults to 4096. 0 effectively disables header + // range from ``0`` to ``4294967295`` (``2^32 - 1``) and defaults to ``4096``. ``0`` effectively disables header // compression. google.protobuf.UInt32Value hpack_table_size = 1; // `Maximum concurrent streams `_ - // allowed for peer on one HTTP/2 connection. Valid values range from 1 to 2147483647 (2^31 - 1) - // and defaults to 2147483647. + // allowed for peer on one HTTP/2 connection. Valid values range from ``1`` to ``2147483647`` (``2^31 - 1``) + // and defaults to ``1024`` for safety and should be sufficient for most use cases. // // For upstream connections, this also limits how many streams Envoy will initiate concurrently // on a single connection. If the limit is reached, Envoy may queue requests or establish @@ -516,13 +581,13 @@ message Http2ProtocolOptions { [(validate.rules).uint32 = {lte: 2147483647 gte: 1}]; // `Initial stream-level flow-control window - // `_ size. Valid values range from 65535 - // (2^16 - 1, HTTP/2 default) to 2147483647 (2^31 - 1, HTTP/2 maximum) and defaults to 268435456 - // (256 * 1024 * 1024). + // `_ size. Valid values range from ``65535`` + // (``2^16 - 1``, HTTP/2 default) to ``2147483647`` (``2^31 - 1``, HTTP/2 maximum) and defaults to + // ``16MiB`` (``16 * 1024 * 1024``). // // .. note:: // - // 65535 is the initial window size from HTTP/2 spec. We only support increasing the default window size now, + // ``65535`` is the initial window size from HTTP/2 spec. We only support increasing the default window size now, // so it's also the minimum. // // This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the @@ -532,7 +597,7 @@ message Http2ProtocolOptions { [(validate.rules).uint32 = {lte: 2147483647 gte: 65535}]; // Similar to ``initial_stream_window_size``, but for connection-level flow-control - // window. Currently, this has the same minimum/maximum/default as ``initial_stream_window_size``. + // window. The default is ``24MiB`` (``24 * 1024 * 1024``). google.protobuf.UInt32Value initial_connection_window_size = 4 [(validate.rules).uint32 = {lte: 2147483647 gte: 65535}]; @@ -550,51 +615,51 @@ message Http2ProtocolOptions { // Limit the number of pending outbound downstream frames of all types (frames that are waiting to // be written into the socket). Exceeding this limit triggers flood mitigation and connection is // terminated. The ``http2.outbound_flood`` stat tracks the number of terminated connections due - // to flood mitigation. The default limit is 10000. + // to flood mitigation. The default limit is ``10000``. google.protobuf.UInt32Value max_outbound_frames = 7 [(validate.rules).uint32 = {gte: 1}]; - // Limit the number of pending outbound downstream frames of types PING, SETTINGS and RST_STREAM, + // Limit the number of pending outbound downstream frames of types ``PING``, ``SETTINGS`` and ``RST_STREAM``, // preventing high memory utilization when receiving continuous stream of these frames. Exceeding // this limit triggers flood mitigation and connection is terminated. The // ``http2.outbound_control_flood`` stat tracks the number of terminated connections due to flood - // mitigation. The default limit is 1000. + // mitigation. The default limit is ``1000``. google.protobuf.UInt32Value max_outbound_control_frames = 8 [(validate.rules).uint32 = {gte: 1}]; - // Limit the number of consecutive inbound frames of types HEADERS, CONTINUATION and DATA with an + // Limit the number of consecutive inbound frames of types ``HEADERS``, ``CONTINUATION`` and ``DATA`` with an // empty payload and no end stream flag. Those frames have no legitimate use and are abusive, but - // might be a result of a broken HTTP/2 implementation. The `http2.inbound_empty_frames_flood`` + // might be a result of a broken HTTP/2 implementation. The ``http2.inbound_empty_frames_flood`` // stat tracks the number of connections terminated due to flood mitigation. - // Setting this to 0 will terminate connection upon receiving first frame with an empty payload - // and no end stream flag. The default limit is 1. + // Setting this to ``0`` will terminate connection upon receiving first frame with an empty payload + // and no end stream flag. The default limit is ``1``. google.protobuf.UInt32Value max_consecutive_inbound_frames_with_empty_payload = 9; - // Limit the number of inbound PRIORITY frames allowed per each opened stream. If the number - // of PRIORITY frames received over the lifetime of connection exceeds the value calculated + // Limit the number of inbound ``PRIORITY`` frames allowed per each opened stream. If the number + // of ``PRIORITY`` frames received over the lifetime of connection exceeds the value calculated // using this formula:: // // ``max_inbound_priority_frames_per_stream`` * (1 + ``opened_streams``) // // the connection is terminated. For downstream connections the ``opened_streams`` is incremented when // Envoy receives complete response headers from the upstream server. For upstream connection the - // ``opened_streams`` is incremented when Envoy send the HEADERS frame for a new stream. The + // ``opened_streams`` is incremented when Envoy sends the ``HEADERS`` frame for a new stream. The // ``http2.inbound_priority_frames_flood`` stat tracks - // the number of connections terminated due to flood mitigation. The default limit is 100. + // the number of connections terminated due to flood mitigation. The default limit is ``100``. google.protobuf.UInt32Value max_inbound_priority_frames_per_stream = 10; - // Limit the number of inbound WINDOW_UPDATE frames allowed per DATA frame sent. If the number - // of WINDOW_UPDATE frames received over the lifetime of connection exceeds the value calculated + // Limit the number of inbound ``WINDOW_UPDATE`` frames allowed per ``DATA`` frame sent. If the number + // of ``WINDOW_UPDATE`` frames received over the lifetime of connection exceeds the value calculated // using this formula:: // - // 5 + 2 * (``opened_streams`` + - // ``max_inbound_window_update_frames_per_data_frame_sent`` * ``outbound_data_frames``) + // ``5 + 2 * (opened_streams + + // max_inbound_window_update_frames_per_data_frame_sent * outbound_data_frames)`` // // the connection is terminated. For downstream connections the ``opened_streams`` is incremented when // Envoy receives complete response headers from the upstream server. For upstream connections the - // ``opened_streams`` is incremented when Envoy sends the HEADERS frame for a new stream. The + // ``opened_streams`` is incremented when Envoy sends the ``HEADERS`` frame for a new stream. The // ``http2.inbound_priority_frames_flood`` stat tracks the number of connections terminated due to - // flood mitigation. The default max_inbound_window_update_frames_per_data_frame_sent value is 10. - // Setting this to 1 should be enough to support HTTP/2 implementations with basic flow control, - // but more complex implementations that try to estimate available bandwidth require at least 2. + // flood mitigation. The default ``max_inbound_window_update_frames_per_data_frame_sent`` value is ``10``. + // Setting this to ``1`` should be enough to support HTTP/2 implementations with basic flow control, + // but more complex implementations that try to estimate available bandwidth require at least ``2``. google.protobuf.UInt32Value max_inbound_window_update_frames_per_data_frame_sent = 11 [(validate.rules).uint32 = {gte: 1}]; @@ -632,8 +697,10 @@ message Http2ProtocolOptions { // 2. SETTINGS_ENABLE_CONNECT_PROTOCOL (0x8) is only configurable through the named field // 'allow_connect'. // - // Note that custom parameters specified through this field can not also be set in the - // corresponding named parameters: + // .. note:: + // + // Custom parameters specified through this field can not also be set in the + // corresponding named parameters: // // .. code-block:: text // @@ -661,8 +728,14 @@ message Http2ProtocolOptions { google.protobuf.BoolValue use_oghttp2_codec = 16 [(xds.annotations.v3.field_status).work_in_progress = true]; - // Configure the maximum amount of metadata than can be handled per stream. Defaults to 1 MB. + // Configure the maximum amount of metadata than can be handled per stream. Defaults to ``1 MB``. google.protobuf.UInt64Value max_metadata_size = 17; + + // Controls whether to encode headers using huffman encoding. + // This can be useful in cases where the cpu spent encoding the headers isn't + // worth the network bandwidth saved e.g. for localhost. + // If unset, uses the data plane's default value. + google.protobuf.BoolValue enable_huffman_encoding = 18; } // [#not-implemented-hide:] @@ -691,7 +764,10 @@ message Http3ProtocolOptions { // `_ // and settings `proposed for HTTP/3 // `_ - // Note that HTTP/3 CONNECT is not yet an RFC. + // + // .. note:: + // + // HTTP/3 CONNECT is not yet an RFC. bool allow_extended_connect = 5 [(xds.annotations.v3.field_status).work_in_progress = true]; // [#not-implemented-hide:] Hiding until Envoy has full metadata support. @@ -706,7 +782,7 @@ message Http3ProtocolOptions { // Still under implementation. DO NOT USE. // // Disables QPACK compression related features for HTTP/3 including: - // No huffman encoding, zero dynamic table capacity and no cookie crumbing. + // No huffman encoding, zero dynamic table capacity and no cookie crumbling. // This can be useful for trading off CPU vs bandwidth when an upstream HTTP/3 connection multiplexes multiple downstream connections. bool disable_qpack = 7; @@ -719,13 +795,13 @@ message Http3ProtocolOptions { message SchemeHeaderTransformation { oneof transformation { // Overwrite any Scheme header with the contents of this string. - // If set, takes precedence over match_upstream. + // If set, takes precedence over ``match_upstream``. string scheme_to_overwrite = 1 [(validate.rules).string = {in: "http" in: "https"}]; } // Set the Scheme header to match the upstream transport protocol. For example, should a - // request be sent to the upstream over TLS, the scheme header will be set to "https". Should the - // request be sent over plaintext, the scheme header will be set to "http". - // If scheme_to_overwrite is set, this field is not used. + // request be sent to the upstream over TLS, the scheme header will be set to ``"https"``. Should the + // request be sent over plaintext, the scheme header will be set to ``"http"``. + // If ``scheme_to_overwrite`` is set, this field is not used. bool match_upstream = 2; } diff --git a/src/main/proto/envoy/config/core/v3/proxy_protocol.proto b/src/main/proto/envoy/config/core/v3/proxy_protocol.proto index 564e76c..2da5fe5 100644 --- a/src/main/proto/envoy/config/core/v3/proxy_protocol.proto +++ b/src/main/proto/envoy/config/core/v3/proxy_protocol.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package envoy.config.core.v3; +import "envoy/config/core/v3/substitution_format_string.proto"; + import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -37,8 +39,27 @@ message TlvEntry { // The type of the TLV. Must be a uint8 (0-255) as per the Proxy Protocol v2 specification. uint32 type = 1 [(validate.rules).uint32 = {lt: 256}]; - // The value of the TLV. Must be at least one byte long. - bytes value = 2 [(validate.rules).bytes = {min_len: 1}]; + // The static value of the TLV. + // Only one of ``value`` or ``format_string`` may be set. + bytes value = 2; + + // Uses the :ref:`format string ` to dynamically + // populate the TLV value from stream information. This allows dynamic values + // such as metadata, filter state, or other stream properties to be included in + // the TLV. + // + // For example: + // + // .. code-block:: yaml + // + // type: 0xF0 + // format_string: + // text_format_source: + // inline_string: "%DYNAMIC_METADATA(envoy.filters.network:key)%" + // + // The formatted string will be used directly as the TLV value. + // Only one of ``value`` or ``format_string`` may be set. + SubstitutionFormatString format_string = 3; } message ProxyProtocolConfig { @@ -81,6 +102,9 @@ message ProxyProtocolConfig { // at the transport socket level and override them at the host level. // - Any TLV defined in the ``pass_through_tlvs`` field will be overridden by either the host-level // or transport socket-level TLV. + // + // If there are multiple TLVs with the same type, only the TLVs from the highest precedence level + // will be used. repeated TlvEntry added_tlvs = 3; } diff --git a/src/main/proto/envoy/config/endpoint/v3/load_report.proto b/src/main/proto/envoy/config/endpoint/v3/load_report.proto index 32bbfe2..6d12765 100644 --- a/src/main/proto/envoy/config/endpoint/v3/load_report.proto +++ b/src/main/proto/envoy/config/endpoint/v3/load_report.proto @@ -38,7 +38,8 @@ message UpstreamLocalityStats { // locality. uint64 total_successful_requests = 2; - // The total number of unfinished requests + // The total number of unfinished requests. A request can be an HTTP request + // or a TCP connection for a TCP connection pool. uint64 total_requests_in_progress = 3; // The total number of requests that failed due to errors at the endpoint, @@ -47,7 +48,8 @@ message UpstreamLocalityStats { // The total number of requests that were issued by this Envoy since // the last report. This information is aggregated over all the - // upstream endpoints in the locality. + // upstream endpoints in the locality. A request can be an HTTP request + // or a TCP connection for a TCP connection pool. uint64 total_issued_requests = 8; // The total number of connections in an established state at the time of the diff --git a/src/main/proto/envoy/config/listener/v3/listener.proto b/src/main/proto/envoy/config/listener/v3/listener.proto index ff2f79d..772f4cd 100644 --- a/src/main/proto/envoy/config/listener/v3/listener.proto +++ b/src/main/proto/envoy/config/listener/v3/listener.proto @@ -15,7 +15,6 @@ import "envoy/config/listener/v3/udp_listener_config.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; -import "xds/annotations/v3/status.proto"; import "xds/core/v3/collection_entry.proto"; import "xds/type/matcher/v3/matcher.proto"; @@ -46,6 +45,14 @@ message AdditionalAddress { // or an empty list of :ref:`socket_options `, // it means no socket option will apply. core.v3.SocketOptionsOverride socket_options = 2; + + // Configures TCP keepalive settings for the additional address. + // If not set, the listener :ref:`tcp_keepalive ` + // configuration is inherited. You can explicitly disable TCP keepalive for the additional address by setting any keepalive field + // (:ref:`keepalive_probes `, + // :ref:`keepalive_time `, or + // :ref:`keepalive_interval `) to ``0``. + core.v3.TcpKeepalive tcp_keepalive = 3; } // Listener list collections. Entries are ``Listener`` resources or references. @@ -54,7 +61,7 @@ message ListenerCollection { repeated xds.core.v3.CollectionEntry entries = 1; } -// [#next-free-field: 37] +// [#next-free-field: 38] message Listener { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener"; @@ -107,7 +114,9 @@ message Listener { // The listener will use the connection balancer according to ``type_url``. If ``type_url`` is invalid, // Envoy will not attempt to balance active connections between worker threads. - // [#extension-category: envoy.network.connection_balance] + // The ``envoy.network.connection_balance`` extension category is currently empty + // because the only registered member (``envoy.network.connection_balance.dlb``) + // is disabled. See https://github.com/envoyproxy/envoy/issues/45491. core.v3.TypedExtensionConfig extend_balance = 2; } } @@ -141,6 +150,12 @@ message Listener { // that is governed by the bind rules of the OS. E.g., multiple listeners can listen on port 0 on // Linux as the actual port will be allocated by the OS. // Required unless ``api_listener`` or ``listener_specifier`` is populated. + // + // When the address contains a network namespace filepath (via + // :ref:`network_namespace_filepath `), + // Envoy automatically populates the filter state with key ``envoy.network.network_namespace`` + // when a connection is accepted. This provides read-only access to the network namespace for + // filters, access logs, and other components. core.v3.Address address = 2; // The additional addresses the listener should listen on. The addresses must be unique across all @@ -184,8 +199,7 @@ message Listener { // connections bound to the filter chain are not drained. If, however, the // filter chain is removed or structurally modified, then the drain for its // connections is initiated. - xds.type.matcher.v3.Matcher filter_chain_matcher = 32 - [(xds.annotations.v3.field_status).work_in_progress = true]; + xds.type.matcher.v3.Matcher filter_chain_matcher = 32; // If a connection is redirected using ``iptables``, the port on which the proxy // receives it might be different from the original destination address. When this flag is set to @@ -416,6 +430,12 @@ message Listener { // Whether the listener bypasses configured overload manager actions. bool bypass_overload_manager = 35; + + // If set, TCP keepalive settings are configured for the listener address and inherited by + // additional addresses. If not set, TCP keepalive settings are not configured for the + // listener address and additional addresses by default. See :ref:`tcp_keepalive ` + // to explicitly configure TCP keepalive settings for individual additional addresses. + core.v3.TcpKeepalive tcp_keepalive = 37; } // A placeholder proto so that users can explicitly configure the standard diff --git a/src/main/proto/envoy/config/listener/v3/listener_components.proto b/src/main/proto/envoy/config/listener/v3/listener_components.proto index 33eb349..16b4356 100644 --- a/src/main/proto/envoy/config/listener/v3/listener_components.proto +++ b/src/main/proto/envoy/config/listener/v3/listener_components.proto @@ -233,7 +233,7 @@ message FilterChain { google.protobuf.BoolValue use_proxy_proto = 4 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // [#not-implemented-hide:] filter chain metadata. + // Filter chain metadata. core.v3.Metadata metadata = 5; // Optional custom transport socket implementation to use for downstream connections. @@ -250,9 +250,11 @@ message FilterChain { google.protobuf.Duration transport_socket_connect_timeout = 9; // The unique name (or empty) by which this filter chain is known. - // Note: :ref:`filter_chain_matcher - // ` - // requires that filter chains are uniquely named within a listener. + // + // .. note:: + // :ref:`filter_chain_matcher + // ` + // requires that filter chains are uniquely named within a listener. string name = 7; } diff --git a/src/main/proto/envoy/config/listener/v3/quic_config.proto b/src/main/proto/envoy/config/listener/v3/quic_config.proto index 6c0a5bd..c208a58 100644 --- a/src/main/proto/envoy/config/listener/v3/quic_config.proto +++ b/src/main/proto/envoy/config/listener/v3/quic_config.proto @@ -25,7 +25,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: QUIC listener config] // Configuration specific to the UDP QUIC listener. -// [#next-free-field: 14] +// [#next-free-field: 15] message QuicProtocolOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.listener.QuicProtocolOptions"; @@ -99,4 +99,10 @@ message QuicProtocolOptions { // QUIC layer by replying with an empty version negotiation packet to the // client. bool reject_new_connections = 13; + + // Maximum number of QUIC sessions to create per event loop. + // If not specified, the default value is 16. + // This is an equivalent of the TCP listener option + // max_connections_to_accept_per_socket_event. + google.protobuf.UInt32Value max_sessions_per_event_loop = 14 [(validate.rules).uint32 = {gt: 0}]; } diff --git a/src/main/proto/envoy/config/metrics/v3/metrics_service.proto b/src/main/proto/envoy/config/metrics/v3/metrics_service.proto index 1c465b5..24b44b0 100644 --- a/src/main/proto/envoy/config/metrics/v3/metrics_service.proto +++ b/src/main/proto/envoy/config/metrics/v3/metrics_service.proto @@ -45,7 +45,7 @@ enum HistogramEmitMode { // "@type": type.googleapis.com/envoy.config.metrics.v3.MetricsServiceConfig // // [#extension: envoy.stat_sinks.metrics_service] -// [#next-free-field: 6] +// [#next-free-field: 7] message MetricsServiceConfig { option (udpa.annotations.versioning).previous_message_type = "envoy.config.metrics.v2.MetricsServiceConfig"; @@ -70,4 +70,11 @@ message MetricsServiceConfig { // Specify which metrics types to emit for histograms. Defaults to SUMMARY_AND_HISTOGRAM. HistogramEmitMode histogram_emit_mode = 5 [(validate.rules).enum = {defined_only: true}]; + + // The maximum number of metrics to send in a single gRPC message. If not set or set to 0, + // all metrics will be sent in a single message (current behavior). When set to a positive value, + // metrics will be batched into multiple messages, with each message containing at most batch_size + // metric families. This helps avoid hitting gRPC message size limits (typically 4MB) when sending + // large numbers of metrics. + uint32 batch_size = 6 [(validate.rules).uint32 = {gte: 0}]; } diff --git a/src/main/proto/envoy/config/metrics/v3/stats.proto b/src/main/proto/envoy/config/metrics/v3/stats.proto index e7d7f80..0fcf36c 100644 --- a/src/main/proto/envoy/config/metrics/v3/stats.proto +++ b/src/main/proto/envoy/config/metrics/v3/stats.proto @@ -60,11 +60,6 @@ message StatsConfig { // `. They will be processed before // the custom tags. // - // .. note:: - // - // If any default tags are specified twice, the config will be considered - // invalid. - // // See :repo:`well_known_names.h ` for a list of the // default tags in Envoy. // @@ -298,10 +293,12 @@ message HistogramBucketSettings { // Each value is the upper bound of a bucket. Each bucket must be greater than 0 and unique. // The order of the buckets does not matter. repeated double buckets = 2 [(validate.rules).repeated = { - min_items: 1 unique: true items {double {gt: 0.0}} }]; + + // Initial number of bins for the ``circllhist`` thread local histogram per time series. Default value is 100. + google.protobuf.UInt32Value bins = 3 [(validate.rules).uint32 = {lte: 46082 gt: 0}]; } // Stats configuration proto schema for built-in ``envoy.stat_sinks.statsd`` sink. This sink does not support diff --git a/src/main/proto/envoy/config/overload/v3/overload.proto b/src/main/proto/envoy/config/overload/v3/overload.proto index 1f267c1..b5bc2c4 100644 --- a/src/main/proto/envoy/config/overload/v3/overload.proto +++ b/src/main/proto/envoy/config/overload/v3/overload.proto @@ -109,6 +109,13 @@ message ScaleTimersOverloadActionConfig { // :ref:`HttpConnectionManager.common_http_protocol_options.max_connection_duration // `. HTTP_DOWNSTREAM_CONNECTION_MAX = 4; + + // Adjusts the timeout for the downstream codec to flush an ended stream. + // This affects the value of :ref:`RouteAction.flush_timeout + // ` and + // :ref:`HttpConnectionManager.stream_flush_timeout + // ` + HTTP_DOWNSTREAM_STREAM_FLUSH = 5; } message ScaleTimer { @@ -134,9 +141,16 @@ message OverloadAction { option (udpa.annotations.versioning).previous_message_type = "envoy.config.overload.v2alpha.OverloadAction"; - // The name of the overload action. This is just a well-known string that listeners can - // use for registering callbacks. Custom overload actions should be named using reverse - // DNS to ensure uniqueness. + // The name of the overload action. This is just a well-known string that + // listeners can use for registering callbacks. + // Valid known overload actions include: + // - envoy.overload_actions.stop_accepting_requests + // - envoy.overload_actions.disable_http_keepalive + // - envoy.overload_actions.stop_accepting_connections + // - envoy.overload_actions.reject_incoming_connections + // - envoy.overload_actions.shrink_heap + // - envoy.overload_actions.reduce_timeouts + // - envoy.overload_actions.reset_high_memory_stream string name = 1 [(validate.rules).string = {min_len: 1}]; // A set of triggers for this action. The state of the action is the maximum @@ -148,7 +162,7 @@ message OverloadAction { // in this list. repeated Trigger triggers = 2 [(validate.rules).repeated = {min_items: 1}]; - // Configuration for the action being instantiated. + // Configuration for the action being instantiated if applicable. google.protobuf.Any typed_config = 3; } diff --git a/src/main/proto/envoy/config/rbac/v3/rbac.proto b/src/main/proto/envoy/config/rbac/v3/rbac.proto index cdb1267..ef153ad 100644 --- a/src/main/proto/envoy/config/rbac/v3/rbac.proto +++ b/src/main/proto/envoy/config/rbac/v3/rbac.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package envoy.config.rbac.v3; import "envoy/config/core/v3/address.proto"; +import "envoy/config/core/v3/cel.proto"; import "envoy/config/core/v3/extension.proto"; import "envoy/config/route/v3/route_components.proto"; import "envoy/type/matcher/v3/filter_state.proto"; @@ -173,6 +174,7 @@ message RBAC { // A policy matches if and only if at least one of its permissions match the // action taking place AND at least one of its principals match the downstream // AND the condition is true if specified. +// [#next-free-field: 6] message Policy { option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Policy"; @@ -199,6 +201,12 @@ message Policy { // Only be used when condition is not used. google.api.expr.v1alpha1.CheckedExpr checked_condition = 4 [(udpa.annotations.field_migrate).oneof_promotion = "expression_specifier"]; + + // CEL expression configuration that modifies the evaluation behavior of the ``condition`` field. + // If specified, string conversion, concatenation, and manipulation functions may be enabled + // for the CEL expression. See :ref:`CelExpressionConfig ` + // for more details. + core.v3.CelExpressionConfig cel_config = 5; } // SourcedMetadata enables matching against metadata from different sources in the request processing diff --git a/src/main/proto/envoy/config/route/v3/route.proto b/src/main/proto/envoy/config/route/v3/route.proto index c4d507d..5bd909f 100644 --- a/src/main/proto/envoy/config/route/v3/route.proto +++ b/src/main/proto/envoy/config/route/v3/route.proto @@ -23,7 +23,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // * Routing :ref:`architecture overview ` // * HTTP :ref:`router filter ` -// [#next-free-field: 18] +// [#next-free-field: 19] message RouteConfiguration { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.RouteConfiguration"; @@ -129,10 +129,17 @@ message RouteConfiguration { // By default, port in :authority header (if any) is used in host matching. // With this option enabled, Envoy will ignore the port number in the :authority header (if any) when picking VirtualHost. - // NOTE: this option will not strip the port number (if any) contained in route config - // :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`.domains field. + // + // .. note:: + // This option will not strip the port number (if any) contained in route config + // :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`.domains field. bool ignore_port_in_host_matching = 14; + // Normally, virtual host matching is done using the :authority (or + // Host: in HTTP < 2) HTTP header. Setting this will instead, use a + // different HTTP header for this purpose. + string vhost_header = 18; + // Ignore path-parameters in path-matching. // Before RFC3986, URI were like(RFC1808): :///;?# // Envoy by default takes ":path" as ";". diff --git a/src/main/proto/envoy/config/route/v3/route_components.proto b/src/main/proto/envoy/config/route/v3/route_components.proto index 292e5b9..4587ef1 100644 --- a/src/main/proto/envoy/config/route/v3/route_components.proto +++ b/src/main/proto/envoy/config/route/v3/route_components.proto @@ -2,9 +2,11 @@ syntax = "proto3"; package envoy.config.route.v3; +import "envoy/config/common/mutation_rules/v3/mutation_rules.proto"; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/proxy_protocol.proto"; +import "envoy/config/core/v3/substitution_format_string.proto"; import "envoy/type/matcher/v3/filter_state.proto"; import "envoy/type/matcher/v3/metadata.proto"; import "envoy/type/matcher/v3/regex.proto"; @@ -41,7 +43,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // host header. This allows a single listener to service multiple top level domain path trees. Once // a virtual host is selected based on the domain, the routes are processed in order to see which // upstream cluster to route to or whether to perform a redirect. -// [#next-free-field: 25] +// [#next-free-field: 26] message VirtualHost { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.VirtualHost"; @@ -78,7 +80,7 @@ message VirtualHost { // .. note:: // // The wildcard will not match the empty string. - // e.g. ``*-bar.foo.com`` will match ``baz-bar.foo.com`` but not ``-bar.foo.com``. + // For example, ``*-bar.foo.com`` will match ``baz-bar.foo.com`` but not ``-bar.foo.com``. // The longest wildcards match first. // Only a single virtual host in the entire route configuration can match on ``*``. A domain // must be unique across all virtual hosts or the config will fail to load. @@ -155,7 +157,7 @@ message VirtualHost { // This field can be used to provide virtual host level per filter config. The key should match the // :ref:`filter config name // `. - // See :ref:`Http filter route specific config ` + // See :ref:`HTTP filter route-specific config ` // for details. // [#comment: An entry's value may be wrapped in a // :ref:`FilterConfig` @@ -166,7 +168,10 @@ message VirtualHost { // ` header should be included // in the upstream request. Setting this option will cause it to override any existing header // value, so in the case of two Envoys on the request path with this option enabled, the upstream - // will see the attempt count as perceived by the second Envoy. Defaults to false. + // will see the attempt count as perceived by the second Envoy. + // + // Defaults to ``false``. + // // This header is unaffected by the // :ref:`suppress_envoy_headers // ` flag. @@ -178,7 +183,10 @@ message VirtualHost { // ` header should be included // in the downstream response. Setting this option will cause the router to override any existing header // value, so in the case of two Envoys on the request path with this option enabled, the downstream - // will see the attempt count as perceived by the Envoy closest upstream from itself. Defaults to false. + // will see the attempt count as perceived by the Envoy closest upstream from itself. + // + // Defaults to ``false``. + // // This header is unaffected by the // :ref:`suppress_envoy_headers // ` flag. @@ -186,29 +194,56 @@ message VirtualHost { // Indicates the retry policy for all routes in this virtual host. Note that setting a // route level entry will take precedence over this config and it'll be treated - // independently (e.g.: values are not inherited). + // independently (e.g., values are not inherited). RetryPolicy retry_policy = 16; // [#not-implemented-hide:] // Specifies the configuration for retry policy extension. Note that setting a route level entry - // will take precedence over this config and it'll be treated independently (e.g.: values are not + // will take precedence over this config and it'll be treated independently (e.g., values are not // inherited). :ref:`Retry policy ` should not be // set if this field is used. google.protobuf.Any retry_policy_typed_config = 20; // Indicates the hedge policy for all routes in this virtual host. Note that setting a // route level entry will take precedence over this config and it'll be treated - // independently (e.g.: values are not inherited). + // independently (e.g., values are not inherited). HedgePolicy hedge_policy = 17; // Decides whether to include the :ref:`x-envoy-is-timeout-retry ` - // request header in retries initiated by per try timeouts. + // request header in retries initiated by per-try timeouts. bool include_is_timeout_retry_header = 23; - // The maximum bytes which will be buffered for retries and shadowing. - // If set and a route-specific limit is not set, the bytes actually buffered will be the minimum - // value of this and the listener per_connection_buffer_limit_bytes. - google.protobuf.UInt32Value per_request_buffer_limit_bytes = 18; + // The maximum bytes which will be buffered for retries and shadowing. If set, the bytes actually buffered will be + // the minimum value of this and the listener ``per_connection_buffer_limit_bytes``. + // + // .. attention:: + // + // This field has been deprecated. Please use :ref:`request_body_buffer_limit + // ` instead. + // Only one of ``per_request_buffer_limit_bytes`` and ``request_body_buffer_limit`` could be set. + google.protobuf.UInt32Value per_request_buffer_limit_bytes = 18 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // The maximum bytes which will be buffered for request bodies to support large request body + // buffering beyond the ``per_connection_buffer_limit_bytes``. + // + // This limit is specifically for the request body buffering and allows buffering larger payloads while maintaining + // flow control. + // + // Buffer limit precedence (from highest to lowest priority): + // + // 1. If ``request_body_buffer_limit`` is set, then ``request_body_buffer_limit`` will be used. + // 2. If :ref:`per_request_buffer_limit_bytes ` + // is set but ``request_body_buffer_limit`` is not, then ``min(per_request_buffer_limit_bytes, per_connection_buffer_limit_bytes)`` + // will be used. + // 3. If neither is set, then ``per_connection_buffer_limit_bytes`` will be used. + // + // For flow control chunk sizes, ``min(per_connection_buffer_limit_bytes, 16KB)`` will be used. + // + // Only one of :ref:`per_request_buffer_limit_bytes ` + // and ``request_body_buffer_limit`` could be set. + google.protobuf.UInt64Value request_body_buffer_limit = 25 + [(validate.rules).message = {required: false}]; // Specify a set of default request mirroring policies for every route under this virtual host. // It takes precedence over the route config mirror policy entirely. @@ -244,7 +279,7 @@ message RouteList { // // Envoy supports routing on HTTP method via :ref:`header matching // `. -// [#next-free-field: 20] +// [#next-free-field: 21] message Route { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.Route"; @@ -297,7 +332,7 @@ message Route { // This field can be used to provide route specific per filter config. The key should match the // :ref:`filter config name // `. - // See :ref:`Http filter route specific config ` + // See :ref:`HTTP filter route-specific config ` // for details. // [#comment: An entry's value may be wrapped in a // :ref:`FilterConfig` @@ -341,7 +376,14 @@ message Route { // The maximum bytes which will be buffered for retries and shadowing. // If set, the bytes actually buffered will be the minimum value of this and the // listener per_connection_buffer_limit_bytes. - google.protobuf.UInt32Value per_request_buffer_limit_bytes = 16; + // + // .. attention:: + // + // This field has been deprecated. Please use :ref:`request_body_buffer_limit + // ` instead. + // Only one of ``per_request_buffer_limit_bytes`` and ``request_body_buffer_limit`` may be set. + google.protobuf.UInt32Value per_request_buffer_limit_bytes = 16 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // The human readable prefix to use when emitting statistics for this endpoint. // The statistics are rooted at vhost..route.. @@ -355,8 +397,27 @@ message Route { // // We do not recommend setting up a stat prefix for // every application endpoint. This is both not easily maintainable and - // statistics use a non-trivial amount of memory(approximately 1KiB per route). + // statistics use a non-trivial amount of memory (approximately 1KiB per route). string stat_prefix = 19; + + // The maximum bytes which will be buffered for request bodies to support large request body + // buffering beyond the ``per_connection_buffer_limit_bytes``. + // + // This limit is specifically for the request body buffering and allows buffering larger payloads while maintaining + // flow control. + // + // Buffer limit precedence (from highest to lowest priority): + // + // 1. If ``request_body_buffer_limit`` is set: use ``request_body_buffer_limit`` + // 2. If :ref:`per_request_buffer_limit_bytes ` + // is set but ``request_body_buffer_limit`` is not: use ``min(per_request_buffer_limit_bytes, per_connection_buffer_limit_bytes)`` + // 3. If neither is set: use ``per_connection_buffer_limit_bytes`` + // + // For flow control chunk sizes, use ``min(per_connection_buffer_limit_bytes, 16KB)``. + // + // Only one of :ref:`per_request_buffer_limit_bytes ` + // and ``request_body_buffer_limit`` may be set. + google.protobuf.UInt64Value request_body_buffer_limit = 20; } // Compared to the :ref:`cluster ` field that specifies a @@ -365,6 +426,7 @@ message Route { // multiple upstream clusters along with weights that indicate the percentage of // traffic to be forwarded to each cluster. The router selects an upstream cluster based on the // weights. +// [#next-free-field: 6] message WeightedCluster { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.WeightedCluster"; @@ -452,7 +514,7 @@ message WeightedCluster { // This field can be used to provide weighted cluster specific per filter config. The key should match the // :ref:`filter config name // `. - // See :ref:`Http filter route specific config ` + // See :ref:`HTTP filter route-specific config ` // for details. // [#comment: An entry's value may be wrapped in a // :ref:`FilterConfig` @@ -495,6 +557,10 @@ message WeightedCluster { // the process for the consistency. And the value is a unsigned number between 0 and UINT64_MAX. string header_name = 4 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME strict: false}]; + + // When set to true, the hash policies will be used to generate the random value for weighted cluster selection. + // This could ensure consistent cluster picking across multiple proxy levels for weighted traffic. + google.protobuf.BoolValue use_hash_policy = 5; } } @@ -513,7 +579,7 @@ message ClusterSpecifierPlugin { bool is_optional = 2; } -// [#next-free-field: 17] +// [#next-free-field: 18] message RouteMatch { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RouteMatch"; @@ -571,7 +637,7 @@ message RouteMatch { // // [#next-major-version: In the v3 API we should redo how path specification works such // that we utilize StringMatcher, and additionally have consistent options around whether we - // strip query strings, do a case sensitive match, etc. In the interim it will be too disruptive + // strip query strings, do a case-sensitive match, etc. In the interim it will be too disruptive // to deprecate the existing options. We should even consider whether we want to do away with // path_specifier entirely and just rely on a set of header matchers which can already match // on :path, etc. The issue with that is it is unclear how to generically deal with query string @@ -603,7 +669,7 @@ message RouteMatch { core.v3.TypedExtensionConfig path_match_policy = 15; } - // Indicates that prefix/path matching should be case sensitive. The default + // Indicates that prefix/path matching should be case-sensitive. The default // is true. Ignored for safe_regex matching. google.protobuf.BoolValue case_sensitive = 4; @@ -643,14 +709,19 @@ message RouteMatch { // // If query parameters are used to pass request message fields when // `grpc_json_transcoder `_ - // is used, the transcoded message fields maybe different. The query parameters are - // url encoded, but the message fields are not. For example, if a query + // is used, the transcoded message fields may be different. The query parameters are + // URL-encoded, but the message fields are not. For example, if a query // parameter is "foo%20bar", the message field will be "foo bar". repeated QueryParameterMatcher query_parameters = 7; + // Specifies a set of cookies on which the route should match. The router parses the ``Cookie`` + // header and evaluates the named cookie against each matcher. If the number of specified cookie + // matchers is nonzero, they all must match for the route to be selected. + repeated CookieMatcher cookies = 17; + // If specified, only gRPC requests will be matched. The router will check - // that the content-type header has a application/grpc or one of the various - // application/grpc+ values. + // that the ``Content-Type`` header has ``application/grpc`` or one of the various + // ``application/grpc+`` values. GrpcRouteMatchOptions grpc = 8; // If specified, the client tls context will be matched against the defined @@ -736,11 +807,11 @@ message CorsPolicy { google.protobuf.BoolValue allow_private_network_access = 12; // Specifies if preflight requests not matching the configured allowed origin should be forwarded - // to the upstream. Default is true. + // to the upstream. Default is ``true``. google.protobuf.BoolValue forward_not_matching_preflights = 13; } -// [#next-free-field: 42] +// [#next-free-field: 46] message RouteAction { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RouteAction"; @@ -779,8 +850,8 @@ message RouteAction { // // .. note:: // - // Shadowing doesn't support Http CONNECT and upgrades. - // [#next-free-field: 7] + // Shadowing doesn't support HTTP CONNECT and upgrades. + // [#next-free-field: 9] message RequestMirrorPolicy { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RouteAction.RequestMirrorPolicy"; @@ -830,8 +901,24 @@ message RouteAction { // is disabled. google.protobuf.BoolValue trace_sampled = 4; - // Disables appending the ``-shadow`` suffix to the shadowed ``Host`` header. Defaults to ``false``. + // Disables appending the ``-shadow`` suffix to the shadowed ``Host`` header. + // + // Defaults to ``false``. bool disable_shadow_host_suffix_append = 6; + + // Specifies a list of header mutations that should be applied to each mirrored request. + // Header mutations are applied in the order they are specified. For more information, including + // details on header value syntax, see the documentation on :ref:`custom request headers + // `. + repeated common.mutation_rules.v3.HeaderMutation request_headers_mutations = 7 + [(validate.rules).repeated = {max_items: 1000}]; + + // Indicates that during mirroring, the host header will be swapped with this value. + // :ref:`disable_shadow_host_suffix_append + // ` + // is implicitly enabled if this field is set. + string host_rewrite_literal = 8 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}]; } // Specifies the route's hashing policy if the upstream cluster uses a hashing :ref:`load balancer @@ -993,13 +1080,15 @@ message RouteAction { bool allow_post = 2; } - // The case-insensitive name of this upgrade, e.g. "websocket". + // The case-insensitive name of this upgrade, for example, "websocket". // For each upgrade type present in upgrade_configs, requests with // Upgrade: [upgrade_type] will be proxied upstream. string upgrade_type = 1 [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_VALUE strict: false}]; - // Determines if upgrades are available on this route. Defaults to true. + // Determines if upgrades are available on this route. + // + // Defaults to ``true``. google.protobuf.BoolValue enabled = 2; // Configuration for sending data upstream as a raw data payload. This is used for @@ -1098,9 +1187,11 @@ message RouteAction { // place the original path before rewrite into the :ref:`x-envoy-original-path // ` header. // - // Only one of :ref:`regex_rewrite ` + // Only one of :ref:`regex_rewrite `, // :ref:`path_rewrite_policy `, - // or :ref:`prefix_rewrite ` may be specified. + // :ref:`path_rewrite `, + // or :ref:`prefix_rewrite ` + // may be specified. // // .. attention:: // @@ -1136,8 +1227,9 @@ message RouteAction { // ` header. // // Only one of :ref:`regex_rewrite `, - // :ref:`prefix_rewrite `, or - // :ref:`path_rewrite_policy `] + // :ref:`path_rewrite_policy `, + // :ref:`path_rewrite `, + // or :ref:`prefix_rewrite ` // may be specified. // // Examples using Google's `RE2 `_ engine: @@ -1161,6 +1253,33 @@ message RouteAction { // [#extension-category: envoy.path.rewrite] core.v3.TypedExtensionConfig path_rewrite_policy = 41; + // Rewrites the whole path (without query parameters) with the given path value. + // The router filter will + // place the original path before rewrite into the :ref:`x-envoy-original-path + // ` header. + // + // Only one of :ref:`regex_rewrite `, + // :ref:`path_rewrite_policy `, + // :ref:`path_rewrite `, + // or :ref:`prefix_rewrite ` + // may be specified. + // + // The :ref:`substitution format specifier ` could be applied here. + // For example, with the following config: + // + // .. code-block:: yaml + // + // path_rewrite: "/new_path_prefix%REQ(custom-path-header-name)%" + // + // Would rewrite the path to ``/new_path_prefix/some_value`` given the header + // ``custom-path-header-name: some_value``. If the header is not present, the path will be + // rewritten to ``/new_path_prefix``. + // + // + // If the final output of the path rewrite is empty, then the update will be ignored and the + // original path will be preserved. + string path_rewrite = 45; + // If one of the host rewrite specifiers is set and the // :ref:`suppress_envoy_headers // ` flag is not @@ -1219,6 +1338,25 @@ message RouteAction { // // Would rewrite the host header to ``envoyproxy.io`` given the path ``/envoyproxy.io/some/path``. type.matcher.v3.RegexMatchAndSubstitute host_rewrite_path_regex = 35; + + // Rewrites the host header with the value of this field. The router filter will + // place the original host header value before rewriting into the :ref:`x-envoy-original-host + // ` header. + // + // The :ref:`substitution format specifier ` could be applied here. + // For example, with the following config: + // + // .. code-block:: yaml + // + // host_rewrite: "prefix-%REQ(custom-host-header-name)%" + // + // Would rewrite the host header to ``prefix-some_value`` given the header + // ``custom-host-header-name: some_value``. If the header is not present, the host header will + // be rewritten to an value of ``prefix-``. + // + // If the final output of the host rewrite is empty, then the update will be ignored and the + // original host header will be preserved. + string host_rewrite = 44; } // If set, then a host rewrite action (one of @@ -1265,8 +1403,28 @@ message RouteAction { // If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" // is configured, this timeout is scaled according to the value for // :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. + // + // This timeout may also be used in place of ``flush_timeout`` in very specific cases. See the + // documentation for ``flush_timeout`` for more details. google.protobuf.Duration idle_timeout = 24; + // Specifies the codec stream flush timeout for the route. + // + // If not specified, the first preference is the global :ref:`stream_flush_timeout + // `, + // but only if explicitly configured. + // + // If neither the explicit HCM-wide flush timeout nor this route-specific flush timeout is configured, + // the route's stream idle timeout is reused for this timeout. This is for + // backwards compatibility since both behaviors were historically controlled by the one timeout. + // + // If the route also does not have an idle timeout configured, the global :ref:`stream_idle_timeout + // `. used, again + // for backwards compatibility. That timeout defaults to 5 minutes. + // + // A value of 0 via any of the above paths will completely disable the timeout for a given route. + google.protobuf.Duration flush_timeout = 42; + // Specifies how to send request over TLS early data. // If absent, allows `safe HTTP requests `_ to be sent on early data. // [#extension-category: envoy.route.early_data_policy] @@ -1274,13 +1432,13 @@ message RouteAction { // Indicates that the route has a retry policy. Note that if this is set, // it'll take precedence over the virtual host level retry policy entirely - // (e.g.: policies are not merged, most internal one becomes the enforced policy). + // (e.g., policies are not merged, the most internal one becomes the enforced policy). RetryPolicy retry_policy = 9; // [#not-implemented-hide:] // Specifies the configuration for retry policy extension. Note that if this is set, it'll take - // precedence over the virtual host level retry policy entirely (e.g.: policies are not merged, - // most internal one becomes the enforced policy). :ref:`Retry policy ` + // precedence over the virtual host level retry policy entirely (e.g., policies are not merged, + // the most internal one becomes the enforced policy). :ref:`Retry policy ` // should not be set if this field is used. google.protobuf.Any retry_policy_typed_config = 33; @@ -1301,7 +1459,9 @@ message RouteAction { // :ref:`rate_limits ` are not applied to the // request. // - // This field is deprecated. Please use :ref:`vh_rate_limits ` + // .. attention:: + // + // This field is deprecated. Please use :ref:`vh_rate_limits ` google.protobuf.BoolValue include_vh_rate_limits = 14 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; @@ -1395,7 +1555,7 @@ message RouteAction { // Indicates that the route has a hedge policy. Note that if this is set, // it'll take precedence over the virtual host level hedge policy entirely - // (e.g.: policies are not merged, most internal one becomes the enforced policy). + // (e.g., policies are not merged, the most internal one becomes the enforced policy). HedgePolicy hedge_policy = 27; // Specifies the maximum stream duration for this route. @@ -1529,7 +1689,9 @@ message RetryPolicy { // Specifies the maximum back off interval that Envoy will allow. If a reset // header contains an interval longer than this then it will be discarded and - // the next header will be tried. Defaults to 300 seconds. + // the next header will be tried. + // + // Defaults to 300 seconds. google.protobuf.Duration max_interval = 2 [(validate.rules).duration = {gt {}}]; } @@ -1558,7 +1720,7 @@ message RetryPolicy { google.protobuf.Duration per_try_timeout = 3; // Specifies an upstream idle timeout per retry attempt (including the initial attempt). This - // parameter is optional and if absent there is no per try idle timeout. The semantics of the per + // parameter is optional and if absent there is no per-try idle timeout. The semantics of the per- // try idle timeout are similar to the // :ref:`route idle timeout ` and // :ref:`stream idle timeout @@ -1633,12 +1795,14 @@ message HedgePolicy { // Specifies the number of initial requests that should be sent upstream. // Must be at least 1. + // // Defaults to 1. // [#not-implemented-hide:] google.protobuf.UInt32Value initial_requests = 1 [(validate.rules).uint32 = {gte: 1}]; // Specifies a probability that an additional upstream request should be sent // on top of what is specified by initial_requests. + // // Defaults to 0. // [#not-implemented-hide:] type.v3.FractionalPercent additional_request_chance = 2; @@ -1648,14 +1812,16 @@ message HedgePolicy { // The first request to complete successfully will be the one returned to the caller. // // * At any time, a successful response (i.e. not triggering any of the retry-on conditions) would be returned to the client. - // * Before per-try timeout, an error response (per retry-on conditions) would be retried immediately or returned ot the client + // * Before per-try timeout, an error response (per retry-on conditions) would be retried immediately or returned to the client // if there are no more retries left. // * After per-try timeout, an error response would be discarded, as a retry in the form of a hedged request is already in progress. // - // Note: For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least - // one error code and specifies a maximum number of retries. + // .. note:: + // + // For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least + // one error code and specifies a maximum number of retries. // - // Defaults to false. + // Defaults to ``false``. bool hedge_on_per_try_timeout = 3; } @@ -1782,6 +1948,12 @@ message DirectResponseAction { // :ref:`envoy_v3_api_msg_config.route.v3.Route`, :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration` or // :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`. core.v3.DataSource body = 2; + + // Specifies a format string for the response body. If present, the contents of + // ``body_format`` will be formatted and used as the response body, where the + // contents of ``body`` (may be empty) will be passed as the variable ``%LOCAL_REPLY_BODY%``. + // If neither are provided, no body is included in the generated response. + core.v3.SubstitutionFormatString body_format = 3; } // [#not-implemented-hide:] @@ -1801,10 +1973,11 @@ message Decorator { // ` header. string operation = 1 [(validate.rules).string = {min_len: 1}]; - // Whether the decorated details should be propagated to the other party. The default is true. + // Whether the decorated details should be propagated to the other party. The default is ``true``. google.protobuf.BoolValue propagate = 2; } +// [#next-free-field: 7] message Tracing { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.Tracing"; @@ -1840,6 +2013,34 @@ message Tracing { // each in the HTTP connection manager and the route level, the one configured here takes // priority. repeated type.tracing.v3.CustomTag custom_tags = 4; + + // The operation name of the span which will be used for tracing. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + // + // This field will take precedence over and make following settings ineffective: + // + // * :ref:`route decorator `. + // * :ref:`x-envoy-decorator-operation `. + // * :ref:`HCM tracing operation + // `. + string operation = 5; + + // The operation name of the upstream span which will be used for tracing. + // This only takes effect when ``spawn_upstream_span`` is set to true and the upstream + // span is created. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + // + // This field will take precedence over and make following settings ineffective: + // + // * :ref:`HCM tracing upstream operation + // ` + string upstream_operation = 6; } // A virtual cluster is a way of specifying a regex matching rule against @@ -1966,7 +2167,7 @@ message RateLimit { // the value of the descriptor entry for the descriptor_key. string query_parameter_name = 1 [(validate.rules).string = {min_len: 1}]; - // The key to use when creating the rate limit descriptor entry. his descriptor key will be used to identify the + // The key to use when creating the rate limit descriptor entry. This descriptor key will be used to identify the // rate limit rule in the rate limiting service. string descriptor_key = 2 [(validate.rules).string = {min_len: 1}]; @@ -2004,14 +2205,18 @@ message RateLimit { // ("masked_remote_address", "") message MaskedRemoteAddress { // Length of prefix mask len for IPv4 (e.g. 0, 32). + // // Defaults to 32 when unset. + // // For example, trusted address from x-forwarded-for is ``192.168.1.1``, // the descriptor entry is ("masked_remote_address", "192.168.1.1/32"); // if mask len is 24, the descriptor entry is ("masked_remote_address", "192.168.1.0/24"). google.protobuf.UInt32Value v4_prefix_mask_len = 1 [(validate.rules).uint32 = {lte: 32}]; // Length of prefix mask len for IPv6 (e.g. 0, 128). + // // Defaults to 128 when unset. + // // For example, trusted address from x-forwarded-for is ``2001:abcd:ef01:2345:6789:abcd:ef01:234``, // the descriptor entry is ("masked_remote_address", "2001:abcd:ef01:2345:6789:abcd:ef01:234/128"); // if mask len is 64, the descriptor entry is ("masked_remote_address", "2001:abcd:ef01:2345::/64"). @@ -2027,9 +2232,40 @@ message RateLimit { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RateLimit.Action.GenericKey"; - // The value to use in the descriptor entry. + // Descriptor value of entry. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + // + // .. note:: + // + // Formatter parsing is controlled by the runtime feature flag + // ``envoy.reloadable_features.enable_formatter_for_ratelimit_action_descriptor_value`` + // (disabled by default). + // + // When enabled: The format string can contain multiple valid substitution + // fields. If multiple substitution fields are present, their results will be concatenated + // to form the final descriptor value. If it contains no substitution fields, the value + // will be used as is. If the final concatenated result is empty and ``default_value`` is set, + // the ``default_value`` will be used. If ``default_value`` is not set and the result is + // empty, this descriptor will be skipped and not included in the rate limit call. + // + // When disabled (default): The descriptor_value is used as a literal string without any formatter + // parsing or substitution. + // + // For example, ``static_value`` will be used as is since there are no substitution fields. + // ``%REQ(:method)%`` will be replaced with the HTTP method, and + // ``%REQ(:method)%%REQ(:path)%`` will be replaced with the concatenation of the HTTP method and path. + // ``%CEL(request.headers['user-id'])%`` will use CEL to extract the user ID from request headers. + // string descriptor_value = 1 [(validate.rules).string = {min_len: 1}]; + // An optional value to use if the final concatenated ``descriptor_value`` result is empty. + // Only applicable when formatter parsing is enabled by the runtime feature flag + // ``envoy.reloadable_features.enable_formatter_for_ratelimit_action_descriptor_value`` (disabled by default). + string default_value = 3; + // An optional key to use in the descriptor entry. If not set it defaults // to 'generic_key' as the descriptor key. string descriptor_key = 2; @@ -2040,16 +2276,51 @@ message RateLimit { // .. code-block:: cpp // // ("header_match", "") + // [#next-free-field: 6] message HeaderValueMatch { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RateLimit.Action.HeaderValueMatch"; - // The key to use in the descriptor entry. Defaults to ``header_match``. - string descriptor_key = 4; - - // The value to use in the descriptor entry. + // Descriptor value of entry. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + // + // .. note:: + // + // Formatter parsing is controlled by the runtime feature flag + // ``envoy.reloadable_features.enable_formatter_for_ratelimit_action_descriptor_value`` + // (disabled by default). + // + // When enabled: The format string can contain multiple valid substitution + // fields. If multiple substitution fields are present, their results will be concatenated + // to form the final descriptor value. If it contains no substitution fields, the value + // will be used as is. All substitution fields will be evaluated and their results + // concatenated. If the final concatenated result is empty and ``default_value`` is set, + // the ``default_value`` will be used. If ``default_value`` is not set and the result is + // empty, this descriptor will be skipped and not included in the rate limit call. + // + // When disabled (default): The descriptor_value is used as a literal string without any formatter + // parsing or substitution. + // + // For example, ``static_value`` will be used as is since there are no substitution fields. + // ``%REQ(:method)%`` will be replaced with the HTTP method, and + // ``%REQ(:method)%%REQ(:path)%`` will be replaced with the concatenation of the HTTP method and path. + // ``%CEL(request.headers['user-id'])%`` will use CEL to extract the user ID from request headers. + // string descriptor_value = 1 [(validate.rules).string = {min_len: 1}]; + // An optional value to use if the final concatenated ``descriptor_value`` result is empty. + // Only applicable when formatter parsing is enabled by the runtime feature flag + // ``envoy.reloadable_features.enable_formatter_for_ratelimit_action_descriptor_value`` (disabled by default). + string default_value = 5; + + // The key to use in the descriptor entry. + // + // Defaults to ``header_match``. + string descriptor_key = 4; + // If set to true, the action will append a descriptor entry when the // request matches the headers. If set to false, the action will append a // descriptor entry when the request does not match the headers. The @@ -2057,7 +2328,7 @@ message RateLimit { google.protobuf.BoolValue expect_match = 2; // Specifies a set of headers that the rate limit action should match - // on. The action will check the request’s headers against all the + // on. The action will check the request's headers against all the // specified headers in the config. A match will happen if all the // headers in the config are present in the request with the same values // (or based on presence if the value field is not in the config). @@ -2137,13 +2408,48 @@ message RateLimit { // .. code-block:: cpp // // ("query_match", "") + // [#next-free-field: 6] message QueryParameterValueMatch { - // The key to use in the descriptor entry. Defaults to ``query_match``. - string descriptor_key = 4; - - // The value to use in the descriptor entry. + // Descriptor value of entry. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + // + // .. note:: + // + // Formatter parsing is controlled by the runtime feature flag + // ``envoy.reloadable_features.enable_formatter_for_ratelimit_action_descriptor_value`` + // (disabled by default). + // + // When enabled: The format string can contain multiple valid substitution + // fields. If multiple substitution fields are present, their results will be concatenated + // to form the final descriptor value. If it contains no substitution fields, the value + // will be used as is. All substitution fields will be evaluated and their results + // concatenated. If the final concatenated result is empty and ``default_value`` is set, + // the ``default_value`` will be used. If ``default_value`` is not set and the result is + // empty, this descriptor will be skipped and not included in the rate limit call. + // + // When disabled (default): The descriptor_value is used as a literal string without any formatter + // parsing or substitution. + // + // For example, ``static_value`` will be used as is since there are no substitution fields. + // ``%REQ(:method)%`` will be replaced with the HTTP method, and + // ``%REQ(:method)%%REQ(:path)%`` will be replaced with the concatenation of the HTTP method and path. + // ``%CEL(request.headers['user-id'])%`` will use CEL to extract the user ID from request headers. + // string descriptor_value = 1 [(validate.rules).string = {min_len: 1}]; + // An optional value to use if the final concatenated ``descriptor_value`` result is empty. + // Only applicable when formatter parsing is enabled by the runtime feature flag + // ``envoy.reloadable_features.enable_formatter_for_ratelimit_action_descriptor_value`` (disabled by default). + string default_value = 5; + + // The key to use in the descriptor entry. + // + // Defaults to ``query_match``. + string descriptor_key = 4; + // If set to true, the action will append a descriptor entry when the // request matches the headers. If set to false, the action will append a // descriptor entry when the request does not match the headers. The @@ -2151,7 +2457,7 @@ message RateLimit { google.protobuf.BoolValue expect_match = 2; // Specifies a set of query parameters that the rate limit action should match - // on. The action will check the request’s query parameters against all the + // on. The action will check the request's query parameters against all the // specified query parameters in the config. A match will happen if all the // query parameters in the config are present in the request with the same values // (or based on presence if the value field is not in the config). @@ -2368,14 +2674,20 @@ message HeaderMatcher { // Specifies how the header match will be performed to route the request. oneof header_match_specifier { // If specified, header match will be performed based on the value of the header. - // This field is deprecated. Please use :ref:`string_match `. + // + // .. attention:: + // + // This field is deprecated. Please use :ref:`string_match `. string exact_match = 4 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // If specified, this regex string is a regular expression rule which implies the entire request // header value must match the regex. The rule will not match if only a subsequence of the // request header value matches the regex. - // This field is deprecated. Please use :ref:`string_match `. + // + // .. attention:: + // + // This field is deprecated. Please use :ref:`string_match `. type.matcher.v3.RegexMatcher safe_regex_match = 11 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; @@ -2397,8 +2709,14 @@ message HeaderMatcher { bool present_match = 7; // If specified, header match will be performed based on the prefix of the header value. - // Note: empty prefix is not allowed, please use present_match instead. - // This field is deprecated. Please use :ref:`string_match `. + // + // .. note:: + // + // Empty prefix is not allowed. Please use ``present_match`` instead. + // + // .. attention:: + // + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // @@ -2410,8 +2728,14 @@ message HeaderMatcher { ]; // If specified, header match will be performed based on the suffix of the header value. - // Note: empty suffix is not allowed, please use present_match instead. - // This field is deprecated. Please use :ref:`string_match `. + // + // .. note:: + // + // Empty suffix is not allowed. Please use ``present_match`` instead. + // + // .. attention:: + // + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // @@ -2424,8 +2748,14 @@ message HeaderMatcher { // If specified, header match will be performed based on whether the header value contains // the given value or not. - // Note: empty contains match is not allowed, please use present_match instead. - // This field is deprecated. Please use :ref:`string_match `. + // + // .. note:: + // + // Empty contains match is not allowed. Please use ``present_match`` instead. + // + // .. attention:: + // + // This field is deprecated. Please use :ref:`string_match `. // // Examples: // @@ -2440,7 +2770,9 @@ message HeaderMatcher { type.matcher.v3.StringMatcher string_match = 13; } - // If specified, the match result will be inverted before checking. Defaults to false. + // If specified, the match result will be inverted before checking. + // + // Defaults to ``false``. // // Examples: // @@ -2449,7 +2781,9 @@ message HeaderMatcher { bool invert_match = 8; // If specified, for any header match rule, if the header match rule specified header - // does not exist, this header value will be treated as empty. Defaults to false. + // does not exist, this header value will be treated as empty. + // + // Defaults to ``false``. // // Examples: // @@ -2501,6 +2835,20 @@ message QueryParameterMatcher { } } +// Cookie matching inspects individual name/value pairs parsed from the ``Cookie`` header. +message CookieMatcher { + // Specifies the cookie name to evaluate. + string name = 1 [(validate.rules).string = {min_len: 1 max_bytes: 1024}]; + + // Match the cookie value using :ref:`StringMatcher + // ` semantics. + type.matcher.v3.StringMatcher string_match = 2 [(validate.rules).message = {required: true}]; + + // Invert the match result. If the cookie is not present, the match result is false, so + // ``invert_match`` will cause the matcher to succeed when the cookie is absent. + bool invert_match = 3; +} + // HTTP Internal Redirect :ref:`architecture overview `. // [#next-free-field: 6] message InternalRedirectPolicy { @@ -2526,7 +2874,7 @@ message InternalRedirectPolicy { repeated core.v3.TypedExtensionConfig predicates = 3; // Allow internal redirect to follow a target URI with a different scheme than the value of - // x-forwarded-proto. The default is false. + // x-forwarded-proto. The default is ``false``. bool allow_cross_scheme_redirect = 4; // Specifies a list of headers, by name, to copy from the internal redirect into the subsequent @@ -2566,6 +2914,5 @@ message FilterConfig { // initial route will not be added back to the filter chain because the filter chain is already // created and it is too late to change the chain. // - // This field only make sense for the downstream HTTP filters for now. bool disabled = 3; } diff --git a/src/main/proto/envoy/config/trace/v3/zipkin.proto b/src/main/proto/envoy/config/trace/v3/zipkin.proto index 2d8f319..2364983 100644 --- a/src/main/proto/envoy/config/trace/v3/zipkin.proto +++ b/src/main/proto/envoy/config/trace/v3/zipkin.proto @@ -2,13 +2,14 @@ syntax = "proto3"; package envoy.config.trace.v3; +import "envoy/config/core/v3/http_service.proto"; + import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; import "udpa/annotations/migrate.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.config.trace.v3"; option java_outer_classname = "ZipkinProto"; @@ -21,10 +22,22 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // Configuration for the Zipkin tracer. // [#extension: envoy.tracers.zipkin] -// [#next-free-field: 8] +// [#next-free-field: 10] message ZipkinConfig { option (udpa.annotations.versioning).previous_message_type = "envoy.config.trace.v2.ZipkinConfig"; + // Available trace context options for handling different trace header formats. + enum TraceContextOption { + // Use B3 headers only (default behavior). + USE_B3 = 0; + + // Enable B3 and W3C dual header support: + // - For downstream: Extract from B3 headers first, fallback to W3C traceparent if B3 is unavailable. + // - For upstream: Inject both B3 and W3C traceparent headers. + // When this option is NOT set, only B3 headers are used for both extraction and injection. + USE_B3_WITH_W3C_PROPAGATION = 1; + } + // Available Zipkin collector endpoint versions. enum CollectorEndpointVersion { // Zipkin API v1, JSON over HTTP. @@ -48,11 +61,23 @@ message ZipkinConfig { } // The cluster manager cluster that hosts the Zipkin collectors. - string collector_cluster = 1 [(validate.rules).string = {min_len: 1}]; + // + // .. note:: + // This field will be deprecated in future releases in favor of + // :ref:`collector_service `. + // + // Either this field or ``collector_service`` must be specified. + string collector_cluster = 1; // The API endpoint of the Zipkin service where the spans will be sent. When // using a standard Zipkin installation. - string collector_endpoint = 2 [(validate.rules).string = {min_len: 1}]; + // + // .. note:: + // This field will be deprecated in future releases in favor of + // :ref:`collector_service `. + // + // Required when using ``collector_cluster``. + string collector_endpoint = 2; // Determines whether a 128bit trace id will be used when creating a new // trace instance. The default value is false, which will result in a 64 bit trace id being used. @@ -67,6 +92,10 @@ message ZipkinConfig { // Optional hostname to use when sending spans to the collector_cluster. Useful for collectors // that require a specific hostname. Defaults to :ref:`collector_cluster ` above. + // + // .. note:: + // This field will be deprecated in future releases in favor of + // :ref:`collector_service `. string collector_hostname = 6; // If this is set to true, then Envoy will be treated as an independent hop in trace chain. A complete span pair will be created for a single @@ -88,4 +117,60 @@ message ZipkinConfig { // Please use that ``spawn_upstream_span`` field to control the span creation. bool split_spans_for_request = 7 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // Determines which trace context format to use for trace header extraction and propagation. + // This controls both downstream request header extraction and upstream request header injection. + // Here is the spec for W3C trace headers: https://www.w3.org/TR/trace-context/ + // The default value is USE_B3 to maintain backward compatibility. + TraceContextOption trace_context_option = 8; + + // HTTP service configuration for the Zipkin collector. + // When specified, this configuration takes precedence over the legacy fields: + // collector_cluster, collector_endpoint, and collector_hostname. + // This provides a complete HTTP service configuration including cluster, URI, timeout, and headers. + // If not specified, the legacy fields above will be used for backward compatibility. + // + // Required fields when using collector_service: + // + // * ``http_uri.cluster`` - Must be specified and non-empty + // * ``http_uri.uri`` - Must be specified and non-empty + // * ``http_uri.timeout`` - Optional + // + // Full URI Support with Automatic Parsing: + // + // The ``uri`` field supports both path-only and full URI formats: + // + // .. code-block:: yaml + // + // tracing: + // provider: + // name: envoy.tracers.zipkin + // typed_config: + // "@type": type.googleapis.com/envoy.config.trace.v3.ZipkinConfig + // collector_service: + // http_uri: + // # Full URI format - hostname and path are extracted automatically + // uri: "https://zipkin-collector.example.com/api/v2/spans" + // cluster: zipkin + // timeout: 5s + // request_headers_to_add: + // - header: + // key: "X-Custom-Token" + // value: "your-custom-token" + // - header: + // key: "X-Service-ID" + // value: "your-service-id" + // + // URI Parsing Behavior: + // + // * Full URI: ``"https://zipkin-collector.example.com/api/v2/spans"`` + // + // * Hostname: ``zipkin-collector.example.com`` (sets HTTP ``Host`` header) + // * Path: ``/api/v2/spans`` (sets HTTP request path) + // + // * Path only: ``"/api/v2/spans"`` + // + // * Hostname: Uses cluster name as fallback + // * Path: ``/api/v2/spans`` + core.v3.HttpService collector_service = 9; } diff --git a/src/main/proto/envoy/data/core/v3/tlv_metadata.proto b/src/main/proto/envoy/data/core/v3/tlv_metadata.proto index 8f99b00..caa7989 100644 --- a/src/main/proto/envoy/data/core/v3/tlv_metadata.proto +++ b/src/main/proto/envoy/data/core/v3/tlv_metadata.proto @@ -17,8 +17,7 @@ message TlvsMetadata { // Typed metadata for :ref:`Proxy protocol filter `, that represents a map of TLVs. // Each entry in the map consists of a key which corresponds to a configured // :ref:`rule key ` and a value (TLV value in bytes). - // When runtime flag ``envoy.reloadable_features.use_typed_metadata_in_proxy_protocol_listener`` is enabled, // :ref:`Proxy protocol filter ` - // will populate typed metadata and regular metadata. By default filter will populate typed and untyped metadata. + // populates both typed and untyped metadata. map typed_metadata = 1; } diff --git a/src/main/proto/envoy/data/tap/v3/http.proto b/src/main/proto/envoy/data/tap/v3/http.proto index 2e5c566..42ba44c 100644 --- a/src/main/proto/envoy/data/tap/v3/http.proto +++ b/src/main/proto/envoy/data/tap/v3/http.proto @@ -49,6 +49,9 @@ message HttpBufferedTrace { // downstream connection Connection downstream_connection = 3; + + // upstream connection + Connection upstream_connection = 4; } // A streamed HTTP trace segment. Multiple segments make up a full trace. diff --git a/src/main/proto/envoy/data/tap/v3/transport.proto b/src/main/proto/envoy/data/tap/v3/transport.proto index 8aef689..5f929bc 100644 --- a/src/main/proto/envoy/data/tap/v3/transport.proto +++ b/src/main/proto/envoy/data/tap/v3/transport.proto @@ -20,7 +20,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // sequences on a socket. // Event in a socket trace. -// [#next-free-field: 6] +// [#next-free-field: 7] message SocketEvent { option (udpa.annotations.versioning).previous_message_type = "envoy.data.tap.v2alpha.SocketEvent"; @@ -69,6 +69,9 @@ message SocketEvent { // Connection information per event Connection connection = 5; + + // Data sequence number + uint64 seq_num = 6; } // Sequence of read/write events that constitute a buffered trace on a socket. diff --git a/src/main/proto/envoy/extensions/access_loggers/dynamic_modules/v3/dynamic_modules.proto b/src/main/proto/envoy/extensions/access_loggers/dynamic_modules/v3/dynamic_modules.proto new file mode 100644 index 0000000..c169fe2 --- /dev/null +++ b/src/main/proto/envoy/extensions/access_loggers/dynamic_modules/v3/dynamic_modules.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package envoy.extensions.access_loggers.dynamic_modules.v3; + +import "envoy/extensions/dynamic_modules/v3/dynamic_modules.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.access_loggers.dynamic_modules.v3"; +option java_outer_classname = "DynamicModulesProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/dynamic_modules/v3;dynamic_modulesv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Dynamic Modules Access Logger] +// [#extension: envoy.access_loggers.dynamic_modules] + +// Configuration for the Dynamic Modules Access Logger. This logger allows loading shared object +// files via ``dlopen`` to implement custom access logging behavior. +// +// A module can be loaded by multiple access loggers; the module is loaded only once and shared +// across multiple logger instances. +// +// The access logger receives completed request information including request/response headers, +// stream info (timing, upstream info, response codes), and the log context type. +message DynamicModuleAccessLog { + // Specifies the shared-object level configuration. This field is required. + envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1 + [(validate.rules).message = {required: true}]; + + // The name for this logger configuration. If not specified, defaults to an empty string. + // + // This can be used to distinguish between different logger implementations inside a dynamic + // module. For example, a module can have completely different logger implementations (e.g., + // file logger, gRPC logger, metrics logger). When Envoy receives this configuration, it passes + // the ``logger_name`` to the dynamic module's access logger config init function together with + // the ``logger_config``. That way a module can decide which in-module logger implementation to + // use based on the name at load time. + string logger_name = 2; + + // The configuration for the logger chosen by ``logger_name``. If not specified, an empty + // configuration is passed to the module. + // + // This is passed to the module's access logger initialization function. Together with the + // ``logger_name``, the module can decide which in-module logger implementation to use and + // fine-tune the behavior of the logger. + // + // For example, if a module has two logger implementations, one for file output and one for + // sending to an external service, ``logger_name`` is used to choose either file or external. + // The ``logger_config`` can be used to configure file paths, service endpoints, batching + // parameters, format strings, etc. + // + // ``google.protobuf.Struct`` is serialized as JSON before passing it to the module. + // ``google.protobuf.BytesValue`` and ``google.protobuf.StringValue`` are passed directly + // without the wrapper. + // + // .. code-block:: yaml + // + // # Passing a JSON struct configuration + // logger_config: + // "@type": "type.googleapis.com/google.protobuf.Struct" + // value: + // output_path: "/var/log/envoy/access.log" + // format: "json" + // buffer_size: 1000 + // + // # Passing a simple string configuration + // logger_config: + // "@type": "type.googleapis.com/google.protobuf.StringValue" + // value: "/var/log/envoy/access.log" + // + google.protobuf.Any logger_config = 3; +} diff --git a/src/main/proto/envoy/extensions/access_loggers/filters/cel/v3/cel.proto b/src/main/proto/envoy/extensions/access_loggers/filters/cel/v3/cel.proto index 750ffd3..72251c6 100644 --- a/src/main/proto/envoy/extensions/access_loggers/filters/cel/v3/cel.proto +++ b/src/main/proto/envoy/extensions/access_loggers/filters/cel/v3/cel.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package envoy.extensions.access_loggers.filters.cel.v3; +import "envoy/config/core/v3/cel.proto"; + import "udpa/annotations/status.proto"; option java_package = "io.envoyproxy.envoy.extensions.access_loggers.filters.cel.v3"; @@ -25,4 +27,10 @@ message ExpressionFilter { // * ``response.code >= 400`` // * ``(connection.mtls && request.headers['x-log-mtls'] == 'true') || request.url_path.contains('v1beta3')`` string expression = 1; + + // CEL expression configuration that modifies the evaluation behavior of the ``expression`` field. + // If specified, string conversion, concatenation, and manipulation functions may be enabled + // for the filter expression. See :ref:`CelExpressionConfig ` + // for more details. + config.core.v3.CelExpressionConfig cel_config = 2; } diff --git a/src/main/proto/envoy/extensions/access_loggers/filters/process_ratelimit/v3/process_ratelimit.proto b/src/main/proto/envoy/extensions/access_loggers/filters/process_ratelimit/v3/process_ratelimit.proto new file mode 100644 index 0000000..6b60a69 --- /dev/null +++ b/src/main/proto/envoy/extensions/access_loggers/filters/process_ratelimit/v3/process_ratelimit.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package envoy.extensions.access_loggers.filters.process_ratelimit.v3; + +import "envoy/config/core/v3/config_source.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.access_loggers.filters.process_ratelimit.v3"; +option java_outer_classname = "ProcessRatelimitProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/filters/process_ratelimit/v3;process_ratelimitv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: ProcessRateLimiter] +// [#extension: envoy.access_loggers.extension_filters.process_ratelimit] + +// Filters for rate limiting the access log emission using global token buckets per process and shared across all listeners. +message ProcessRateLimitFilter { + // The dynamic config for the token bucket. + DynamicTokenBucket dynamic_config = 1; +} + +message DynamicTokenBucket { + // the key used to find the token bucket in the singleton map. + string resource_name = 1 [(validate.rules).string = {min_len: 1}]; + + // The configuration source for the :ref:`token_bucket `. + // It should stay the same through the process lifetime. + config.core.v3.ConfigSource config_source = 2 [(validate.rules).message = {required: true}]; +} diff --git a/src/main/proto/envoy/extensions/access_loggers/open_telemetry/v3/logs_service.proto b/src/main/proto/envoy/extensions/access_loggers/open_telemetry/v3/logs_service.proto index 641276a..ccb1ac4 100644 --- a/src/main/proto/envoy/extensions/access_loggers/open_telemetry/v3/logs_service.proto +++ b/src/main/proto/envoy/extensions/access_loggers/open_telemetry/v3/logs_service.proto @@ -3,12 +3,18 @@ syntax = "proto3"; package envoy.extensions.access_loggers.open_telemetry.v3; import "envoy/config/core/v3/extension.proto"; +import "envoy/config/core/v3/grpc_service.proto"; +import "envoy/config/core/v3/http_service.proto"; import "envoy/extensions/access_loggers/grpc/v3/als.proto"; +import "envoy/type/tracing/v3/custom_tag.proto"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/wrappers.proto"; import "opentelemetry/proto/common/v1/common.proto"; +import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.access_loggers.open_telemetry.v3"; option java_outer_classname = "LogsServiceProto"; @@ -16,17 +22,37 @@ option java_multiple_files = true; option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/open_telemetry/v3;open_telemetryv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; -// [#protodoc-title: OpenTelemetry (gRPC) Access Log] +// [#protodoc-title: OpenTelemetry Access Log] // Configuration for the built-in ``envoy.access_loggers.open_telemetry`` // :ref:`AccessLog `. This configuration will // populate `opentelemetry.proto.collector.v1.logs.ExportLogsServiceRequest.resource_logs `_. // In addition, the request start time is set in the dedicated field. // [#extension: envoy.access_loggers.open_telemetry] -// [#next-free-field: 8] +// [#next-free-field: 15] message OpenTelemetryAccessLogConfig { // [#comment:TODO(itamarkam): add 'filter_state_objects_to_log' to logs.] - grpc.v3.CommonGrpcAccessLogConfig common_config = 1 [(validate.rules).message = {required: true}]; + // Deprecated. Use ``grpc_service`` or ``http_service`` instead. + grpc.v3.CommonGrpcAccessLogConfig common_config = 1 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // The upstream HTTP cluster that will receive OTLP logs via + // `OTLP/HTTP `_. + // Note: Only one of ``common_config``, ``grpc_service``, or ``http_service`` may be used. + // + // .. note:: + // + // The ``request_headers_to_add`` property in the OTLP HTTP exporter service + // does not support the :ref:`format specifier ` as used for + // :ref:`HTTP access logging `. + // The values configured are added as HTTP headers on the OTLP export request + // without any formatting applied. + config.core.v3.HttpService http_service = 8; + + // The upstream gRPC cluster that will receive OTLP logs. + // Note: Only one of ``common_config``, ``grpc_service``, or ``http_service`` may be used. + // This field is preferred over ``common_config.grpc_service``. + config.core.v3.GrpcService grpc_service = 9; // If specified, Envoy will not generate built-in resource labels // like ``log_name``, ``zone_name``, ``cluster_name``, ``node_name``. @@ -57,4 +83,19 @@ message OpenTelemetryAccessLogConfig { // See the formatters extensions documentation for details. // [#extension-category: envoy.formatter] repeated config.core.v3.TypedExtensionConfig formatters = 7; + + string log_name = 10; + + // The interval for flushing access logs to the transport. Default: 1 second. + google.protobuf.Duration buffer_flush_interval = 11; + + // Soft size limit in bytes for the access log buffer. When the buffer exceeds + // this limit, logs will be flushed. Default: 16KB. + google.protobuf.UInt32Value buffer_size_bytes = 12; + + // Additional filter state objects to log as attributes. + repeated string filter_state_objects_to_log = 13; + + // Custom tags to include as log attributes. + repeated type.tracing.v3.CustomTag custom_tags = 14; } diff --git a/src/main/proto/envoy/extensions/access_loggers/stats/v3/stats.proto b/src/main/proto/envoy/extensions/access_loggers/stats/v3/stats.proto new file mode 100644 index 0000000..bcb1296 --- /dev/null +++ b/src/main/proto/envoy/extensions/access_loggers/stats/v3/stats.proto @@ -0,0 +1,102 @@ +syntax = "proto3"; + +package envoy.extensions.access_loggers.stats.v3; + +import "google/protobuf/wrappers.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.access_loggers.stats.v3"; +option java_outer_classname = "StatsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/stats/v3;statsv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Stats logger] +// Configuration for an access logger that emits custom Envoy stats according to its +// configuration. The stats can have tags and values derived from +// :ref:`command operators `. +// [#extension: envoy.access_loggers.stats] +// +// .. warning:: +// It is easy to configure and use this extension in ways that create very +// large numbers of stats in Envoy, which can cause excessive memory or CPU use +// leading to a denial of service in Envoy, or can overwhelm any configured +// stat sinks by sending too many unique metrics. + +message Config { + option (xds.annotations.v3.message_status).work_in_progress = true; + + // Defines a tag on a stat. + message Tag { + // The name of the tag. + string name = 1 [(validate.rules).string = {min_len: 1}]; + + // The value of the tag, using :ref:`command operators `. + string value_format = 2 [(validate.rules).string = {min_len: 1}]; + } + + // Defines the name and tags of a stat. + message Stat { + // The name of the stat. + string name = 1 [(validate.rules).string = {min_len: 1}]; + + // The tags for the stat. + repeated Tag tags = 2; + } + + // Configuration for a histogram stat. + message Histogram { + // The histogram units. The units are needed for some stat sinks. + enum Unit { + Unspecified = 0; + + Bytes = 1; + + Microseconds = 2; + + Milliseconds = 3; + + // Values are scaled to range 0-1.0, indicating 0%-100%. Values can be outside this range, + // but must be positive. Values extremely far out of this range may overflow. + Percent = 4; + } + + // The name and tags of this histogram. + Stat stat = 1 [(validate.rules).message = {required: true}]; + + // The units for this histogram. + Unit unit = 2 [(validate.rules).enum = {defined_only: true}]; + + // The format string for the value of this histogram, using :ref:`command operators `. + // This must evaluate to a positive number. + string value_format = 3 [(validate.rules).string = {min_len: 1 prefix: "%" suffix: "%"}]; + } + + // Configuration for a counter stat. + message Counter { + // The name and tags of this counter. + Stat stat = 1 [(validate.rules).message = {required: true}]; + + // The format string for the value to add to this counter, using :ref:`command operators `. + // One of ``value_format`` or ``value_fixed`` must be configured. + string value_format = 2 + [(validate.rules).string = {prefix: "%" suffix: "%" ignore_empty: true}]; + + // A fixed value to add to this counter. + // One of ``value_format`` or ``value_fixed`` must be configured. + google.protobuf.UInt64Value value_fixed = 3 [(validate.rules).uint64 = {gt: 0}]; + } + + // The stat prefix for the generated stats. + string stat_prefix = 1 [(validate.rules).string = {min_len: 1}]; + + // The histograms this logger will emit. + repeated Histogram histograms = 3; + + // The counters this logger will emit. + repeated Counter counters = 4; +} diff --git a/src/main/proto/envoy/extensions/bootstrap/dynamic_modules/v3/dynamic_modules.proto b/src/main/proto/envoy/extensions/bootstrap/dynamic_modules/v3/dynamic_modules.proto new file mode 100644 index 0000000..a0c406b --- /dev/null +++ b/src/main/proto/envoy/extensions/bootstrap/dynamic_modules/v3/dynamic_modules.proto @@ -0,0 +1,74 @@ +syntax = "proto3"; + +package envoy.extensions.bootstrap.dynamic_modules.v3; + +import "envoy/extensions/dynamic_modules/v3/dynamic_modules.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.bootstrap.dynamic_modules.v3"; +option java_outer_classname = "DynamicModulesProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/bootstrap/dynamic_modules/v3;dynamic_modulesv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Dynamic Modules Bootstrap Extension] +// [#extension: envoy.bootstrap.dynamic_modules] + +// Configuration for the Dynamic Modules bootstrap extension. This extension allows loading shared +// object files that can be loaded via ``dlopen`` to extend Envoy's bootstrap behavior. +// +// A module can be loaded by multiple bootstrap extensions; the module is loaded only once and shared +// across multiple extensions. +// +// Bootstrap extensions run on the main thread and are initialized when Envoy starts. They can: +// +// * Perform initialization tasks when the server is initialized. +// * Perform per-worker thread initialization when worker threads start. +// * Access server-level resources like the cluster manager and dispatcher. +// +message DynamicModuleBootstrapExtension { + // Specifies the shared-object level configuration. + envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1; + + // The name for this extension configuration. + // + // This can be used to distinguish between different extension implementations inside a dynamic + // module. For example, a module can have completely different extension implementations. When Envoy + // receives this configuration, it passes the ``extension_name`` to the dynamic module's bootstrap + // extension config init function together with the ``extension_config``. That way a module can + // decide which in-module extension implementation to use based on the name at load time. + // + // If not specified, defaults to an empty string. + string extension_name = 2; + + // The configuration for the extension chosen by ``extension_name``. + // + // This is passed to the module's bootstrap extension initialization function. Together with the + // ``extension_name``, the module can decide which in-module extension implementation to use and + // fine-tune the behavior of the extension. + // + // For example, if a module has two extension implementations, one for configuration loading and + // one for metric initialization, ``extension_name`` is used to choose the implementation. The + // ``extension_config`` can be used to configure the specific behavior of each implementation. + // + // ``google.protobuf.Struct`` is serialized as JSON before passing it to the module. + // ``google.protobuf.BytesValue`` and ``google.protobuf.StringValue`` are passed directly + // without the wrapper. + // + // .. code-block:: yaml + // + // # Passing a string value + // extension_config: + // "@type": "type.googleapis.com/google.protobuf.StringValue" + // value: hello + // + // # Passing raw bytes + // extension_config: + // "@type": "type.googleapis.com/google.protobuf.BytesValue" + // value: aGVsbG8= # echo -n "hello" | base64 + // + google.protobuf.Any extension_config = 3; +} diff --git a/src/main/proto/envoy/extensions/bootstrap/reverse_tunnel/downstream_socket_interface/v3/downstream_reverse_connection_socket_interface.proto b/src/main/proto/envoy/extensions/bootstrap/reverse_tunnel/downstream_socket_interface/v3/downstream_reverse_connection_socket_interface.proto new file mode 100644 index 0000000..72994c0 --- /dev/null +++ b/src/main/proto/envoy/extensions/bootstrap/reverse_tunnel/downstream_socket_interface/v3/downstream_reverse_connection_socket_interface.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package envoy.extensions.bootstrap.reverse_tunnel.downstream_socket_interface.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.bootstrap.reverse_tunnel.downstream_socket_interface.v3"; +option java_outer_classname = "DownstreamReverseConnectionSocketInterfaceProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/bootstrap/reverse_tunnel/downstream_socket_interface/v3;downstream_socket_interfacev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Bootstrap settings for downstream reverse connection socket interface] +// [#extension: envoy.bootstrap.reverse_tunnel.downstream_socket_interface] + +// Configuration for the downstream reverse connection socket interface. +// This interface initiates reverse connections to upstream Envoys and provides +// them as socket connections for downstream requests. +message DownstreamReverseConnectionSocketInterface { + // HTTP handshake settings for initiator envoy initiated reverse tunnels. + message HttpHandshakeConfig { + // Request path used when issuing the HTTP reverse-connection handshake. Defaults to + // "/reverse_connections/request". + string request_path = 1; + } + + // Stat prefix to be used for downstream reverse connection socket interface stats. + string stat_prefix = 1; + + // Enable detailed per-host and per-cluster statistics. + // When enabled, emits hidden statistics for individual hosts and clusters. + // Defaults to ``false``. + bool enable_detailed_stats = 2; + + // Optional HTTP handshake configuration. When unset, the initiator envoy uses the defaults + // provided by ``HttpHandshakeConfig``. + HttpHandshakeConfig http_handshake = 3; +} diff --git a/src/main/proto/envoy/extensions/bootstrap/reverse_tunnel/upstream_socket_interface/v3/upstream_reverse_connection_socket_interface.proto b/src/main/proto/envoy/extensions/bootstrap/reverse_tunnel/upstream_socket_interface/v3/upstream_reverse_connection_socket_interface.proto new file mode 100644 index 0000000..d1d3b36 --- /dev/null +++ b/src/main/proto/envoy/extensions/bootstrap/reverse_tunnel/upstream_socket_interface/v3/upstream_reverse_connection_socket_interface.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +package envoy.extensions.bootstrap.reverse_tunnel.upstream_socket_interface.v3; + +import "envoy/config/core/v3/extension.proto"; + +import "google/protobuf/wrappers.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.bootstrap.reverse_tunnel.upstream_socket_interface.v3"; +option java_outer_classname = "UpstreamReverseConnectionSocketInterfaceProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/bootstrap/reverse_tunnel/upstream_socket_interface/v3;upstream_socket_interfacev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Upstream reverse connection socket interface] +// [#extension: envoy.bootstrap.reverse_tunnel.upstream_socket_interface] + +// Configuration for the upstream reverse connection socket interface. +message UpstreamReverseConnectionSocketInterface { + // Stat prefix for upstream reverse connection socket interface stats. + string stat_prefix = 1; + + // Number of consecutive ping failures before an idle reverse connection socket is marked dead. + // Defaults to 3 if unset. Must be at least 1. + google.protobuf.UInt32Value ping_failure_threshold = 2 [(validate.rules).uint32 = {gte: 1}]; + + // Enable detailed per-node and per-cluster statistics. + // When enabled, emits hidden statistics for individual nodes and clusters. + // Defaults to false. + bool enable_detailed_stats = 3; + + // Optional configuration for a tunnel reporting extension. When provided, + // the socket interface instantiates a reporter via the configured factory. + // If unset, no reporting is done. + config.core.v3.TypedExtensionConfig reporter_config = 4; +} diff --git a/src/main/proto/envoy/extensions/clusters/composite/v3/cluster.proto b/src/main/proto/envoy/extensions/clusters/composite/v3/cluster.proto new file mode 100644 index 0000000..475f8d1 --- /dev/null +++ b/src/main/proto/envoy/extensions/clusters/composite/v3/cluster.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; + +package envoy.extensions.clusters.composite.v3; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.clusters.composite.v3"; +option java_outer_classname = "ClusterProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/clusters/composite/v3;compositev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Composite cluster configuration] + +// Configuration for the composite cluster. See the :ref:`architecture overview +// ` for more information. This cluster type enables retry-aware +// cluster selection, allowing different retry attempts to automatically target +// different upstream clusters. Unlike the standard aggregate cluster which uses +// health-based selection, the composite cluster uses the retry attempt count to +// deterministically select which sub-cluster to route to. +// +// When retry attempts exceed the number of configured clusters, requests will fail with no +// host available. +// +// Example configuration: +// +// .. code-block:: yaml +// +// name: composite_cluster +// connect_timeout: 0.25s +// lb_policy: CLUSTER_PROVIDED +// cluster_type: +// name: envoy.clusters.composite +// typed_config: +// "@type": type.googleapis.com/envoy.extensions.clusters.composite.v3.ClusterConfig +// clusters: +// - name: primary_cluster +// - name: secondary_cluster +// - name: fallback_cluster +// +// [#extension: envoy.clusters.composite] +message ClusterConfig { + // Configuration for an individual cluster entry. + message ClusterEntry { + // Name of the cluster. This cluster must be defined elsewhere in the configuration. + string name = 1 [(validate.rules).string = {min_len: 1}]; + } + + // List of clusters to use for request routing. The first cluster is used for the + // initial request (attempt 1), the second cluster for the first retry (attempt 2), + // and so on. Must contain at least one cluster. When retry attempts exceed the number + // of configured clusters, requests will fail with no host available. + repeated ClusterEntry clusters = 1 [(validate.rules).repeated = {min_items: 1}]; +} diff --git a/src/main/proto/envoy/extensions/clusters/reverse_connection/v3/reverse_connection.proto b/src/main/proto/envoy/extensions/clusters/reverse_connection/v3/reverse_connection.proto new file mode 100644 index 0000000..054ac14 --- /dev/null +++ b/src/main/proto/envoy/extensions/clusters/reverse_connection/v3/reverse_connection.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package envoy.extensions.clusters.reverse_connection.v3; + +import "google/protobuf/duration.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.clusters.reverse_connection.v3"; +option java_outer_classname = "ReverseConnectionProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/clusters/reverse_connection/v3;reverse_connectionv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Reverse connection cluster] +// [#extension: envoy.clusters.reverse_connection] + +// Configuration for a cluster of type REVERSE_CONNECTION. +message ReverseConnectionClusterConfig { + // Time interval after which Envoy removes unused dynamic hosts created for reverse connections. + // Hosts that are not referenced by any connection pool are deleted during cleanup. + // + // If unset, Envoy uses a default of 60s. + google.protobuf.Duration cleanup_interval = 1 [(validate.rules).duration = {gt {}}]; + + // Host identifier format string. + // + // This format string is evaluated against the downstream request context to compute + // the host identifier for selecting the reverse connection endpoint. The format string + // supports Envoy's standard formatter syntax, including: + // + // * ``%REQ(header-name)%``: Extract request header value. + // * ``%DYNAMIC_METADATA(namespace:key)%``: Extract dynamic metadata value. + // * ``%CEL(expression)%``: Evaluate CEL expression. + // * ``%DOWNSTREAM_REMOTE_ADDRESS%``: Downstream connection address. + // * ``%DOWNSTREAM_LOCAL_ADDRESS%``: Downstream local address. + // * Plain text and combinations of the above. + // + // Examples: + // + // * ``%REQ(x-remote-node-id)%``: Use the value of the ``x-remote-node-id`` header. + // * ``%REQ(host):EXTRACT_FIRST_PART%``: Extract the first part of the Host header before a dot. + // * ``%CEL(request.headers['x-node-id'] | orValue('default'))%``: Use CEL with fallback. + // * ``node-%REQ(x-tenant-id)%-%REQ(x-region)%``: Combine multiple values. + // + // If the format string evaluates to an empty value, the request will not be routed. + string host_id_format = 2 [(validate.rules).string = {min_len: 1}]; +} diff --git a/src/main/proto/envoy/extensions/common/aws/v3/credential_provider.proto b/src/main/proto/envoy/extensions/common/aws/v3/credential_provider.proto index 395a2e9..45ecf9b 100644 --- a/src/main/proto/envoy/extensions/common/aws/v3/credential_provider.proto +++ b/src/main/proto/envoy/extensions/common/aws/v3/credential_provider.proto @@ -77,8 +77,10 @@ message InlineCredentialProvider { // to retrieve AWS credentials. message AssumeRoleWithWebIdentityCredentialProvider { // Data source for a web identity token that is provided by the identity provider to assume the role. - // When using this data source, even if a ``watched_directory`` is provided, the token file will only be re-read when the credentials - // returned from AssumeRoleWithWebIdentity expire. + // If a ``watched_directory`` is not provided, one will be automatically inferred from the directory of the token file. This is to ensure + // that if the token file is rotated, the new token will be picked up. This behaviour differs from the standard envoy data source behavior, which does not + // automatically watch the directory of a file data source. + // Even when file rotation occurs, current credentials will continue to be used until they expire, at which point new credentials will be retrieved using the new token. config.core.v3.DataSource web_identity_token_data_source = 1 [(udpa.annotations.sensitive) = true]; @@ -163,7 +165,8 @@ message AssumeRoleCredentialProvider { // The ARN of the role to assume. string role_arn = 1 [(validate.rules).string = {min_len: 1}]; - // Optional string value to use as the role session name + // An optional role session name, used when identifying the role in subsequent AWS API calls. If not provided, the role session name will default + // to the current timestamp. string role_session_name = 2; // Optional string value to use as the externalId diff --git a/src/main/proto/envoy/extensions/dynamic_modules/v3/dynamic_modules.proto b/src/main/proto/envoy/extensions/dynamic_modules/v3/dynamic_modules.proto index 0971d50..46d4480 100644 --- a/src/main/proto/envoy/extensions/dynamic_modules/v3/dynamic_modules.proto +++ b/src/main/proto/envoy/extensions/dynamic_modules/v3/dynamic_modules.proto @@ -11,46 +11,59 @@ option java_multiple_files = true; option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/dynamic_modules/v3;dynamic_modulesv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; -// [#protodoc-title: Dynamic Modules common configuration] +// [#protodoc-title: Dynamic Modules Common Configuration] -// Configuration of a dynamic module. A dynamic module is a shared object file that can be loaded via dlopen -// by various Envoy extension points. Currently, only HTTP filter (envoy.filters.http.dynamic_modules) is supported. +// Configuration of a dynamic module. A dynamic module is a shared object file that can be loaded via +// ``dlopen`` by various Envoy extension points. // -// How a module is loaded is determined by the extension point that uses it. For example, the HTTP filter -// loads the module with dlopen when Envoy receives a configuration that references the module at load time. -// If loading the module fails, the configuration will be rejected. +// How a module is loaded is determined by the extension point that uses it. For example, the HTTP +// filter loads the module when Envoy receives a configuration that references the module. If loading +// the module fails, the configuration will be rejected. // -// Whether or not the shared object is the same is determined by the file path as well as the file's inode depending -// on the platform. Notably, if the file path and the content of the file are the same, the shared object will be reused. +// A module is uniquely identified by its file path and the file's inode, depending on the platform. +// Notably, if the file path and the content of the file are the same, the shared object will be +// reused. // -// A module must be compatible with the ABI specified in :repo:`abi.h `. -// Currently, compatibility is only guaranteed by an exact version match between the Envoy -// codebase and the dynamic module SDKs. In the future, after the ABI is stabilized, we will revisit -// this restriction and hopefully provide a wider compatibility guarantee. Until then, Envoy -// checks the hash of the ABI header files to ensure that the dynamic modules are built against the -// same version of the ABI. +// A module must be compatible with the ABI specified in :repo:`abi.h +// `. Currently, compatibility is only guaranteed by an +// exact version match between the Envoy codebase and the dynamic module SDKs. In the future, after +// the ABI is stabilized, this restriction will be revisited. Until then, Envoy checks the hash of +// the ABI header files to ensure that the dynamic modules are built against the same version of the +// ABI. message DynamicModuleConfig { - // The name of the dynamic module. The client is expected to have some configuration indicating where to search for the module. - // In Envoy, the search path can only be configured via the environment variable ``ENVOY_DYNAMIC_MODULES_SEARCH_PATH``. - // The actual search path is ``${ENVOY_DYNAMIC_MODULES_SEARCH_PATH}/lib${name}.so``. TODO: make the search path configurable via - // command line options. + // The name of the dynamic module. + // + // The client is expected to have some configuration indicating where to search for the module. In + // Envoy, the search path can only be configured via the environment variable + // ``ENVOY_DYNAMIC_MODULES_SEARCH_PATH``. The actual search path is + // ``${ENVOY_DYNAMIC_MODULES_SEARCH_PATH}/lib${name}.so``. + // + // .. note:: + // There is some remaining work to make the search path configurable via command line options. string name = 1 [(validate.rules).string = {min_len: 1}]; - // Set true to prevent the module from being unloaded with dlclose. - // This is useful for modules that have global state that should not be unloaded. - // A module is closed when no more references to it exist in the process. For example, - // no HTTP filters are using the module (e.g. after configuration update). + // If true, prevents the module from being unloaded with ``dlclose``. + // + // This is useful for modules that have global state that should not be unloaded. A module is + // closed when no more references to it exist in the process. For example, no HTTP filters are + // using the module (e.g. after configuration update). + // + // Defaults to ``false``. bool do_not_close = 3; - // The dynamic module is loaded with ``RTLD_LOCAL`` flag to avoid symbol conflicts when multiple - // modules are loaded by default. Set this to true to load the module with ``RTLD_GLOBAL`` flag. - // This is useful for modules that need to share symbols with other dynamic libraries. For - // example, a module X may load another shared library Y that depends on some symbols defined - // in module X. In this case, module X must be loaded with ``RTLD_GLOBAL`` flag so that the - // symbols defined in module X are visible to library Y. + // If true, the dynamic module is loaded with the ``RTLD_GLOBAL`` flag. + // + // The dynamic module is loaded with the ``RTLD_LOCAL`` flag by default to avoid symbol conflicts + // when multiple modules are loaded. Set this to ``true`` to load the module with the + // ``RTLD_GLOBAL`` flag. This is useful for modules that need to share symbols with other dynamic + // libraries. For example, a module X may load another shared library Y that depends on some + // symbols defined in module X. In this case, module X must be loaded with the ``RTLD_GLOBAL`` + // flag so that the symbols defined in module X are visible to library Y. // // .. warning:: - // Use this option with caution as it may lead to symbol conflicts and undefined behavior - // if multiple modules define the same symbols and are loaded globally. + // Use this option with caution as it may lead to symbol conflicts and undefined behavior if + // multiple modules define the same symbols and are loaded globally. + // + // Defaults to ``false``. bool load_globally = 4; } diff --git a/src/main/proto/envoy/extensions/filters/common/set_filter_state/v3/value.proto b/src/main/proto/envoy/extensions/filters/common/set_filter_state/v3/value.proto index 6abd228..054529c 100644 --- a/src/main/proto/envoy/extensions/filters/common/set_filter_state/v3/value.proto +++ b/src/main/proto/envoy/extensions/filters/common/set_filter_state/v3/value.proto @@ -32,14 +32,55 @@ message FilterStateValue { oneof key { option (validate.required) = true; - // Filter state object key. The key is used to lookup the object factory, unless :ref:`factory_key - // ` is set. See - // :ref:`the well-known filter state keys ` for a list of valid object keys. + // The name under which the filter state object will be stored and can be retrieved. + // + // When using :ref:`well-known filter state keys ` (e.g., + // ``envoy.network.upstream_server_name``, ``envoy.tcp_proxy.cluster``), the object key serves + // dual purpose where it identifies both where the data is stored and which factory creates the + // object. In this case, :ref:`factory_key + // ` + // is not needed. + // + // When using a custom key name which is not from the well-known list, you must also specify + // :ref:`factory_key + // ` + // to indicate which factory should create the object from your value. + // + // Example using a well-known key where ``factory_key`` is not needed: + // + // .. code-block:: yaml + // + // object_key: envoy.tcp_proxy.cluster + // format_string: + // text_format_source: + // inline_string: "my-cluster" + // + // Example using a custom key which requires a ``factory_key``: + // + // .. code-block:: yaml + // + // object_key: my.custom.key + // factory_key: envoy.string + // format_string: + // text_format_source: + // inline_string: "my-value" + // string object_key = 1 [(validate.rules).string = {min_len: 1}]; } - // Optional filter object factory lookup key. See :ref:`the well-known filter state keys ` - // for a list of valid factory keys. + // Specifies which registered factory should be used to create the filter state object from the + // provided value. This field is required when :ref:`object_key + // ` + // is a custom name not found in the :ref:`well-known filter state keys `. + // + // Each well-known key has a factory registered with the same name (e.g., the key + // ``envoy.tcp_proxy.cluster`` has a factory also named ``envoy.tcp_proxy.cluster``). For custom keys, + // use one of the following generic factories: + // + // * ``envoy.string``: Creates a generic string object. Use this for arbitrary string values that + // will be accessed via ``StringAccessor``. + // + // If not specified, defaults to the value of ``object_key``. string factory_key = 6; oneof value { diff --git a/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto b/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto index 6c683cc..9200ae9 100644 --- a/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto +++ b/src/main/proto/envoy/extensions/filters/http/aws_lambda/v3/aws_lambda.proto @@ -48,13 +48,15 @@ message Config { // this value. If not set or empty, the original host header value // will be used and no rewrite will happen. // - // Note: this rewrite affects both signing and host header forwarding. However, this - // option shouldn't be used with - // :ref:`HCM host rewrite ` given that the - // value set here would be used for signing whereas the value set in the HCM would be used - // for host header forwarding which is not the desired outcome. - // Changing the value of the host header can result in a different route to be selected - // if an HTTP filter after AWS lambda re-evaluates the route (clears route cache). + // .. note:: + // This rewrite affects both signing and host header forwarding. However, this + // option shouldn't be used with + // :ref:`HCM host rewrite ` given that the + // value set here would be used for signing whereas the value set in the HCM would be used + // for host header forwarding which is not the desired outcome. + // + // Changing the value of the host header can result in a different route to be selected + // if an HTTP filter after AWS lambda re-evaluates the route (clears route cache). string host_rewrite = 4; // Specifies the credentials profile to be used from the AWS credentials file. diff --git a/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto b/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto index 610c8c7..64678be 100644 --- a/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto +++ b/src/main/proto/envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.proto @@ -22,7 +22,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#extension: envoy.filters.http.aws_request_signing] // Top level configuration for the AWS request signing filter. -// [#next-free-field: 9] +// [#next-free-field: 10] message AwsRequestSigning { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.aws_request_signing.v2alpha.AwsRequestSigning"; @@ -58,14 +58,14 @@ message AwsRequestSigning { // When signing_algorithm is set to ``AWS_SIGV4`` the region is a standard AWS `region `_ string for the service // hosting the HTTP endpoint. // - // Example: us-west-2 + // Example: ``us-west-2`` // // When signing_algorithm is set to ``AWS_SIGV4A`` the region is used as a region set. // // A region set is a comma separated list of AWS regions, such as ``us-east-1,us-east-2`` or wildcard ``*`` // or even region strings containing wildcards such as ``us-east-*`` // - // Example: '*' + // Example: ``'*'`` // // By configuring a region set, a SigV4A signed request can be sent to multiple regions, rather than being // valid for only a single region destination. @@ -75,11 +75,12 @@ message AwsRequestSigning { // this value. If not set or empty, the original host header value // will be used and no rewrite will happen. // - // Note: this rewrite affects both signing and host header forwarding. However, this - // option shouldn't be used with - // :ref:`HCM host rewrite ` given that the - // value set here would be used for signing whereas the value set in the HCM would be used - // for host header forwarding which is not the desired outcome. + // .. note:: + // This rewrite affects both signing and host header forwarding. However, this + // option shouldn't be used with + // :ref:`HCM host rewrite ` given that the + // value set here would be used for signing whereas the value set in the HCM would be used + // for host header forwarding which is not the desired outcome. string host_rewrite = 3; // Instead of buffering the request to calculate the payload hash, use the literal string ``UNSIGNED-PAYLOAD`` @@ -91,11 +92,15 @@ message AwsRequestSigning { // any patterns defined in the StringMatcher proto (e.g. exact string, prefix, regex, etc). // // Example: - // match_excluded_headers: - // - prefix: x-envoy - // - exact: foo - // - exact: bar - // When applied, all headers that start with "x-envoy" and headers "foo" and "bar" will not be signed. + // + // .. code-block:: yaml + // + // match_excluded_headers: + // - prefix: x-envoy + // - exact: foo + // - exact: bar + // + // When applied, all headers that start with ``x-envoy`` and headers ``foo`` and ``bar`` will not be signed. repeated type.matcher.v3.StringMatcher match_excluded_headers = 5; // Optional Signing algorithm specifier, either ``AWS_SIGV4`` or ``AWS_SIGV4A``, defaulting to ``AWS_SIGV4``. @@ -112,6 +117,23 @@ message AwsRequestSigning { // The credential provider for signing the request. This is optional and if not set, // it will be retrieved using the procedure described in :ref:`config_http_filters_aws_request_signing`. common.aws.v3.AwsCredentialProvider credential_provider = 8; + + // A list of request header string matchers that will be included during signing. The included header can be matched by + // any patterns defined in the StringMatcher proto (e.g. exact string, prefix, regex, etc). + // match_included_headers takes precedence over match_excluded_headers - if match_included_headers is set, only those headers will be signed and match_excluded_headers will be ignored. + // Required headers for signing such as ``host`` will always be signed regardless of this setting. The required headers are determined via ``CanonicalHeaders`` section in the AWS documentation `here `_. + // + // Example: + // + // .. code-block:: yaml + // + // match_included_headers: + // - prefix: x-envoy + // - exact: foo + // - exact: bar + // + // When applied, all headers that start with ``x-envoy`` and headers ``foo`` and ``bar`` will be signed and all other headers will be excluded from signing except required headers. + repeated type.matcher.v3.StringMatcher match_included_headers = 9; } message AwsRequestSigningPerRoute { diff --git a/src/main/proto/envoy/extensions/filters/http/cache_v2/v3/cache.proto b/src/main/proto/envoy/extensions/filters/http/cache_v2/v3/cache.proto new file mode 100644 index 0000000..9a335f5 --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/http/cache_v2/v3/cache.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.cache_v2.v3; + +import "envoy/config/route/v3/route_components.proto"; +import "envoy/type/matcher/v3/string.proto"; + +import "google/protobuf/any.proto"; +import "google/protobuf/wrappers.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.cache_v2.v3"; +option java_outer_classname = "CacheProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/cache_v2/v3;cache_v2v3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: HTTP Cache Filter V2] + +// [#extension: envoy.filters.http.cache_v2] +// [#next-free-field: 8] +message CacheV2Config { + // [#not-implemented-hide:] + // Modifies cache key creation by restricting which parts of the URL are included. + message KeyCreatorParams { + // If true, exclude the URL scheme from the cache key. Set to true if your origins always + // produce the same response for http and https requests. + bool exclude_scheme = 1; + + // If true, exclude the host from the cache key. Set to true if your origins' responses don't + // ever depend on host. + bool exclude_host = 2; + + // If ``query_parameters_included`` is nonempty, only query parameters matched + // by one or more of its matchers are included in the cache key. Any other + // query params will not affect cache lookup. + repeated config.route.v3.QueryParameterMatcher query_parameters_included = 3; + + // If ``query_parameters_excluded`` is nonempty, query parameters matched by one + // or more of its matchers are excluded from the cache key (even if also + // matched by ``query_parameters_included``), and will not affect cache lookup. + repeated config.route.v3.QueryParameterMatcher query_parameters_excluded = 4; + } + + // Config specific to the cache storage implementation. Required unless ``disabled`` + // is true. + // [#extension-category: envoy.http.cache_v2] + google.protobuf.Any typed_config = 1; + + // When true, the cache filter is a no-op filter. + // + // Possible use-cases for this include: + // - Turning a filter on and off with :ref:`ECDS `. + // [#comment: once route-specific overrides are implemented, they are the more likely use-case.] + google.protobuf.BoolValue disabled = 5; + + // [#not-implemented-hide:] + // List of matching rules that defines allowed ``Vary`` headers. + // + // The ``vary`` response header holds a list of header names that affect the + // contents of a response, as described by + // https://httpwg.org/specs/rfc7234.html#caching.negotiated.responses. + // + // During insertion, ``allowed_vary_headers`` acts as a allowlist: if a + // response's ``vary`` header mentions any header names that aren't matched by any rules in + // ``allowed_vary_headers``, that response will not be cached. + // + // During lookup, ``allowed_vary_headers`` controls what request headers will be + // sent to the cache storage implementation. + repeated type.matcher.v3.StringMatcher allowed_vary_headers = 2; + + // [#not-implemented-hide:] + // + // + // Modifies cache key creation by restricting which parts of the URL are included. + KeyCreatorParams key_creator_params = 3; + + // [#not-implemented-hide:] + // + // + // Max body size the cache filter will insert into a cache. 0 means unlimited (though the cache + // storage implementation may have its own limit beyond which it will reject insertions). + uint32 max_body_bytes = 4; + + // By default, a ``cache-control: no-cache`` or ``pragma: no-cache`` header in the request + // causes the cache to validate with its upstream even if the lookup is a hit. Setting this + // to true will ignore these headers. + bool ignore_request_cache_control_header = 6; + + // If this is set, requests sent upstream to populate the cache will go to the + // specified cluster rather than the cluster selected by the vhost and route. + // + // If you have actions to be taken by the router filter - either + // ``upstream_http_filters`` or one of the ``RouteConfiguration`` actions such as + // ``response_headers_to_add`` - then the cache's side-channel going directly to the + // routed cluster will bypass these actions. You can set ``override_upstream_cluster`` + // to an internal listener which duplicates the relevant ``RouteConfiguration``, to + // replicate the desired behavior on the side-channel upstream request issued by the + // cache. + // + // This is a workaround for implementation constraints which it is hoped will at some + // point become unnecessary, then unsupported and this field will be removed. + string override_upstream_cluster = 7; +} diff --git a/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto b/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto index 4e7d372..1ab6c5e 100644 --- a/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto +++ b/src/main/proto/envoy/extensions/filters/http/composite/v3/composite.proto @@ -31,11 +31,30 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // :ref:`ExecuteFilterAction `) // which filter configuration to create and delegate to. message Composite { + // Named filter chain definitions that can be referenced from + // :ref:`ExecuteFilterAction.filter_chain_name + // `. + // The filter chains are compiled at configuration time and can be referenced by name. + // This is useful when the same filter chain needs to be applied across many routes, + // as it avoids duplicating the filter chain configuration. + map named_filter_chains = 1; +} + +// A list of filter configurations to be called in order. Note that this can be used as the type +// inside of an ECDS :ref:`TypedExtensionConfig +// ` extension, which allows a chain of +// filters to be configured dynamically. In that case, the types of all filters in the chain must +// be present in the :ref:`ExtensionConfigSource.type_urls +// ` field. +message FilterChainConfiguration { + repeated config.core.v3.TypedExtensionConfig typed_config = 1; } // Configuration for an extension configuration discovery service with name. message DynamicConfig { // The name of the extension configuration. It also serves as a resource name in ExtensionConfigDS. + // The resource type in the ``DiscoveryRequest`` will be :ref:`TypedExtensionConfig + // `. string name = 1 [(validate.rules).string = {min_len: 1}]; // Configuration source specifier for an extension configuration discovery @@ -46,19 +65,36 @@ message DynamicConfig { // Composite match action (see :ref:`matching docs ` for more info on match actions). // This specifies the filter configuration of the filter that the composite filter should delegate filter interactions to. +// [#next-free-field: 6] message ExecuteFilterAction { // Filter specific configuration which depends on the filter being // instantiated. See the supported filters for further documentation. - // Only one of ``typed_config`` or ``dynamic_config`` can be set. + // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name`` + // can be set. // [#extension-category: envoy.filters.http] config.core.v3.TypedExtensionConfig typed_config = 1 [(udpa.annotations.field_migrate).oneof_promotion = "config_type"]; // Dynamic configuration of filter obtained via extension configuration discovery service. - // Only one of ``typed_config`` or ``dynamic_config`` can be set. + // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name`` + // can be set. DynamicConfig dynamic_config = 2 [(udpa.annotations.field_migrate).oneof_promotion = "config_type"]; + // An inlined list of filter configurations. The specified filters will be executed in order. + // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name`` + // can be set. + FilterChainConfiguration filter_chain = 4; + + // The name of a filter chain defined in + // :ref:`Composite.named_filter_chains + // `. + // At runtime, if the named filter chain is not found in the Composite filter's configuration, + // no filter will be applied for this match (the action is silently skipped). + // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name`` + // can be set. + string filter_chain_name = 5; + // Probability of the action execution. If not specified, this is 100%. // This allows sampling behavior for the configured actions. // For example, if diff --git a/src/main/proto/envoy/extensions/filters/http/compressor/v3/compressor.proto b/src/main/proto/envoy/extensions/filters/http/compressor/v3/compressor.proto index c49ccfe..7e67938 100644 --- a/src/main/proto/envoy/extensions/filters/http/compressor/v3/compressor.proto +++ b/src/main/proto/envoy/extensions/filters/http/compressor/v3/compressor.proto @@ -28,21 +28,31 @@ message Compressor { "envoy.config.filter.http.compressor.v2.Compressor"; message CommonDirectionConfig { - // Runtime flag that controls whether compression is enabled or not for the direction this - // common config is put in. If set to false, the filter will operate as a pass-through filter - // in the chosen direction, unless overridden by CompressorPerRoute. - // If the field is omitted, the filter will be enabled. + // Runtime flag that controls whether compression is enabled for the direction this + // common config is applied to. When this field is ``false``, the filter will operate as a + // pass-through filter in the chosen direction, unless overridden by ``CompressorPerRoute``. + // If this field is not specified, the filter will be enabled. config.core.v3.RuntimeFeatureFlag enabled = 1; - // Minimum value of Content-Length header of request or response messages (depending on the direction - // this common config is put in), in bytes, which will trigger compression. The default value is 30. + // Minimum value of the ``Content-Length`` header in request or response messages (depending on the + // direction this common config is applied to), in bytes, that will trigger compression. Defaults to 30. google.protobuf.UInt32Value min_content_length = 2; // Set of strings that allows specifying which mime-types yield compression; e.g., - // application/json, text/html, etc. When this field is not defined, compression will be applied - // to the following mime-types: "application/javascript", "application/json", - // "application/xhtml+xml", "image/svg+xml", "text/css", "text/html", "text/plain", "text/xml" - // and their synonyms. + // ``application/json``, ``text/html``, etc. + // + // When this field is not specified, compression will be applied to these following mime-types + // and their synonyms: + // + // * ``application/javascript`` + // * ``application/json`` + // * ``application/xhtml+xml`` + // * ``image/svg+xml`` + // * ``text/css`` + // * ``text/html`` + // * ``text/plain`` + // * ``text/xml`` + // repeated string content_type = 3; } @@ -52,28 +62,40 @@ message Compressor { } // Configuration for filter behavior on the response direction. + // [#next-free-field: 6] message ResponseDirectionConfig { CommonDirectionConfig common_config = 1; - // If true, disables compression when the response contains an etag header. When it is false, the - // filter will preserve weak etags and remove the ones that require strong validation. + // When this field is ``true``, disables compression when the response contains an ``ETag`` header. + // When this field is ``false``, the filter will preserve weak ``ETag`` values and remove those that + // require strong validation. bool disable_on_etag_header = 2; - // If true, removes accept-encoding from the request headers before dispatching it to the upstream - // so that responses do not get compressed before reaching the filter. + // When this field is ``true``, removes ``Accept-Encoding`` from the request headers before dispatching + // the request to the upstream so that responses do not get compressed before reaching the filter. // // .. attention:: // - // To avoid interfering with other compression filters in the same chain use this option in + // To avoid interfering with other compression filters in the same chain, use this option in // the filter closest to the upstream. bool remove_accept_encoding_header = 3; - // Set of response codes for which compression is disabled, e.g. 206 Partial Content should not + // Set of response codes for which compression is disabled; e.g., 206 Partial Content should not // be compressed. repeated uint32 uncompressible_response_codes = 4 [(validate.rules).repeated = { unique: true items {uint32 {lt: 600 gte: 200}} }]; + + // If true, the filter adds the ``x-envoy-compression-status`` response + // header to indicate whether the compression occurred and, if not, provide + // the reason why. The header's value format is + // ``;[;]``, where ```` is + // ``Compressed`` or the reason compression was skipped (e.g., + // ``ContentLengthTooSmall``). When this field is enabled, the compressor + // filter alters the order of the compression eligibility checks to report + // the most valid reason for skipping the compression. + bool status_header_enabled = 5; } // Minimum response length, in bytes, which will trigger compression. The default value is 30. @@ -81,60 +103,69 @@ message Compressor { [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // Set of strings that allows specifying which mime-types yield compression; e.g., - // application/json, text/html, etc. When this field is not defined, compression will be applied - // to the following mime-types: "application/javascript", "application/json", - // "application/xhtml+xml", "image/svg+xml", "text/css", "text/html", "text/plain", "text/xml" - // and their synonyms. + // ``application/json``, ``text/html``, etc. + // + // When this field is not specified, compression will be applied to these following mime-types + // and their synonyms: + // + // * ``application/javascript`` + // * ``application/json`` + // * ``application/xhtml+xml`` + // * ``image/svg+xml`` + // * ``text/css`` + // * ``text/html`` + // * ``text/plain`` + // * ``text/xml`` + // repeated string content_type = 2 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // If true, disables compression when the response contains an etag header. When it is false, the - // filter will preserve weak etags and remove the ones that require strong validation. + // When this field is ``true``, disables compression when the response contains an ``ETag`` header. + // When this field is ``false``, the filter will preserve weak ``ETag`` values and remove those that + // require strong validation. bool disable_on_etag_header = 3 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // If true, removes accept-encoding from the request headers before dispatching it to the upstream - // so that responses do not get compressed before reaching the filter. + // When this field is ``true``, removes ``Accept-Encoding`` from the request headers before dispatching + // the request to the upstream so that responses do not get compressed before reaching the filter. // // .. attention:: // - // To avoid interfering with other compression filters in the same chain use this option in + // To avoid interfering with other compression filters in the same chain, use this option in // the filter closest to the upstream. bool remove_accept_encoding_header = 4 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // Runtime flag that controls whether the filter is enabled or not. If set to false, the - // filter will operate as a pass-through filter, unless overridden by - // CompressorPerRoute. If not specified, defaults to enabled. + // Runtime flag that controls whether the filter is enabled. When this field is ``false``, the + // filter will operate as a pass-through filter, unless overridden by ``CompressorPerRoute``. + // If this field is not specified, the filter is enabled by default. config.core.v3.RuntimeFeatureFlag runtime_enabled = 5 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // A compressor library to use for compression. Currently only - // :ref:`envoy.compression.gzip.compressor` - // is included in Envoy. + // A compressor library to use for compression. // [#extension-category: envoy.compression.compressor] config.core.v3.TypedExtensionConfig compressor_library = 6 [(validate.rules).message = {required: true}]; - // Configuration for request compression. Compression is disabled by default if left empty. + // Configuration for request compression. If this field is not specified, request compression is disabled. RequestDirectionConfig request_direction_config = 7; - // Configuration for response compression. Compression is enabled by default if left empty. + // Configuration for response compression. If this field is not specified, response compression is enabled. // // .. attention:: // - // If the field is not empty then the duplicate deprecated fields of the ``Compressor`` message, + // When this field is set, duplicate deprecated fields of the ``Compressor`` message, // such as ``content_length``, ``content_type``, ``disable_on_etag_header``, - // ``remove_accept_encoding_header`` and ``runtime_enabled``, are ignored. + // ``remove_accept_encoding_header``, and ``runtime_enabled``, are ignored. // - // Also all the statistics related to response compression will be rooted in + // Additionally, all statistics related to response compression will be rooted in // ``.compressor...response.*`` // instead of // ``.compressor...*``. ResponseDirectionConfig response_direction_config = 8; - // If true, chooses this compressor first to do compression when the q-values in ``Accept-Encoding`` are same. - // The last compressor which enables choose_first will be chosen if multiple compressor filters in the chain have choose_first as true. + // When this field is ``true``, this compressor is preferred when q-values in ``Accept-Encoding`` are equal. + // If multiple compressor filters set ``choose_first`` to ``true``, the last one in the filter chain is chosen. bool choose_first = 9; } @@ -152,6 +183,10 @@ message ResponseDirectionOverrides { message CompressorOverrides { // If present, response compression is enabled. ResponseDirectionOverrides response_direction_config = 1; + + // A compressor library to use for compression. If specified, this overrides + // the filter-level ``compressor_library`` configuration for this route. + config.core.v3.TypedExtensionConfig compressor_library = 2; } message CompressorPerRoute { @@ -159,7 +194,7 @@ message CompressorPerRoute { option (validate.required) = true; // If set, the filter will operate as a pass-through filter. - // Overrides Compressor.runtime_enabled and CommonDirectionConfig.enabled. + // Overrides ``Compressor.runtime_enabled`` and ``CommonDirectionConfig.enabled``. bool disabled = 1 [(validate.rules).bool = {const: true}]; // Per-route overrides. Fields set here will override corresponding fields in ``Compressor``. diff --git a/src/main/proto/envoy/extensions/filters/http/dynamic_modules/v3/dynamic_modules.proto b/src/main/proto/envoy/extensions/filters/http/dynamic_modules/v3/dynamic_modules.proto index 6e74df4..e4e8816 100644 --- a/src/main/proto/envoy/extensions/filters/http/dynamic_modules/v3/dynamic_modules.proto +++ b/src/main/proto/envoy/extensions/filters/http/dynamic_modules/v3/dynamic_modules.proto @@ -14,36 +14,47 @@ option java_multiple_files = true; option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/dynamic_modules/v3;dynamic_modulesv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; -// [#protodoc-title: HTTP filter for dynamic modules] +// [#protodoc-title: Dynamic Modules HTTP Filter] // [#extension: envoy.filters.http.dynamic_modules] -// Configuration of the HTTP filter for dynamic modules. This filter allows loading shared object files -// that can be loaded via dlopen by the HTTP filter. +// Configuration for the Dynamic Modules HTTP filter. This filter allows loading shared object files +// that can be loaded via ``dlopen`` to extend the HTTP filter chain. // -// A module can be loaded by multiple HTTP filters, hence the program can be structured in a way that -// the module is loaded only once and shared across multiple filters providing multiple functionalities. +// A module can be loaded by multiple HTTP filters; the module is loaded only once and shared across +// multiple filters. +// +// A dynamic module HTTP filter can opt into being a terminal filter with no upstream by setting +// :ref:`terminal_filter +// ` +// to ``true``. A terminal dynamic module can use ``send_`` ABI methods to send response headers, +// body, and trailers to the downstream. message DynamicModuleFilter { // Specifies the shared-object level configuration. envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1; - // The name for this filter configuration. This can be used to distinguish between different filter implementations - // inside a dynamic module. For example, a module can have completely different filter implementations. - // When Envoy receives this configuration, it passes the filter_name to the dynamic module's HTTP filter config init function - // together with the filter_config. - // That way a module can decide which in-module filter implementation to use based on the name at load time. + // The name for this filter configuration. + // + // This can be used to distinguish between different filter implementations inside a dynamic + // module. For example, a module can have completely different filter implementations. When Envoy + // receives this configuration, it passes the ``filter_name`` to the dynamic module's HTTP filter + // config init function together with the ``filter_config``. That way a module can decide which + // in-module filter implementation to use based on the name at load time. string filter_name = 2; - // The configuration for the filter chosen by filter_name. This is passed to the module's HTTP filter initialization function. - // Together with the filter_name, the module can decide which in-module filter implementation to use and + // The configuration for the filter chosen by ``filter_name``. + // + // This is passed to the module's HTTP filter initialization function. Together with the + // ``filter_name``, the module can decide which in-module filter implementation to use and // fine-tune the behavior of the filter. // - // For example, if a module has two filter implementations, one for logging and one for header manipulation, - // filter_name is used to choose either logging or header manipulation. The filter_config can be used to - // configure the logging level or the header manipulation behavior. + // For example, if a module has two filter implementations, one for logging and one for header + // manipulation, ``filter_name`` is used to choose either logging or header manipulation. The + // ``filter_config`` can be used to configure the logging level or the header manipulation + // behavior. // - // ``google.protobuf.Struct`` is serialized as JSON before - // passing it to the plugin. ``google.protobuf.BytesValue`` and - // ``google.protobuf.StringValue`` are passed directly without the wrapper. + // ``google.protobuf.Struct`` is serialized as JSON before passing it to the plugin. + // ``google.protobuf.BytesValue`` and ``google.protobuf.StringValue`` are passed directly without + // the wrapper. // // .. code-block:: yaml // @@ -58,32 +69,43 @@ message DynamicModuleFilter { // value: aGVsbG8= # echo -n "hello" | base64 // google.protobuf.Any filter_config = 3; + + // If ``true``, the dynamic module is a terminal filter to use without an upstream. + // + // The dynamic module is responsible for creating and sending the response to downstream. + // + // Defaults to ``false``. + bool terminal_filter = 4; } -// Configuration of the HTTP per-route filter for dynamic modules. This filter allows loading shared object files -// that can be loaded via dlopen by the HTTP filter. +// Configuration of the HTTP per-route filter for dynamic modules. message DynamicModuleFilterPerRoute { // Specifies the shared-object level configuration. envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1; - // The name for this filter configuration. This can be used to distinguish between different filter implementations - // inside a dynamic module. For example, a module can have completely different filter implementations. - // When Envoy receives this configuration, it passes the filter_name to the dynamic module's HTTP per-route filter config init function - // together with the filter_config. - // That way a module can decide which in-module filter implementation to use based on the name at load time. + // The name for this filter configuration. + // + // This can be used to distinguish between different filter implementations inside a dynamic + // module. For example, a module can have completely different filter implementations. When Envoy + // receives this configuration, it passes the ``per_route_config_name`` to the dynamic module's + // HTTP per-route filter config init function together with the ``filter_config``. That way a + // module can decide which in-module filter implementation to use based on the name at load time. string per_route_config_name = 2; - // The configuration for the filter chosen by filter_name. This is passed to the module's HTTP per-route filter initialization function. - // Together with the filter_name, the module can decide which in-module filter implementation to use and - // fine-tune the behavior of the filter on a specific route. + // The configuration for the filter chosen by ``per_route_config_name``. + // + // This is passed to the module's HTTP per-route filter initialization function. Together with + // the ``per_route_config_name``, the module can decide which in-module filter implementation to + // use and fine-tune the behavior of the filter on a specific route. // - // For example, if a module has two filter implementations, one for logging and one for header manipulation, - // filter_name is used to choose either logging or header manipulation. The filter_config can be used to - // configure the logging level or the header manipulation behavior. + // For example, if a module has two filter implementations, one for logging and one for header + // manipulation, ``per_route_config_name`` is used to choose either logging or header + // manipulation. The ``filter_config`` can be used to configure the logging level or the header + // manipulation behavior. // - // ``google.protobuf.Struct`` is serialized as JSON before - // passing it to the plugin. ``google.protobuf.BytesValue`` and - // ``google.protobuf.StringValue`` are passed directly without the wrapper. + // ``google.protobuf.Struct`` is serialized as JSON before passing it to the plugin. + // ``google.protobuf.BytesValue`` and ``google.protobuf.StringValue`` are passed directly without + // the wrapper. // // .. code-block:: yaml // diff --git a/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto b/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto index 0a2492b..7f70b70 100644 --- a/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto +++ b/src/main/proto/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto @@ -30,7 +30,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // External Authorization :ref:`configuration overview `. // [#extension: envoy.filters.http.ext_authz] -// [#next-free-field: 30] +// [#next-free-field: 32] message ExtAuthz { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v3.ExtAuthz"; @@ -53,67 +53,72 @@ message ExtAuthz { config.core.v3.ApiVersion transport_api_version = 12 [(validate.rules).enum = {defined_only: true}]; - // Changes filter's behavior on errors: + // Changes the filter's behavior on errors: // - // 1. When set to true, the filter will ``accept`` client request even if the communication with - // the authorization service has failed, or if the authorization service has returned a HTTP 5xx - // error. + // * When set to ``true``, the filter will ``accept`` the client request even if communication with + // the authorization service has failed, or if the authorization service has returned an HTTP 5xx + // error. // - // 2. When set to false, ext-authz will ``reject`` client requests and return a ``Forbidden`` - // response if the communication with the authorization service has failed, or if the - // authorization service has returned a HTTP 5xx error. + // * When set to ``false``, the filter will ``reject`` client requests and return ``Forbidden`` + // if communication with the authorization service has failed, or if the authorization service + // has returned an HTTP 5xx error. // - // Note that errors can be ``always`` tracked in the :ref:`stats - // `. + // Errors can always be tracked in the :ref:`stats `. + // + // Defaults to ``false``. bool failure_mode_allow = 2; - // When ``failure_mode_allow`` and ``failure_mode_allow_header_add`` are both set to true, + // When ``failure_mode_allow`` and ``failure_mode_allow_header_add`` are both set to ``true``, // ``x-envoy-auth-failure-mode-allowed: true`` will be added to request headers if the communication // with the authorization service has failed, or if the authorization service has returned a // HTTP 5xx error. bool failure_mode_allow_header_add = 19; - // Enables filter to buffer the client request body and send it within the authorization request. - // A ``x-envoy-auth-partial-body: false|true`` metadata header will be added to the authorization - // request message indicating if the body data is partial. + // Enables the filter to buffer the client request body and send it within the authorization request. + // The ``x-envoy-auth-partial-body: false|true`` metadata header will be added to the authorization + // request indicating whether the body data is partial. BufferSettings with_request_body = 5; - // Clears route cache in order to allow the external authorization service to correctly affect - // routing decisions. Filter clears all cached routes when: - // - // 1. The field is set to ``true``. - // - // 2. The status returned from the authorization service is a HTTP 200 or gRPC 0. + // Clears the route cache in order to allow the external authorization service to correctly affect + // routing decisions. The filter clears all cached routes when all of the following holds: // - // 3. At least one ``authorization response header`` is added to the client request, or is used for - // altering another client request header. + // * This field is set to ``true``. + // * The status returned from the authorization service is an HTTP 200 or gRPC 0. + // * At least one ``authorization response header`` is added to the client request, or is used to + // alter another client request header. // + // Defaults to ``false``. bool clear_route_cache = 6; // Sets the HTTP status that is returned to the client when the authorization server returns an error - // or cannot be reached. The default status is HTTP 403 Forbidden. + // or cannot be reached. + // + // The default status is ``HTTP 403 Forbidden``. type.v3.HttpStatus status_on_error = 7; - // When this is set to true, the filter will check the :ref:`ext_authz response - // ` for invalid header & - // query parameter mutations. If the side stream response is invalid, it will send a local reply - // to the downstream request with status HTTP 500 Internal Server Error. + // When set to ``true``, the filter will check the :ref:`ext_authz response + // ` for invalid header and + // query parameter mutations. If the response is invalid, the filter will send a local reply + // to the downstream request with status ``HTTP 500 Internal Server Error``. // - // Note that headers_to_remove & query_parameters_to_remove are validated, but invalid elements in - // those fields should not affect any headers & thus will not cause the filter to send a local - // reply. + // .. note:: + // Both ``headers_to_remove`` and ``query_parameters_to_remove`` are validated, but invalid elements in + // those fields should not affect any headers and thus will not cause the filter to send a local reply. // - // When set to false, any invalid mutations will be visible to the rest of envoy and may cause + // When set to ``false``, any invalid mutations will be visible to the rest of Envoy and may cause // unexpected behavior. // - // If you are using ext_authz with an untrusted ext_authz server, you should set this to true. + // If you are using ext_authz with an untrusted ext_authz server, you should set this to ``true``. + // + // Defaults to ``false``. bool validate_mutations = 24; // Specifies a list of metadata namespaces whose values, if present, will be passed to the // ext_authz service. The :ref:`filter_metadata ` // is passed as an opaque ``protobuf::Struct``. // - // Please note that this field exclusively applies to the gRPC ext_authz service and has no effect on the HTTP service. + // .. note:: + // This field applies exclusively to the gRPC ext_authz service and has no effect on the HTTP service. // // For example, if the ``jwt_authn`` filter is used and :ref:`payload_in_metadata // ` is set, @@ -130,10 +135,11 @@ message ExtAuthz { // ext_authz service. :ref:`typed_filter_metadata ` // is passed as a ``protobuf::Any``. // - // Please note that this field exclusively applies to the gRPC ext_authz service and has no effect on the HTTP service. + // .. note:: + // This field applies exclusively to the gRPC ext_authz service and has no effect on the HTTP service. // - // It works in a way similar to ``metadata_context_namespaces`` but allows Envoy and ext_authz server to share - // the protobuf message definition in order to do a safe parsing. + // This works similarly to ``metadata_context_namespaces`` but allows Envoy and the ext_authz server to share + // the protobuf message definition in order to perform safe parsing. // repeated string typed_metadata_context_namespaces = 16; @@ -146,7 +152,7 @@ message ExtAuthz { // Specifies a list of route metadata namespaces whose values, if present, will be passed to the // ext_authz service at :ref:`route_metadata_context ` in // :ref:`CheckRequest `. - // :ref:`typed_filter_metadata ` is passed as an ``protobuf::Any``. + // :ref:`typed_filter_metadata ` is passed as a ``protobuf::Any``. repeated string route_typed_metadata_context_namespaces = 22; // Specifies if the filter is enabled. @@ -159,13 +165,31 @@ message ExtAuthz { // Specifies if the filter is enabled with metadata matcher. // If this field is not specified, the filter will be enabled for all requests. + // + // .. note:: + // + // This field is only evaluated if the filter is instantiated. If the filter is marked with + // ``disabled: true`` in the :ref:`HttpFilter + // ` + // configuration or in per-route configuration via :ref:`ExtAuthzPerRoute + // `, + // the filter will not be instantiated and this field will have no effect. + // + // .. tip:: + // + // For dynamic filter activation based on metadata (such as metadata set by a preceding + // filter), consider using :ref:`ExtensionWithMatcher + // ` instead. This + // provides a more flexible matching framework that can evaluate conditions before filter + // instantiation. See the :ref:`ext_authz filter documentation + // ` for examples. type.matcher.v3.MetadataMatcher filter_enabled_metadata = 14; - // Specifies whether to deny the requests, when the filter is disabled. + // Specifies whether to deny the requests when the filter is disabled. // If :ref:`runtime_key ` is specified, - // Envoy will lookup the runtime key to determine whether to deny request for - // filter protected path at filter disabling. If filter is disabled in - // typed_per_filter_config for the path, requests will not be denied. + // Envoy will lookup the runtime key to determine whether to deny requests for filter-protected paths + // when the filter is disabled. If the filter is disabled in ``typed_per_filter_config`` for the path, + // requests will not be denied. // // If this field is not specified, all requests will be allowed when disabled. // @@ -176,11 +200,11 @@ message ExtAuthz { // Specifies if the peer certificate is sent to the external service. // - // When this field is true, Envoy will include the peer X.509 certificate, if available, in the + // When this field is ``true``, Envoy will include the peer X.509 certificate, if available, in the // :ref:`certificate`. bool include_peer_certificate = 10; - // Optional additional prefix to use when emitting statistics. This allows to distinguish + // Optional additional prefix to use when emitting statistics. This allows distinguishing // emitted statistics between configured ``ext_authz`` filters in an HTTP filter chain. For example: // // .. code-block:: yaml @@ -203,28 +227,27 @@ message ExtAuthz { string bootstrap_metadata_labels_key = 15; // Check request to authorization server will include the client request headers that have a correspondent match - // in the :ref:`list `. If this option isn't specified, then + // in the list. If this option isn't specified, then // all client request headers are included in the check request to a gRPC authorization server, whereas no client request headers // (besides the ones allowed by default - see note below) are included in the check request to an HTTP authorization server. // This inconsistency between gRPC and HTTP servers is to maintain backwards compatibility with legacy behavior. // // .. note:: // - // 1. For requests to an HTTP authorization server: in addition to the user's supplied matchers, ``Host``, ``Method``, ``Path``, - // ``Content-Length``, and ``Authorization`` are **additionally included** in the list. + // For requests to an HTTP authorization server: in addition to the user's supplied matchers, ``Host``, ``Method``, ``Path``, + // ``Content-Length``, and ``Authorization`` are **additionally included** in the list. // // .. note:: // - // 2. For requests to an HTTP authorization server: value of ``Content-Length`` will be set to 0 and the request to the + // For requests to an HTTP authorization server: the value of ``Content-Length`` will be set to ``0`` and the request to the // authorization server will not have a message body. However, the check request can include the buffered // client request body (controlled by :ref:`with_request_body - // ` setting), - // consequently the value of *Content-Length* of the authorization request reflects the size of - // its payload size. + // ` setting); + // consequently, the value of ``Content-Length`` in the authorization request reflects the size of its payload. // // .. note:: // - // 3. This can be overridden by the field ``disallowed_headers`` below. That is, if a header + // This can be overridden by the field ``disallowed_headers`` below. That is, if a header // matches for both ``allowed_headers`` and ``disallowed_headers``, the header will NOT be sent. type.matcher.v3.ListStringMatcher allowed_headers = 17; @@ -234,62 +257,63 @@ message ExtAuthz { // Specifies if the TLS session level details like SNI are sent to the external service. // - // When this field is true, Envoy will include the SNI name used for TLSClientHello, if available, in the + // When this field is ``true``, Envoy will include the SNI name used for TLSClientHello, if available, in the // :ref:`tls_session`. bool include_tls_session = 18; // Whether to increment cluster statistics (e.g. cluster..upstream_rq_*) on authorization failure. - // Defaults to true. + // Defaults to ``true``. google.protobuf.BoolValue charge_cluster_response_stats = 20; - // Whether to encode the raw headers (i.e. unsanitized values & unconcatenated multi-line headers) - // in authentication request. Works with both HTTP and gRPC clients. + // Whether to encode the raw headers (i.e., unsanitized values and unconcatenated multi-line headers) + // in the authorization request. Works with both HTTP and gRPC clients. // - // When this is set to true, header values are not sanitized. Headers with the same key will also + // When this is set to ``true``, header values are not sanitized. Headers with the same key will also // not be combined into a single, comma-separated header. // Requests to gRPC services will populate the field // :ref:`header_map`. // Requests to HTTP services will be constructed with the unsanitized header values and preserved // multi-line headers with the same key. // - // If this field is set to false, header values will be sanitized, with any non-UTF-8-compliant - // bytes replaced with '!'. Headers with the same key will have their values concatenated into a + // If this field is set to ``false``, header values will be sanitized, with any non-UTF-8-compliant + // bytes replaced with ``'!'``. Headers with the same key will have their values concatenated into a // single comma-separated header value. // Requests to gRPC services will populate the field // :ref:`headers`. // Requests to HTTP services will have their header values sanitized and will not preserve // multi-line headers with the same key. // - // It's recommended you set this to true unless you already rely on the old behavior. False is the - // default only for backwards compatibility. + // It is recommended to set this to ``true`` unless you rely on the previous behavior. + // + // It is set to ``false`` by default for backwards compatibility. bool encode_raw_headers = 23; // Rules for what modifications an ext_authz server may make to the request headers before - // continuing decoding / forwarding upstream. + // continuing decoding or forwarding upstream. // - // If set to anything, enables header mutation checking against configured rules. Note that + // If set, enables header mutation checking against the configured rules. Note that // :ref:`HeaderMutationRules ` - // has defaults that change ext_authz behavior. Also note that if this field is set to anything, - // ext_authz can no longer append to :-prefixed headers. + // has defaults that change ext_authz behavior. Also note that if this field is set, + // ext_authz can no longer append to ``:``-prefixed headers. // - // If empty, header mutation rule checking is completely disabled. + // If unset, header mutation rule checking is completely disabled. // - // Regardless of what is configured here, ext_authz cannot remove :-prefixed headers. + // Regardless of what is configured here, ext_authz cannot remove ``:``-prefixed headers. // // This field and ``validate_mutations`` have different use cases. ``validate_mutations`` enables - // correctness checks for all header / query parameter mutations (e.g. for invalid characters). + // correctness checks for all header and query parameter mutations (for example, invalid characters). // This field allows the filter to reject mutations to specific headers. config.common.mutation_rules.v3.HeaderMutationRules decoder_header_mutation_rules = 26; - // Enable / disable ingestion of dynamic metadata from ext_authz service. + // Enable or disable ingestion of dynamic metadata from the ext_authz service. // - // If false, the filter will ignore dynamic metadata injected by the ext_authz service. If the + // If ``false``, the filter will ignore dynamic metadata injected by the ext_authz service. If the // ext_authz service tries injecting dynamic metadata, the filter will log, increment the // ``ignored_dynamic_metadata`` stat, then continue handling the response. // - // If true, the filter will ingest dynamic metadata entries as normal. + // If ``true``, the filter will ingest dynamic metadata entries as normal. // - // If unset, defaults to true. + // If unset, defaults to ``true``. google.protobuf.BoolValue enable_dynamic_metadata_ingestion = 27; // Additional metadata to be added to the filter state for logging purposes. The metadata will be @@ -297,19 +321,44 @@ message ExtAuthz { // name. google.protobuf.Struct filter_metadata = 28; - // When set to true, the filter will emit per-stream stats for access logging. The filter state + // When set to ``true``, the filter will emit per-stream stats for access logging. The filter state // key will be the same as the filter name. // // If using Envoy gRPC, emits latency, bytes sent / received, upstream info, and upstream cluster - // info. If not using Envoy gRPC, emits only latency. Note that stats are ONLY added to filter - // state if a check request is actually made to an ext_authz service. + // info. If not using Envoy gRPC, emits only latency. + // + // .. note:: + // Stats are ONLY added to filter state if a check request is actually made to an ext_authz service. // - // If this is false the filter will not emit stats, but filter_metadata will still be respected if + // If this is ``false`` the filter will not emit stats, but filter_metadata will still be respected if // it has a value. // // Field ``latency_us`` is exposed for CEL and logging when using gRPC or HTTP service. // Fields ``bytesSent`` and ``bytesReceived`` are exposed for CEL and logging only when using gRPC service. bool emit_filter_state_stats = 29; + + // Sets the maximum size (in bytes) of the response body that the filter will send downstream + // when a request is denied by the external authorization service. + // + // If the authorization server returns a response body larger than this configured limit, + // the body will be truncated to ``max_denied_response_body_bytes`` before being sent to the + // downstream client. + // + // If this field is not set or is set to 0, no truncation will occur, and the entire + // denied response body will be forwarded. + uint32 max_denied_response_body_bytes = 30; + + // When set to ``true``, the filter will enforce the response header map's count and size limits + // by sending a local reply when those limits are violated. + // + // When set to ``false``, the filter will ignore the response header map's limits and add / set + // all response headers as specified by the external authorization service. + // + // Recommendation: enable if the external authorization service is not trusted. Otherwise, leave + // it ``false``. + // + // Defaults to ``false``. + bool enforce_response_header_limits = 31; } // Configuration for buffering the request data. @@ -318,36 +367,45 @@ message BufferSettings { "envoy.config.filter.http.ext_authz.v2.BufferSettings"; // Sets the maximum size of a message body that the filter will hold in memory. Envoy will return - // ``HTTP 413`` and will *not* initiate the authorization process when buffer reaches the number - // set in this field. Note that this setting will have precedence over :ref:`failure_mode_allow - // `. + // ``HTTP 413`` and will *not* initiate the authorization process when the buffer reaches the size + // set in this field. + // + // .. note:: + // This setting will have precedence over :ref:`failure_mode_allow + // `. uint32 max_request_bytes = 1 [(validate.rules).uint32 = {gt: 0}]; - // When this field is true, Envoy will buffer the message until ``max_request_bytes`` is reached. + // When this field is ``true``, Envoy will buffer the message until ``max_request_bytes`` is reached. // The authorization request will be dispatched and no 413 HTTP error will be returned by the // filter. + // + // Defaults to ``false``. bool allow_partial_message = 2; - // If true, the body sent to the external authorization service is set with raw bytes, it sets - // the :ref:`raw_body` - // field of HTTP request attribute context. Otherwise, :ref:`body - // ` will be filled - // with UTF-8 string request body. + // If ``true``, the body sent to the external authorization service is set as raw bytes and populates + // :ref:`raw_body` + // in the HTTP request attribute context. Otherwise, :ref:`body + // ` will be populated + // with a UTF-8 string request body. // // This field only affects configurations using a :ref:`grpc_service // `. In configurations that use // an :ref:`http_service `, this // has no effect. + // + // Defaults to ``false``. bool pack_as_bytes = 3; } // HttpService is used for raw HTTP communication between the filter and the authorization service. // When configured, the filter will parse the client request and use these attributes to call the // authorization server. Depending on the response, the filter may reject or accept the client -// request. Note that in any of these events, metadata can be added, removed or overridden by the -// filter: +// request. +// +// .. note:: +// In any of these events, metadata can be added, removed or overridden by the filter: // -// *On authorization request*, a list of allowed request headers may be supplied. See +// On authorization request, a list of allowed request headers may be supplied. See // :ref:`allowed_headers // ` // for details. Additional headers metadata may be added to the authorization request. See @@ -355,7 +413,7 @@ message BufferSettings { // ` for // details. // -// On authorization response status HTTP 200 OK, the filter will allow traffic to the upstream and +// On authorization response status ``HTTP 200 OK``, the filter will allow traffic to the upstream and // additional headers metadata may be added to the original client request. See // :ref:`allowed_upstream_headers // ` @@ -368,7 +426,7 @@ message BufferSettings { // metadata as well as body may be added to the client's response. See :ref:`allowed_client_headers // ` // for details. -// [#next-free-field: 9] +// [#next-free-field: 10] message HttpService { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v2.HttpService"; @@ -386,14 +444,21 @@ message HttpService { // Settings used for controlling authorization response metadata. AuthorizationResponse authorization_response = 8; + + // Optional retry policy for requests to the authorization server. + // If not set, no retries will be performed. + // + // .. note:: + // When this field is set, the ``ext_authz`` filter will buffer the request body for retry purposes. + config.core.v3.RetryPolicy retry_policy = 9; } message AuthorizationRequest { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v2.AuthorizationRequest"; - // Authorization request includes the client request headers that have a correspondent match - // in the :ref:`list `. + // Authorization request includes the client request headers that have a corresponding match + // in the list. // This field has been deprecated in favor of :ref:`allowed_headers // `. // @@ -404,17 +469,19 @@ message AuthorizationRequest { // // .. note:: // - // By default, ``Content-Length`` header is set to ``0`` and the request to the authorization + // By default, the ``Content-Length`` header is set to ``0`` and the request to the authorization // service has no message body. However, the authorization request *may* include the buffered // client request body (controlled by :ref:`with_request_body // ` - // setting) hence the value of its ``Content-Length`` reflects the size of its payload size. + // setting); hence the value of its ``Content-Length`` reflects the size of its payload. // type.matcher.v3.ListStringMatcher allowed_headers = 1 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // Sets a list of headers that will be included to the request to authorization service. Note that - // client request of the same key will be overridden. + // Sets a list of headers that will be included in the request to the authorization service. + // + // .. note:: + // Client request headers with the same key will be overridden. repeated config.core.v3.HeaderValue headers_to_add = 2; } @@ -423,30 +490,37 @@ message AuthorizationResponse { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v2.AuthorizationResponse"; - // When this :ref:`list ` is set, authorization + // When this list is set, authorization // response headers that have a correspondent match will be added to the original client request. - // Note that coexistent headers will be overridden. + // + // .. note:: + // Existing headers will be overridden. type.matcher.v3.ListStringMatcher allowed_upstream_headers = 1; - // When this :ref:`list ` is set, authorization + // When this list is set, authorization // response headers that have a correspondent match will be added to the original client request. - // Note that coexistent headers will be appended. + // + // .. note:: + // Existing headers will be appended. type.matcher.v3.ListStringMatcher allowed_upstream_headers_to_append = 3; - // When this :ref:`list ` is set, authorization - // response headers that have a correspondent match will be added to the client's response. Note - // that when this list is *not* set, all the authorization response headers, except ``Authority - // (Host)`` will be in the response to the client. When a header is included in this list, ``Path``, - // ``Status``, ``Content-Length``, ``WWWAuthenticate`` and ``Location`` are automatically added. + // When this list is set, authorization + // response headers that have a correspondent match will be added to the client's response. + // When a header is included in this list, ``Path``, ``Status``, ``Content-Length``, ``WWW-Authenticate`` and + // ``Location`` are automatically added. + // + // .. note:: + // When this list is *not* set, all the authorization response headers, except + // ``Authority (Host)``, will be in the response to the client. type.matcher.v3.ListStringMatcher allowed_client_headers = 2; - // When this :ref:`list ` is set, authorization + // When this list is set, authorization // response headers that have a correspondent match will be added to the client's response when // the authorization response itself is successful, i.e. not failed or denied. When this list is // *not* set, no additional headers will be added to the client's response on success. type.matcher.v3.ListStringMatcher allowed_client_headers_on_success = 4; - // When this :ref:`list ` is set, authorization + // When this list is set, authorization // response headers that have a correspondent match will be emitted as dynamic metadata to be consumed // by the next filter. This metadata lives in a namespace specified by the canonical name of extension filter // that requires it: @@ -466,7 +540,7 @@ message ExtAuthzPerRoute { // Disable the ext auth filter for this particular vhost or route. // If disabled is specified in multiple per-filter-configs, the most specific one will be used. - // If the filter is disabled by default and this is set to false, the filter will be enabled + // If the filter is disabled by default and this is set to ``false``, the filter will be enabled // for this vhost or route. bool disabled = 1; @@ -476,6 +550,7 @@ message ExtAuthzPerRoute { } // Extra settings for the check request. +// [#next-free-field: 6] message CheckSettings { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v2.CheckSettings"; @@ -492,15 +567,14 @@ message CheckSettings { // Merge semantics for this field are such that keys from more specific configs override. // // .. note:: - // // These settings are only applied to a filter configured with a // :ref:`grpc_service`. map context_extensions = 1 [(udpa.annotations.sensitive) = true]; - // When set to true, disable the configured :ref:`with_request_body + // When set to ``true``, disable the configured :ref:`with_request_body // ` for a specific route. // - // Please note that only one of *disable_request_body_buffering* or + // Only one of ``disable_request_body_buffering`` and // :ref:`with_request_body ` // may be specified. bool disable_request_body_buffering = 2; @@ -509,8 +583,20 @@ message CheckSettings { // :ref:`with_request_body ` // option for a specific route. // - // Please note that only one of ``with_request_body`` or + // Only one of ``with_request_body`` and // :ref:`disable_request_body_buffering ` // may be specified. BufferSettings with_request_body = 3; + + // Override the external authorization service for this route. + // This allows different routes to use different external authorization service backends + // and service types (gRPC or HTTP). If specified, this overrides the filter-level service + // configuration regardless of the original service type. + oneof service_override { + // Override with a gRPC service configuration. + config.core.v3.GrpcService grpc_service = 4; + + // Override with an HTTP service configuration. + HttpService http_service = 5; + } } diff --git a/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto b/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto index 2187c45..b07811d 100644 --- a/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto +++ b/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/ext_proc.proto @@ -9,6 +9,7 @@ import "envoy/config/core/v3/grpc_service.proto"; import "envoy/config/core/v3/http_service.proto"; import "envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto"; import "envoy/type/matcher/v3/string.proto"; +import "envoy/type/v3/http_status.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; @@ -16,6 +17,7 @@ import "google/protobuf/wrappers.proto"; import "xds/annotations/v3/status.proto"; +import "envoy/annotations/deprecation.proto"; import "udpa/annotations/migrate.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -48,8 +50,6 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // // * Whether it receives the response message at all. // * Whether it receives the message body at all, in separate chunks, or as a single buffer. -// * Whether subsequent HTTP requests are transmitted synchronously or whether they are -// sent asynchronously. // * To modify request or response trailers if they already exist. // // The filter supports up to six different processing steps. Each is represented by @@ -57,9 +57,13 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // processor must send a matching response. // // * Request headers: Contains the headers from the original HTTP request. -// * Request body: Delivered if they are present and sent in a single message if -// the ``BUFFERED`` or ``BUFFERED_PARTIAL`` mode is chosen, in multiple messages if the -// ``STREAMED`` mode is chosen, and not at all otherwise. +// * Request body: If the body is present, the behavior depends on the +// body send mode. In ``BUFFERED`` or ``BUFFERED_PARTIAL`` mode, the body is sent to the external +// processor in a single message. In ``STREAMED`` or ``FULL_DUPLEX_STREAMED`` mode, the body will +// be split across multiple messages sent to the external processor. In ``GRPC`` mode, as each +// gRPC message arrives, it will be sent to the external processor (there will be exactly one +// gRPC message in each message sent to the external processor). In ``NONE`` mode, the body will +// not be sent to the external processor. // * Request trailers: Delivered if they are present and if the trailer mode is set // to ``SEND``. // * Response headers: Contains the headers from the HTTP response. Keep in mind @@ -75,7 +79,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // from the external processor. The latter is only enabled if ``allow_mode_override`` is // set to true. This way, a processor may, for example, use information // in the request header to determine whether the message body must be examined, or whether -// the proxy should simply stream it straight through. +// the data plane should simply stream it straight through. // // All of this together allows a server to process the filter traffic in fairly // sophisticated ways. For example: @@ -84,12 +88,8 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // on the content of the headers. // * A server may choose to immediately reject some messages based on their HTTP // headers (or other dynamic metadata) and more carefully examine others. -// * A server may asynchronously monitor traffic coming through the filter by inspecting -// headers, bodies, or both, and then decide to switch to a synchronous processing -// mode, either permanently or temporarily. // -// The protocol itself is based on a bidirectional gRPC stream. Envoy will send the -// server +// The protocol itself is based on a bidirectional gRPC stream. The data plane will send the server // :ref:`ProcessingRequest ` // messages, and the server must reply with // :ref:`ProcessingResponse `. @@ -98,7 +98,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // ` object in a namespace matching the filter // name. // -// [#next-free-field: 24] +// [#next-free-field: 26] message ExternalProcessor { // Describes the route cache action to be taken when an external processor response // is received in response to request headers. @@ -124,7 +124,6 @@ message ExternalProcessor { reserved "async_mode"; // Configuration for the gRPC service that the filter will communicate with. - // The filter supports both the "Envoy" and "Google" gRPC clients. // Only one of ``grpc_service`` or ``http_service`` can be set. // It is required that one of them must be set. config.core.v3.GrpcService grpc_service = 1 @@ -140,14 +139,14 @@ message ExternalProcessor { // cannot be configured to send any body or trailers. i.e., ``http_service`` only supports // sending request or response headers to the side stream server. // - // With this configuration, Envoy behavior: + // With this configuration, the data plane behavior is: // // 1. The headers are first put in a proto message // :ref:`ProcessingRequest `. // // 2. This proto message is then transcoded into a JSON text. // - // 3. Envoy then sends an HTTP POST message with content-type as "application/json", + // 3. The data plane then sends an HTTP POST message with content-type as "application/json", // and this JSON text as body to the side stream server. // // After the side-stream receives this HTTP request message, it is expected to do as follows: @@ -160,7 +159,7 @@ message ExternalProcessor { // // 3. It converts the ``ProcessingResponse`` proto message into a JSON text. // - // 4. It then sends an HTTP response back to Envoy with status code as ``"200"``, + // 4. It then sends an HTTP response back to the data plane with status code as ``"200"``, // ``content-type`` as ``"application/json"`` and sets the JSON text as the body. // ExtProcHttpService http_service = 20 [ @@ -190,28 +189,31 @@ message ExternalProcessor { // sent. See ``ProcessingMode`` for details. ProcessingMode processing_mode = 3; - // Envoy provides a number of :ref:`attributes ` + // The data plane provides a number of :ref:`attributes ` // for expressive policies. Each attribute name provided in this field will be - // matched against that list and populated in the ``request_headers`` message. + // matched against that list and populated in the + // :ref:`ProcessingRequest.attributes ` field. // See the :ref:`attribute documentation ` // for the list of supported attributes and their types. repeated string request_attributes = 5; - // Envoy provides a number of :ref:`attributes ` + // The data plane provides a number of :ref:`attributes ` // for expressive policies. Each attribute name provided in this field will be - // matched against that list and populated in the ``response_headers`` message. + // matched against that list and populated in the + // :ref:`ProcessingRequest.attributes ` field. // See the :ref:`attribute documentation ` // for the list of supported attributes and their types. repeated string response_attributes = 6; - // Specifies the timeout for each individual message sent on the stream and - // when the filter is running in synchronous mode. Whenever the proxy sends - // a message on the stream that requires a response, it will reset this timer, - // and will stop processing and return an error (subject to the processing mode) - // if the timer expires before a matching response is received. There is no - // timeout when the filter is running in asynchronous mode. Zero is a valid - // config which means the timer will be triggered immediately. If not - // configured, default is 200 milliseconds. + // Specifies the timeout for each individual message sent on the stream. + // Whenever the data plane sends a message on the stream that requires a + // response, it will reset this timer, and will stop processing and return + // an error (subject to the processing mode) if the timer expires before a + // matching response is received. There is no timeout when the filter is + // running in observability mode or when the body send mode is + // ``FULL_DUPLEX_STREAMED`` or ``GRPC``. Zero is a valid config which means + // the timer will be triggered immediately. If not configured, default is + // 200 milliseconds. google.protobuf.Duration message_timeout = 7 [(validate.rules).duration = { lte {seconds: 3600} gte {} @@ -228,7 +230,7 @@ message ExternalProcessor { // :ref:`header_prefix ` // (which is usually "x-envoy"). // Note that changing headers such as "host" or ":authority" may not in itself - // change Envoy's routing decision, as routes can be cached. To also force the + // change the data plane's routing decision, as routes can be cached. To also force the // route to be recomputed, set the // :ref:`clear_route_cache ` // field to true in the same response. @@ -256,6 +258,7 @@ message ExternalProcessor { // can be overridden by the response message from the external processing server // :ref:`mode_override `. // If not set, ``mode_override`` API in the response message will be ignored. + // Mode override is not supported if the body send mode is ``FULL_DUPLEX_STREAMED``. bool allow_mode_override = 14; // If set to true, ignore the @@ -270,10 +273,10 @@ message ExternalProcessor { // If true, send each part of the HTTP request or response specified by ``ProcessingMode`` // without pausing on filter chain iteration. It is "Send and Go" mode that can be used - // by external processor to observe Envoy data and status. In this mode: + // by external processor to observe the request's data and status. In this mode: // - // 1. Only ``STREAMED`` body processing mode is supported and any other body processing modes will be - // ignored. ``NONE`` mode (i.e., skip body processing) will still work as expected. + // 1. Only ``STREAMED``, ``GRPC``, and ``NONE`` body processing modes are supported; for any + // other body processing mode, the body will not be sent. // // 2. External processor should not send back processing response, as any responses will be ignored. // This also means that @@ -310,12 +313,13 @@ message ExternalProcessor { // Specifies the deferred closure timeout for gRPC stream that connects to external processor. Currently, the deferred stream closure // is only used in :ref:`observability_mode `. // In observability mode, gRPC streams may be held open to the external processor longer than the lifetime of the regular client to - // backend stream lifetime. In this case, Envoy will eventually timeout the external processor stream according to this time limit. + // backend stream lifetime. In this case, the data plane will eventually timeout the external processor stream according to this time limit. // The default value is 5000 milliseconds (5 seconds) if not specified. google.protobuf.Duration deferred_close_timeout = 19; // Send body to the side stream server once it arrives without waiting for the header response from that server. - // It only works for ``STREAMED`` body processing mode. For any other body processing modes, it is ignored. + // It only works for ``STREAMED`` body processing mode. For any other body + // processing modes, it is ignored. // The server has two options upon receiving a header request: // // 1. Instant Response: send the header response as soon as the header request is received. @@ -324,9 +328,9 @@ message ExternalProcessor { // // In all scenarios, the header-body ordering must always be maintained. // - // If enabled Envoy will ignore the + // If enabled the data plane will ignore the // :ref:`mode_override ` - // value that the server sends in the header response. This is because Envoy may have already + // value that the server sends in the header response. This is because the data plane may have already // sent the body to the server, prior to processing the header response. bool send_body_without_waiting_for_header_response = 21; @@ -340,6 +344,16 @@ message ExternalProcessor { // Since ``request_header_mode`` is not applicable in any way, it's ignored in comparison. repeated ProcessingMode allowed_override_modes = 22; + // Decorator to introduce custom logic that runs after the ``ProcessingRequest`` is constructed, but + // before it is sent to the External Processor. The ``ProcessingRequest`` may be modified. + // + // .. note:: + // Processing request modifiers are currently in alpha. + // + // [#extension-category: envoy.http.ext_proc.processing_request_modifiers] + config.core.v3.TypedExtensionConfig processing_request_modifier = 25 + [(xds.annotations.v3.field_status).work_in_progress = true]; + // Decorator to introduce custom logic that runs after a message received from // the External Processor is processed, but before continuing filter chain iteration. // @@ -349,6 +363,12 @@ message ExternalProcessor { // [#extension-category: envoy.http.ext_proc.response_processors] config.core.v3.TypedExtensionConfig on_processing_response = 23 [(xds.annotations.v3.field_status).work_in_progress = true]; + + // Sets the HTTP status code that is returned to the client when the external processing server returns + // an error, fails to respond, or cannot be reached. + // + // The default status is ``HTTP 500 Internal Server Error``. + type.v3.HttpStatus status_on_error = 24; } // ExtProcHttpService is used for HTTP communication between the filter and the external processing service. @@ -373,14 +393,21 @@ message MetadataOptions { repeated string typed = 2; } - // Describes which typed or untyped dynamic metadata namespaces to forward to + // Describes which typed or untyped filter dynamic metadata namespaces to forward to // the external processing server. MetadataNamespaces forwarding_namespaces = 1; - // Describes which typed or untyped dynamic metadata namespaces to accept from + // Describes which typed or untyped filter dynamic metadata namespaces to accept from // the external processing server. Set to empty or leave unset to disallow writing // any received dynamic metadata. Receiving of typed metadata is not supported. MetadataNamespaces receiving_namespaces = 2; + + // Describes which cluster metadata namespaces to forward to + // the external processing server. + // .. note:: + // This is the least specific metadata. Should there be any namespace collision, + // cluster level metadata can be overridden by filter metadata. + MetadataNamespaces cluster_metadata_forwarding_namespaces = 3; } // The HeaderForwardingRules structure specifies what headers are @@ -423,14 +450,15 @@ message ExtProcPerRoute { } // Overrides that may be set on a per-route basis -// [#next-free-field: 9] +// [#next-free-field: 10] message ExtProcOverrides { // Set a different processing mode for this route than the default. ProcessingMode processing_mode = 1; // [#not-implemented-hide:] // Set a different asynchronous processing option than the default. - bool async_mode = 2; + // Deprecated and not implemented. + bool async_mode = 2 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; // [#not-implemented-hide:] // Set different optional attributes than the default setting of the @@ -462,4 +490,11 @@ message ExtProcOverrides { // or could not be opened. This field is the per-route override of // :ref:`failure_mode_allow `. google.protobuf.BoolValue failure_mode_allow = 8; + + // Decorator to introduce custom logic that runs after the ``ProcessingRequest`` is constructed, but + // before it is sent to the External Processor. The ``ProcessingRequest`` may be modified. + // This is a per-route override of + // :ref:`processing_request_modifier `. + config.core.v3.TypedExtensionConfig processing_request_modifier = 9 + [(xds.annotations.v3.field_status).work_in_progress = true]; } diff --git a/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto b/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto index 467320d..e2ec894 100644 --- a/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto +++ b/src/main/proto/envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto @@ -65,8 +65,7 @@ message ProcessingMode { // Do not send the body at all. This is the default. NONE = 0; - // Stream the body to the server in pieces as they arrive at the - // proxy. + // Stream the body to the server in pieces as they are seen. STREAMED = 1; // Buffer the message body in memory and send the entire body at once. @@ -79,11 +78,11 @@ message ProcessingMode { // up to the buffer limit will be sent. BUFFERED_PARTIAL = 3; - // Envoy streams the body to the server in pieces as they arrive. + // The ext_proc client (the data plane) streams the body to the server in pieces as they arrive. // // 1) The server may choose to buffer any number chunks of data before processing them. // After it finishes buffering, the server processes the buffered data. Then it splits the processed - // data into any number of chunks, and streams them back to Envoy one by one. + // data into any number of chunks, and streams them back to the ext_proc client one by one. // The server may continuously do so until the complete body is processed. // The individual response chunk size is recommended to be no greater than 64K bytes, or // :ref:`max_receive_message_length ` @@ -98,17 +97,36 @@ message ProcessingMode { // // In this body mode: // * The corresponding trailer mode has to be set to ``SEND``. - // * Envoy will send body and trailers (if present) to the server as they arrive. + // * The client will send body and trailers (if present) to the server as they arrive. // Sending the trailers (if present) is to inform the server the complete body arrives. - // In case there are no trailers, then Envoy will set + // In case there are no trailers, then the client will set // :ref:`end_of_stream ` // to true as part of the last body chunk request to notify the server that no other data is to be sent. // * The server needs to send // :ref:`StreamedBodyResponse ` - // to Envoy in the body response. - // * Envoy will stream the body chunks in the responses from the server to the upstream/downstream as they arrive. + // to the client in the body response. + // * The client will stream the body chunks in the responses from the server to the upstream/downstream as they arrive. FULL_DUPLEX_STREAMED = 4; + + // [#not-implemented-hide:] + // A mode for gRPC traffic. This is similar to ``FULL_DUPLEX_STREAMED``, + // except that instead of sending raw chunks of the HTTP/2 DATA frames, + // the ext_proc client will de-frame the individual gRPC messages inside + // the HTTP/2 DATA frames, and as each message is de-framed, it will be + // sent to the ext_proc server as a :ref:`request_body + // ` + // or :ref:`response_body + // `. + // The ext_proc server will stream back individual gRPC messages in the + // :ref:`StreamedBodyResponse ` + // field, but the number of messages sent by the ext_proc server + // does not need to equal the number of messages sent by the data + // plane. This allows the ext_proc server to change the number of + // messages sent on the stream. + // In this mode, the client will send body and trailers to the server as + // they arrive. + GRPC = 5; } // How to handle the request header. Default is "SEND". diff --git a/src/main/proto/envoy/extensions/filters/http/geoip/v3/geoip.proto b/src/main/proto/envoy/extensions/filters/http/geoip/v3/geoip.proto index 4ef26a8..7703544 100644 --- a/src/main/proto/envoy/extensions/filters/http/geoip/v3/geoip.proto +++ b/src/main/proto/envoy/extensions/filters/http/geoip/v3/geoip.proto @@ -24,18 +24,44 @@ message Geoip { message XffConfig { // The number of additional ingress proxy hops from the right side of the // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when - // determining the origin client's IP address. The default is zero if this option - // is not specified. See the documentation for + // determining the origin client's IP address. See the documentation for // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. + // + // Defaults to ``0``. uint32 xff_num_trusted_hops = 1; } - // If set, the :ref:`xff_num_trusted_hops ` field will be used to determine - // trusted client address from ``x-forwarded-for`` header. - // Otherwise, the immediate downstream connection source address will be used. - // [#next-free-field: 2] + message CustomHeaderConfig { + // The name of the request header to extract the client IP address from. + // The header value must contain a valid IP address (IPv4 or IPv6). + // + // If the header is missing or contains an invalid IP address, the filter will fall back + // to using the immediate downstream connection source address. + string header_name = 1 [(validate.rules).string = {min_len: 1}]; + } + + // Configuration for extracting the client IP address from the + // ``x-forwarded-for`` header. If set, the + // :ref:`xff_num_trusted_hops ` + // field will be used to determine the trusted client address from the ``x-forwarded-for`` header. + // If not set, the immediate downstream connection source address will be used. + // + // Only one of ``xff_config`` or + // :ref:`custom_header_config ` + // can be set. XffConfig xff_config = 1; + // Configuration for extracting the client IP address from a custom request header. + // + // If set, the + // :ref:`header_name ` + // field will be used to extract the client IP address from the specified request header. + // + // Only one of ``custom_header_config`` or + // :ref:`xff_config ` + // can be set. + CustomHeaderConfig custom_header_config = 4; + // Geoip driver specific configuration which depends on the driver being instantiated. // See the geoip drivers for examples: // diff --git a/src/main/proto/envoy/extensions/filters/http/header_to_metadata/v3/header_to_metadata.proto b/src/main/proto/envoy/extensions/filters/http/header_to_metadata/v3/header_to_metadata.proto index a34568c..662eefc 100644 --- a/src/main/proto/envoy/extensions/filters/http/header_to_metadata/v3/header_to_metadata.proto +++ b/src/main/proto/envoy/extensions/filters/http/header_to_metadata/v3/header_to_metadata.proto @@ -27,6 +27,7 @@ message Config { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.header_to_metadata.v2.Config"; + // Specifies the value type to use in metadata. enum ValueType { STRING = 0; @@ -37,14 +38,18 @@ message Config { PROTOBUF_VALUE = 2; } - // ValueEncode defines the encoding algorithm. + // Specifies the encoding scheme for the value. enum ValueEncode { - // The value is not encoded. + // No encoding is applied. NONE = 0; // The value is encoded in `Base64 `_. - // Note: this is mostly used for STRING and PROTOBUF_VALUE to escape the - // non-ASCII characters in the header. + // + // .. note:: + // + // This is mostly used for ``STRING`` and ``PROTOBUF_VALUE`` to escape the + // non-ASCII characters in the header. + // BASE64 = 1; } @@ -74,7 +79,10 @@ message Config { // // This is only used for :ref:`on_header_present `. // - // Note: if the ``value`` field is non-empty this field should be empty. + // .. note:: + // + // If the ``value`` field is non-empty this field should be empty. + // type.matcher.v3.RegexMatchAndSubstitute regex_value_rewrite = 6 [(udpa.annotations.field_migrate).oneof_promotion = "value_type"]; @@ -106,15 +114,15 @@ message Config { (udpa.annotations.field_migrate).oneof_promotion = "header_cookie_specifier" ]; - // If the header or cookie is present, apply this metadata KeyValuePair. + // If the header or cookie is present, apply this metadata ``KeyValuePair``. // - // If the value in the KeyValuePair is non-empty, it'll be used instead + // If the value in the ``KeyValuePair`` is non-empty, it'll be used instead // of the header or cookie value. KeyValuePair on_header_present = 2 [(udpa.annotations.field_migrate).rename = "on_present"]; - // If the header or cookie is not present, apply this metadata KeyValuePair. + // If the header or cookie is not present, apply this metadata ``KeyValuePair``. // - // The value in the KeyValuePair must be set, since it'll be used in lieu + // The value in the ``KeyValuePair`` must be set, since it'll be used in lieu // of the missing header or cookie value. KeyValuePair on_header_missing = 3 [(udpa.annotations.field_migrate).rename = "on_missing"]; @@ -130,4 +138,15 @@ message Config { // The list of rules to apply to responses. repeated Rule response_rules = 2; + + // Optional prefix to use when emitting filter statistics. When configured, + // statistics are emitted with the prefix ``http_filter_name.``. + // + // This emits statistics such as: + // + // - ``http_filter_name.my_header_converter.rules_processed`` + // - ``http_filter_name.my_header_converter.metadata_added`` + // + // If not configured, no statistics are emitted. + string stat_prefix = 3; } diff --git a/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto b/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto index 02ab21d..9a955bd 100644 --- a/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto +++ b/src/main/proto/envoy/extensions/filters/http/jwt_authn/v3/config.proto @@ -77,17 +77,20 @@ message JwtProvider { // It is optional. If specified, it has to match the ``iss`` field in JWT, // otherwise the JWT ``iss`` field is not checked. // - // Note: ``JwtRequirement`` :ref:`allow_missing ` - // and :ref:`allow_missing_or_failed ` - // are implemented differently than other ``JwtRequirements``. Hence the usage of this field - // is different as follows if ``allow_missing`` or ``allow_missing_or_failed`` is used: + // .. note:: + // ``JwtRequirement`` :ref:`allow_missing ` + // and :ref:`allow_missing_or_failed ` + // are implemented differently than other ``JwtRequirements``. Hence the usage of this field + // is different as follows if ``allow_missing`` or ``allow_missing_or_failed`` is used: // - // * If a JWT has ``iss`` field, it needs to be specified by this field in one of ``JwtProviders``. - // * If a JWT doesn't have ``iss`` field, one of ``JwtProviders`` should fill this field empty. - // * Multiple ``JwtProviders`` should not have same value in this field. + // * If a JWT has ``iss`` field, it needs to be specified by this field in one of ``JwtProviders``. + // * If a JWT doesn't have ``iss`` field, one of ``JwtProviders`` should fill this field empty. + // * Multiple ``JwtProviders`` should not have same value in this field. // - // Example: https://securetoken.google.com - // Example: 1234567-compute@developer.gserviceaccount.com + // Examples: + // + // * https://securetoken.google.com + // * Example: 1234567-compute@developer.gserviceaccount.com // string issuer = 1; @@ -558,7 +561,7 @@ message ProviderWithAudiences { // - allow_missing: {} // - provider_name: provider-B // -// [#next-free-field: 7] +// [#next-free-field: 8] message JwtRequirement { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.jwt_authn.v2alpha.JwtRequirement"; @@ -589,9 +592,41 @@ message JwtRequirement { // to only verify JWTs and pass the verified payload to another filter. The // different is this mode will reject requests with invalid tokens. google.protobuf.Empty allow_missing = 6; + + // Extract JWT claims without performing signature validation. + // This mode will decode the JWT, extract claims, and forward them as + // configured (via claim_to_headers, forward_payload_header, etc.) but + // will NOT verify the JWT signature against JWKS. + // + // .. warning:: + // + // This mode does not verify JWT authenticity. Use only in scenarios where: + // + // - JWTs come from a trusted source (e.g., internal service mesh) + // - Signature verification is performed elsewhere in the request path + // - You are in a testing period and the token issuer doesn't support JWKS yet + // + // This mode will: + // + // * Decode the JWT header and payload + // * Extract claims and forward them as headers + // * Always return success (Status::Ok) regardless of JWT validity + // * Log when extraction occurs + // + // This mode will NOT: + // + // * Verify the JWT signature + // * Validate the (issuer) claim + // * Validate the (audience) claim + // * Check not-before time (nbf claim) + ExtractOnlyWithoutValidation extract_only_without_validation = 7; } } +message ExtractOnlyWithoutValidation { + // Reserved for future extensions (e.g., claim filtering, logging options) +} + // This message specifies a list of RequiredProvider. // Their results are OR-ed; if any one of them passes, the result is passed message JwtRequirementOrList { diff --git a/src/main/proto/envoy/extensions/filters/http/mcp/v3/mcp.proto b/src/main/proto/envoy/extensions/filters/http/mcp/v3/mcp.proto new file mode 100644 index 0000000..5d2825e --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/http/mcp/v3/mcp.proto @@ -0,0 +1,106 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.mcp.v3; + +import "google/protobuf/wrappers.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.mcp.v3"; +option java_outer_classname = "McpProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/mcp/v3;mcpv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: MCP] +// MCP filter :ref:`configuration overview `. +// [#extension: envoy.filters.http.mcp] + +// This filter will inspect and get attributes from MCP traffic. +message Mcp { + // Traffic handling mode for non-MCP traffic. + enum TrafficMode { + // Proxies the HTTP request and response without MCP spec check. + // This is the default mode. + PASS_THROUGH = 0; + + // Reject requests that are not following MCP spec. + // Valid MCP requests are: + // - POST requests with JSON-RPC 2.0 messages + // - GET requests for SSE streams (with Accept: text/event-stream) + REJECT_NO_MCP = 1; + } + + // Configures how the filter handles non-MCP traffic. + TrafficMode traffic_mode = 1 [(validate.rules).enum = {defined_only: true}]; + + // When set to true, the filter will clear the route cache after setting dynamic metadata. + // This allows the route to be re-selected based on the MCP metadata (e.g., method, params). + // Defaults to false. + bool clear_route_cache = 2; + + // Maximum size of the request body to buffer for JSON-RPC validation. + // If the request body exceeds this size, the request is rejected with ``413 Payload Too Large``. + // This limit applies to both ``REJECT_NO_MCP`` and ``PASS_THROUGH`` modes to prevent unbounded buffering. + // + // It defaults to 8KB (8192 bytes) and the maximum allowed value is 10MB (10485760 bytes). + // + // Setting it to 0 would disable the limit. It is not recommended to do so in production. + google.protobuf.UInt32Value max_request_body_size = 3 [(validate.rules).uint32 = {lte: 10485760}]; + + // Parser configuration, this provide the attribute extraction override. + ParserConfig parser_config = 4; +} + +// Parser configuration with method-specific rules. +// This configuration allows overriding the default attribute extraction behavior for specific MCP methods. +message ParserConfig { + // A single attribute extraction rule. + message AttributeExtractionRule { + // JSON path to extract (e.g., "params.name", "params.uri"). + // The path is a dot-separated string representing the location of the field in the JSON payload. + // For example, "params.name" extracts the "name" field from the "params" object. + string path = 1 [(validate.rules).string = {min_len: 1}]; + } + + // Configuration for a specific MCP method. + message MethodConfig { + // Method name (e.g., "tools/call", "resources/read", "initialize"). + // This matches the "method" field in the JSON-RPC request. + string method = 1 [(validate.rules).string = {min_len: 1}]; + + // The group/category name to assign to this method (e.g., "tool", "lifecycle"). + // This will be emitted to dynamic metadata under the key specified by group_metadata_key. + // If empty, the built-in group classification is used. + string group = 2; + + // Attributes to extract for this method. + // If empty, only default attributes (jsonrpc, method) are extracted. + repeated AttributeExtractionRule extraction_rules = 3; + } + + // List of rules for classification and extraction. + // Rules are evaluated in order; the first match wins. + // If no rule matches, extraction defaults are used and group falls back to built-in classification. + // Built-in groups: lifecycle, tool, resource, prompt, notification, logging, sampling, completion, unknown. + repeated MethodConfig methods = 1; + + // The dynamic metadata key where the group name will be stored. + // If empty, group classification is disabled. + string group_metadata_key = 2; +} + +// Per-route override configuration for MCP filter +message McpOverride { + // Optional per-route traffic mode override + Mcp.TrafficMode traffic_mode = 1 [(validate.rules).enum = {defined_only: true}]; + + // Optional per-route max request body size override. + // When set, this overrides the global max_request_body_size for this route. + // It defaults to 8KB (8192 bytes) and the maximum allowed value is 10MB (10485760 bytes). + google.protobuf.UInt32Value max_request_body_size = 2 [(validate.rules).uint32 = {lte: 10485760}]; +} diff --git a/src/main/proto/envoy/extensions/filters/http/mcp_router/v3/mcp_router.proto b/src/main/proto/envoy/extensions/filters/http/mcp_router/v3/mcp_router.proto new file mode 100644 index 0000000..1d32449 --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/http/mcp_router/v3/mcp_router.proto @@ -0,0 +1,128 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.mcp_router.v3; + +import "envoy/type/metadata/v3/metadata.proto"; + +import "google/protobuf/duration.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.mcp_router.v3"; +option java_outer_classname = "McpRouterProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/mcp_router/v3;mcp_routerv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: MCP Multiplexer/Demultiplexer] +// [#extension: envoy.filters.http.mcp_router] + +// Configuration for the MCP Multiplexer/Demultiplexer. +// +// This extension aggregates capabilities, tools and resources of remote MCP servers and presents Envoy +// as a singe MCP server to the client. This allows a unified policy to be applied to multiple remote +// servers and abstracts multiple MCP servers as a single one. +// +// This filter must be a terminal filter in the filter chain and replaces the HTTP router filter. +// +// Not all route level policies are applicable to this filter. +// Specifically the following policies are ignored: +// * :ref:`route ` +// * :ref:`redirect ` +// * :ref:`direct_response ` +// + +// Extract identity from a request header. +message HeaderSource { + // Header name to extract (e.g., "x-user-identity"). + string name = 1 [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME}]; +} + +// Extract identity from dynamic metadata (e.g., populated by JWT or ext_authz filter). +message DynamicMetadataSource { + // The metadata key to retrieve the value from. + type.metadata.v3.MetadataKey key = 1 [(validate.rules).message = {required: true}]; +} + +// Defines how the identity (user/principal) is extracted from the request. +// Exactly one of ``header`` or ``dynamic_metadata`` must be set. +message IdentityExtractor { + // Extract identity from a request header. + HeaderSource header = 1; + + // Extract identity from dynamic metadata. + DynamicMetadataSource dynamic_metadata = 2; +} + +// Specifies how to handle requests where the identity is missing or mismatched. +message ValidationPolicy { + enum Mode { + // Not specified. Defaults to DISABLED behavior. + MODE_UNSPECIFIED = 0; + + // Bind identity on Initialize if present, but do not validate subsequent requests. + // If extraction fails, the session proceeds anonymously. + DISABLED = 1; + + // Reject the request (403) if the identity cannot be extracted + // or if the session identity does not match the request identity. + ENFORCE = 2; + } + + Mode mode = 1 [(validate.rules).enum = {defined_only: true}]; +} + +// Session identity configuration. +message SessionIdentity { + // Defines how the identity (user/principal) is extracted from the request. + IdentityExtractor identity = 1 [(validate.rules).message = {required: true}]; + + // Specifies how to handle requests where the subject is missing or invalid. + // Defaults to DISABLED. + ValidationPolicy validation = 2; +} + +message McpRouter { + // Specification of the MCP server. + message McpBackend { + // Unique name for this backend. Used for: + // - Tool name prefixing (e.g., "time__get_current_time") + // - Session ID composition + // - Logging and error messages. + // Default will be the cluster name if not specified. + string name = 1; + + // Backend target specification. + McpCluster mcp_cluster = 2; + } + + // Cluster-based backend configuration. + message McpCluster { + // Cluster name to route requests to. + string cluster = 1 [(validate.rules).string = {min_len: 1}]; + + // Path to use for MCP requests. Defaults to "/mcp". + string path = 2; + + // Request timeout. + // If not set, uses cluster's timeout configuration. + google.protobuf.Duration timeout = 3; + + // Indicates that during forwarding, the host header will be swapped with + // this value. + string host_rewrite_literal = 4; + } + + // A list of remote MCP servers. MCP router aggregates capabilities, tools and resources from remote MCP servers + // and presents itself as single MCP server to the client. All remote MCP servers are sent the same capabilities + // that the client presented to Envoy. + repeated McpBackend servers = 1; + + // If set, extracts a request "subject" and binds it into the MCP session. + // If not set, sessions are created without identity binding. + SessionIdentity session_identity = 2; +} diff --git a/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto b/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto index 1cb1fc7..285578f 100644 --- a/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto +++ b/src/main/proto/envoy/extensions/filters/http/oauth2/v3/oauth.proto @@ -37,6 +37,29 @@ message CookieConfig { // The value used for the SameSite cookie attribute. SameSite same_site = 1 [(validate.rules).enum = {defined_only: true}]; + + // The path attribute for the cookie. + // + // This controls the scope of the cookie and is useful for path-based routing scenarios + // where different logical boundaries or applications may operate with different OAuth2 clients. + // The CSRF cookie (nonce cookie) can be configured with a different path than session cookies + // to support flows where the callback URL is on a different path. + // + // If not specified, defaults to ``/``. + string path = 2 [(validate.rules).string = {pattern: "^$|^/[^\\x00-\\x1f\\x7f \",;<>\\\\]*$"}]; + + // If true, the ``Partitioned`` attribute will be set on the cookie. + // + // Modern browsers (Firefox, Chrome with third-party cookie deprecation) warn or block + // "foreign" cookies unless they carry the ``Partitioned`` attribute alongside ``SameSite=None; Secure``. + // When Envoy is used in a gateway/IdP flow that sets OAuth/OIDC cookies for a parent domain + // (e.g., ``Domain=.example.com``) while running on a different host, those cookies are + // considered third-party and will be rejected without ``Partitioned``. + // + // See `CHIPS `_ for more information. + // + // Default is false. + bool partitioned = 3; } // [#next-free-field: 8] @@ -121,12 +144,13 @@ message OAuth2Credentials { // The domain to set the cookie on. If not set, the cookie will default to the host of the request, not including the subdomains. // This is useful when token cookies need to be shared across multiple subdomains. - string cookie_domain = 5; + string cookie_domain = 5 + [(validate.rules).string = {pattern: "^$|^[^\\x00-\\x1f\\x7f \",;<>\\\\]+$"}]; } // OAuth config // -// [#next-free-field: 26] +// [#next-free-field: 27] message OAuth2Config { enum AuthType { // The ``client_id`` and ``client_secret`` will be sent in the URL encoded request body. @@ -254,6 +278,11 @@ message OAuth2Config { // If not specified, defaults to ``600s`` (10 minutes), which should provide sufficient time // for users to complete the OAuth2 authorization flow. google.protobuf.Duration code_verifier_token_expires_in = 25; + + // Disable token encryption. When set to true, both the access token and the ID token will be stored in plain text. + // This option should only be used in secure environments where token encryption is not required. + // Default is false (tokens are encrypted). + bool disable_token_encryption = 26; } // Filter config. diff --git a/src/main/proto/envoy/extensions/filters/http/on_demand/v3/on_demand.proto b/src/main/proto/envoy/extensions/filters/http/on_demand/v3/on_demand.proto index 93c9f76..3e23afe 100644 --- a/src/main/proto/envoy/extensions/filters/http/on_demand/v3/on_demand.proto +++ b/src/main/proto/envoy/extensions/filters/http/on_demand/v3/on_demand.proto @@ -8,7 +8,6 @@ import "google/protobuf/duration.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.http.on_demand.v3"; option java_outer_classname = "OnDemandProto"; @@ -29,7 +28,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; message OnDemandCds { // A configuration source for the service that will be used for // on-demand cluster discovery. - config.core.v3.ConfigSource source = 1 [(validate.rules).message = {required: true}]; + config.core.v3.ConfigSource source = 1; // xdstp:// resource locator for on-demand cluster collection. string resources_locator = 2; diff --git a/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/config.proto b/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/config.proto index b41e0a4..8143a04 100644 --- a/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/config.proto +++ b/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/config.proto @@ -4,7 +4,6 @@ package envoy.extensions.filters.http.proto_api_scrubber.v3; import "envoy/config/core/v3/base.proto"; -import "xds/annotations/v3/status.proto"; import "xds/type/matcher/v3/matcher.proto"; import "udpa/annotations/status.proto"; @@ -14,10 +13,8 @@ option java_outer_classname = "ConfigProto"; option java_multiple_files = true; option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/proto_api_scrubber/v3;proto_api_scrubberv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; -option (xds.annotations.v3.file_status).work_in_progress = true; // [#protodoc-title: Proto API Scrubber] -// [#not-implemented-hide:] Implementation in progress. // [#extension: envoy.filters.http.proto_api_scrubber] // ProtoApiScrubber filter supports filtering of the request and @@ -25,10 +22,7 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // The field restrictions and actions can be defined using unified matcher API. // The filter evaluates the configured restriction for each field // to produce the filtered output using the configured actions. -// This filter currently supports only field level restrictions. -// Restriction support for other proto elements (eg, message -// level restriction, method level restriction, etc.) are planned to be -// implemented in future. The design doc for this filter is available +// The design doc for this filter is available // `here `_ message ProtoApiScrubberConfig { @@ -62,28 +56,54 @@ message Restrictions { // Key - Fully qualified method name e.g., ``endpoints.examples.bookstore.BookStore/GetShelf``. // Value - Method restrictions. map method_restrictions = 1; + + // Specifies the message restrictions. + // Key - Fully qualified message name e.g., ``endpoints.examples.bookstore.Book``. + // Value - Message restrictions. + map message_restrictions = 2; } // Contains the method restrictions which include the field level restrictions // for the request and response fields. message MethodRestrictions { // Restrictions that apply to request fields of the method. - // Key - field mask like path of the field eg, foo.bar.baz + // Key - field mask like path of the field e.g., foo.bar.baz // Value - Restrictions map containing the mapping from restriction name to // the restriction values. map request_field_restrictions = 1; // Restrictions that apply to response fields of the method. - // Key - field mask like path of the field eg, foo.bar.baz + // Key - field mask like path of the field e.g., foo.bar.baz // Value - Restrictions map containing the mapping from restriction name to // the restriction values. map response_field_restrictions = 2; + + // Optional restriction that applies to the entire method. If present, this + // rule takes precedence for the method itself over field-level or + // message-level rules. The 'matcher' within RestrictionConfig will determine + // if the method is denied/scrubbed. If the matcher evaluates to true: + // + // - The request is **denied**, and further processing is stopped. + // - The implementation should generate an immediate error response + // (e.g., an HTTP 403 Forbidden status) and send it to the client. + RestrictionConfig method_restriction = 3; +} + +// Contains message-level restrictions. +message MessageRestrictions { + // The core restriction to apply to this message type. + // The 'matcher' within RestrictionConfig will determine if the message is + // scrubbed/denied/allowed. + RestrictionConfig config = 1; + + // Restrictions that apply to specific fields within this message type. + // Key - field mask (e.g. "social_security_number"). + // Value - The restriction configuration for that field. + map field_restrictions = 2; } // The restriction configuration. message RestrictionConfig { // Matcher tree for matching requests and responses with the configured restrictions. - // NOTE: Currently, only CEL expressions are supported for matching. Support for more - // matchers will be added incrementally overtime. xds.type.matcher.v3.Matcher matcher = 1; } diff --git a/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/matcher_actions.proto b/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/matcher_actions.proto index a6f3c7e..1beb39c 100644 --- a/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/matcher_actions.proto +++ b/src/main/proto/envoy/extensions/filters/http/proto_api_scrubber/v3/matcher_actions.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package envoy.extensions.filters.http.proto_api_scrubber.v3; -import "xds/annotations/v3/status.proto"; - import "udpa/annotations/status.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.http.proto_api_scrubber.v3"; @@ -11,7 +9,6 @@ option java_outer_classname = "MatcherActionsProto"; option java_multiple_files = true; option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/proto_api_scrubber/v3;proto_api_scrubberv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; -option (xds.annotations.v3.file_status).work_in_progress = true; // [#protodoc-title: Proto API Scrubber Matcher Actions] diff --git a/src/main/proto/envoy/extensions/filters/http/proto_message_extraction/v3/config.proto b/src/main/proto/envoy/extensions/filters/http/proto_message_extraction/v3/config.proto index dc51f9d..0706771 100644 --- a/src/main/proto/envoy/extensions/filters/http/proto_message_extraction/v3/config.proto +++ b/src/main/proto/envoy/extensions/filters/http/proto_message_extraction/v3/config.proto @@ -259,6 +259,11 @@ message MethodExtraction { // It should be only annotated on Message type fields so if the field isn't // empty, an empty Struct will be extracted. EXTRACT_REDACT = 2; + + // Extract a repeated top-level field and record its number of entries in + // the extraction result. Can be applied to at most one field in the + // response, and cannot be applied to any fields in the request. + EXTRACT_REPEATED_CARDINALITY = 3; } // The mapping of field path to its ExtractDirective for request messages diff --git a/src/main/proto/envoy/extensions/filters/http/ratelimit/v3/rate_limit.proto b/src/main/proto/envoy/extensions/filters/http/ratelimit/v3/rate_limit.proto index e59217b..5c5a9f3 100644 --- a/src/main/proto/envoy/extensions/filters/http/ratelimit/v3/rate_limit.proto +++ b/src/main/proto/envoy/extensions/filters/http/ratelimit/v3/rate_limit.proto @@ -23,7 +23,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // Rate limit :ref:`configuration overview `. // [#extension: envoy.filters.http.ratelimit] -// [#next-free-field: 17] +// [#next-free-field: 18] message RateLimit { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.rate_limit.v2.RateLimit"; @@ -167,6 +167,25 @@ message RateLimit { // This means that when the rate limit service is unavailable, 50% of requests will be denied // (fail closed) and 50% will be allowed (fail open). config.core.v3.RuntimeFractionalPercent failure_mode_deny_percent = 16; + + // Rate limit configuration that is used to generate a list of descriptor entries based on + // the request context. The generated entries will be sent to the rate limit service. + // If this is set, then + // :ref:`VirtualHost.rate_limits` or + // :ref:`RouteAction.rate_limits` fields + // will be ignored. However, :ref:`RateLimitPerRoute.rate_limits` + // will take precedence over this field. + // + // .. note:: + // Not all configuration fields of + // :ref:`rate limit config ` is supported at here. + // Following fields are not supported: + // + // 1. :ref:`rate limit stage `. + // 2. :ref:`dynamic metadata `. + // 3. :ref:`disable_key `. + // 4. :ref:`override limit `. + repeated config.route.v3.RateLimit rate_limits = 17; } message RateLimitPerRoute { @@ -210,8 +229,9 @@ message RateLimitPerRoute { // the request context. The generated entries will be used to find one or multiple matched rate // limit rule from the ``descriptors``. // If this is set, then - // :ref:`VirtualHost.rate_limits` or - // :ref:`RouteAction.rate_limits` fields + // :ref:`VirtualHost.rate_limits`, + // :ref:`RouteAction.rate_limits` and + // :ref:`RateLimit.rate_limits` fields // will be ignored. // // .. note:: diff --git a/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto b/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto index 6efd47a..a37efe1 100644 --- a/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto +++ b/src/main/proto/envoy/extensions/filters/http/rbac/v3/rbac.proto @@ -4,7 +4,6 @@ package envoy.extensions.filters.http.rbac.v3; import "envoy/config/rbac/v3/rbac.proto"; -import "xds/annotations/v3/status.proto"; import "xds/type/matcher/v3/matcher.proto"; import "udpa/annotations/migrate.proto"; @@ -64,10 +63,8 @@ message RBAC { // If absent, no shadow matcher will be applied. // Match tree for testing RBAC rules through stats and logs without enforcing them. // If absent, no shadow matching occurs. - xds.type.matcher.v3.Matcher shadow_matcher = 5 [ - (udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier", - (xds.annotations.v3.field_status).work_in_progress = true - ]; + xds.type.matcher.v3.Matcher shadow_matcher = 5 + [(udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier"]; // If specified, shadow rules will emit stats with the given prefix. // This is useful for distinguishing metrics when multiple RBAC filters use shadow rules. diff --git a/src/main/proto/envoy/extensions/filters/http/router/v3/router.proto b/src/main/proto/envoy/extensions/filters/http/router/v3/router.proto index d3996a9..7da658b 100644 --- a/src/main/proto/envoy/extensions/filters/http/router/v3/router.proto +++ b/src/main/proto/envoy/extensions/filters/http/router/v3/router.proto @@ -23,7 +23,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // Router :ref:`configuration overview `. // [#extension: envoy.filters.http.router] -// [#next-free-field: 10] +// [#next-free-field: 11] message Router { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.router.v2.Router"; @@ -134,4 +134,10 @@ message Router { // upstream HTTP filters will count as a final response if hedging is configured. // [#extension-category: envoy.filters.http.upstream] repeated network.http_connection_manager.v3.HttpFilter upstream_http_filters = 8; + + // If set to true, Envoy will reject ``CONNECT`` requests that send data before + // receiving a ``200`` response from the upstream. This early data behavior + // is common for latency reduction but can cause issues with some upstreams. + // Defaults to false to allow early data and be compatible with common behavior. + google.protobuf.BoolValue reject_connect_request_early_data = 10; } diff --git a/src/main/proto/envoy/extensions/filters/http/stateful_session/v3/stateful_session.proto b/src/main/proto/envoy/extensions/filters/http/stateful_session/v3/stateful_session.proto index 5cef3fc..b3e5e53 100644 --- a/src/main/proto/envoy/extensions/filters/http/stateful_session/v3/stateful_session.proto +++ b/src/main/proto/envoy/extensions/filters/http/stateful_session/v3/stateful_session.proto @@ -29,6 +29,15 @@ message StatefulSession { // which allows Envoy to fall back to its load balancing mechanism. In this case, if the requested destination is not // found, the request will be routed according to the load balancing algorithm. bool strict = 2; + + // Optional stat prefix. If specified, the filter will emit statistics in the + // ``http..stateful_session..`` namespace. If not specified, no statistics will be emitted. + // + // .. note:: + // + // Per-route configuration overrides do not support statistics and will not emit stats even if this field is set + // in the per-route config. + string stat_prefix = 3; } message StatefulSessionPerRoute { diff --git a/src/main/proto/envoy/extensions/filters/http/tap/v3/tap.proto b/src/main/proto/envoy/extensions/filters/http/tap/v3/tap.proto index 0ed35de..0c12c3f 100644 --- a/src/main/proto/envoy/extensions/filters/http/tap/v3/tap.proto +++ b/src/main/proto/envoy/extensions/filters/http/tap/v3/tap.proto @@ -34,4 +34,7 @@ message Tap { // Indicates whether report downstream connection info bool record_downstream_connection = 3; + + // If enabled, upstream connection information will be reported. + bool record_upstream_connection = 4; } diff --git a/src/main/proto/envoy/extensions/filters/http/thrift_to_metadata/v3/thrift_to_metadata.proto b/src/main/proto/envoy/extensions/filters/http/thrift_to_metadata/v3/thrift_to_metadata.proto index 59dad1b..204f02f 100644 --- a/src/main/proto/envoy/extensions/filters/http/thrift_to_metadata/v3/thrift_to_metadata.proto +++ b/src/main/proto/envoy/extensions/filters/http/thrift_to_metadata/v3/thrift_to_metadata.proto @@ -69,8 +69,6 @@ message KeyValuePair { } message FieldSelector { - option (xds.annotations.v3.message_status).work_in_progress = true; - // field name to log string name = 1 [(validate.rules).string = {min_len: 1}]; @@ -83,7 +81,9 @@ message FieldSelector { // [#next-free-field: 6] message Rule { - // The field to match on. If set, takes precedence over field_selector. + // The field to match on. + // :ref:`field_selector` + // takes precedence if both are set. Field field = 1; // Specifies that a match will be performed on the value of a field in the thrift body. @@ -123,11 +123,11 @@ message Rule { // bool bar(1: i32 id, 2: Info info); // } // - FieldSelector field_selector = 2 [(xds.annotations.v3.field_status).work_in_progress = true]; + FieldSelector field_selector = 2; // If specified, :ref:`field_selector` // will be used to extract the field value *only* on the thrift message with method name. - string method_name = 3 [(xds.annotations.v3.field_status).work_in_progress = true]; + string method_name = 3; // The key-value pair to set in the *filter metadata* if the field is present // in *thrift metadata*. diff --git a/src/main/proto/envoy/extensions/filters/http/transform/v3/transform.proto b/src/main/proto/envoy/extensions/filters/http/transform/v3/transform.proto new file mode 100644 index 0000000..f971a31 --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/http/transform/v3/transform.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.transform.v3; + +import "envoy/config/common/mutation_rules/v3/mutation_rules.proto"; +import "envoy/config/core/v3/substitution_format_string.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.transform.v3"; +option java_outer_classname = "TransformProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/transform/v3;transformv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Transform filter configuration] +// Transform filter :ref:`configuration overview ` to perform +// HTTP header and body transformations. +// [#extension: envoy.filters.http.transform] + +// Configuration for the transform filter. The filter may buffer the request/response until the +// entire body is received, and then mutate the headers and body according to the contents +// of the request/response. The request and response transformations are independent and could +// be configured separately. +// Only JSON body transformation is supported for now. +message TransformConfig { + // Configuration for transforming request. + // + // .. note:: + // + // If set then the entire request headers and body will always be buffered on a JSON request + // even if only headers are transformed. + Transformation request_transformation = 1; + + // Configuration for transforming response. + // + // .. note:: + // + // If set then the entire response headers and body will always be buffered on a JSON response + // even if only headers are transformed. + Transformation response_transformation = 2; + + // If true and the request headers are transformed, Envoy will re-evaluate the target + // cluster in the same route. Please ensure the cluster specifier in the route supports + // dynamic evaluation or this flag will have no effect, e.g. + // :ref:`matcher cluster specifier + // `. + // + // Only one of ``clear_cluster_cache`` and ``clear_route_cache`` can be true. + bool clear_cluster_cache = 3; + + // If true and the request headers are transformed, Envoy will clear the route cache for + // the current request and force re-evaluation of the route. This has performance penalty and + // should only be used when the route match criteria depends on the transformed headers. + // + // Only one of ``clear_cluster_cache`` and ``clear_route_cache`` can be true. + bool clear_route_cache = 4; +} + +message Transformation { + // The header mutations to perform. + // The :ref:`substitution format specifier ` could be applied here. + // In addition to the commonly used format specifiers, this filter introduces additional format specifiers: + // + // * ``%REQUEST_BODY(KEY*)%``: the request body. And ``Key`` KEY is an optional + // lookup key in the namespace with the option of specifying nested keys separated by ':'. + // * ``%RESPONSE_BODY(KEY*)%``: the response body. And ``Key`` KEY is an optional + // lookup key in the namespace with the option of specifying nested keys separated by ':'. + repeated config.common.mutation_rules.v3.HeaderMutation headers_mutations = 1; + + // The body transformation configuration. If not set, no body transformation will be performed. + BodyTransformation body_transformation = 2; +} + +message BodyTransformation { + enum TransformAction { + // Merge the transformed body with the original body. This is the default action. + MERGE = 0; + + // Replace the original body with the transformed body. + REPLACE = 1; + } + + // Body transformation configuration. The substitution format string is used as the template + // to generate the transformed new body content. + // The :ref:`substitution format specifier ` could be applied here. + // And except the commonly used format specifiers, the additional format specifiers + // ``%REQUEST_BODY(KEY*)%`` and ``%RESPONSE_BODY(KEY*)%`` could also be used here. + config.core.v3.SubstitutionFormatString body_format = 1 + [(validate.rules).message = {required: true}]; + + // The action to perform for new body content and original body content. + // For example, if ``MERGE`` is used, then the new body content generated from the ``body_format`` + // will be merged into the original body content. + // + // Default is ``MERGE``. + TransformAction action = 2; +} diff --git a/src/main/proto/envoy/extensions/filters/listener/dynamic_modules/v3/dynamic_modules.proto b/src/main/proto/envoy/extensions/filters/listener/dynamic_modules/v3/dynamic_modules.proto new file mode 100644 index 0000000..f2a4eca --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/listener/dynamic_modules/v3/dynamic_modules.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package envoy.extensions.filters.listener.dynamic_modules.v3; + +import "envoy/extensions/dynamic_modules/v3/dynamic_modules.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.listener.dynamic_modules.v3"; +option java_outer_classname = "DynamicModulesProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/dynamic_modules/v3;dynamic_modulesv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Listener filter for dynamic modules] +// [#extension: envoy.filters.listener.dynamic_modules] + +// Configuration of the listener filter for dynamic modules. This filter allows loading shared object +// files that can be loaded via dlopen by the listener filter. +// +// A module can be loaded by multiple listener filters, hence the program can be structured in a way +// that the module is loaded only once and shared across multiple filters providing multiple +// functionalities. +// +// Unlike network filters which operate on established TCP connections, listener filters +// work with raw accepted sockets BEFORE a Connection object is created. The filter can: +// +// * Inspect initial bytes to detect protocols (TLS, HTTP, PostgreSQL, etc.). +// * Set socket properties (SNI, ALPN, transport protocol, fingerprints). +// * Modify connection addresses (original destination restoration). +// * Set dynamic metadata and filter state for downstream filters. +// * Rate limit incoming connections. +// +message DynamicModuleListenerFilter { + // Specifies the shared-object level configuration. + envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1; + + // The name for this filter configuration. This can be used to distinguish between different + // filter implementations inside a dynamic module. For example, a module can have completely + // different filter implementations (TLS inspector, rate limiter, proxy protocol parser). + // When Envoy receives this configuration, it passes the ``filter_name`` to the dynamic module's + // listener filter config init function together with the ``filter_config``. That way a module + // can decide which in-module filter implementation to use based on the name at load time. + string filter_name = 2; + + // The configuration for the filter chosen by ``filter_name``. This is passed to the module's + // listener filter initialization function. Together with the ``filter_name``, the module can + // decide which in-module filter implementation to use and fine-tune the behavior of the filter. + // + // For example, if a module has two filter implementations, one for TLS inspection and one for + // rate limiting, ``filter_name`` is used to choose either TLS or rate limiting. The ``filter_config`` + // can be used to configure the TLS inspection options or the rate limiting parameters. + // + // ``google.protobuf.Struct`` is serialized as JSON before passing it to the module. + // ``google.protobuf.BytesValue`` and ``google.protobuf.StringValue`` are passed directly + // without the wrapper. + // + // .. code-block:: yaml + // + // # Passing a string value + // filter_config: + // "@type": "type.googleapis.com/google.protobuf.StringValue" + // value: hello + // + // # Passing raw bytes + // filter_config: + // "@type": "type.googleapis.com/google.protobuf.BytesValue" + // value: aGVsbG8= # echo -n "hello" | base64 + // + google.protobuf.Any filter_config = 3; +} diff --git a/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto b/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto index cc96c48..b90d08d 100644 --- a/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto +++ b/src/main/proto/envoy/extensions/filters/listener/proxy_protocol/v3/proxy_protocol.proto @@ -18,11 +18,20 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // PROXY protocol listener filter. // [#extension: envoy.filters.listener.proxy_protocol] -// [#next-free-field: 6] +// [#next-free-field: 7] message ProxyProtocol { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.listener.proxy_protocol.v2.ProxyProtocol"; + // Controls where TLV values are stored when rules match. + enum TlvLocation { + // Store TLV values in dynamic metadata. + DYNAMIC_METADATA = 0; + + // Store TLV values in filter state as a single map-like object. + FILTER_STATE = 1; + } + message KeyValuePair { // The namespace — if this is empty, the filter's namespace will be used. string metadata_namespace = 1; @@ -92,4 +101,7 @@ message ProxyProtocol { // See the :ref:`filter's statistics documentation ` for // more information. string stat_prefix = 5; + + // Controls where TLV values are stored when rules match. Defaults to DYNAMIC_METADATA. + TlvLocation tlv_location = 6; } diff --git a/src/main/proto/envoy/extensions/filters/listener/tls_inspector/v3/tls_inspector.proto b/src/main/proto/envoy/extensions/filters/listener/tls_inspector/v3/tls_inspector.proto index c421e57..365af52 100644 --- a/src/main/proto/envoy/extensions/filters/listener/tls_inspector/v3/tls_inspector.proto +++ b/src/main/proto/envoy/extensions/filters/listener/tls_inspector/v3/tls_inspector.proto @@ -18,6 +18,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // Allows detecting whether the transport appears to be TLS or plaintext. // [#extension: envoy.filters.listener.tls_inspector] +// [#next-free-field: 6] message TlsInspector { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.listener.tls_inspector.v2.TlsInspector"; @@ -32,8 +33,8 @@ message TlsInspector { // The size in bytes of the initial buffer requested by the tls_inspector. // If the filter needs to read additional bytes from the socket, the - // filter will double the buffer up to it's default maximum of 64KiB. - // If this size is not defined, defaults to maximum 64KiB that the + // filter will double the buffer up to it's default maximum of 16KiB. + // If this size is not defined, defaults to maximum 16KiB that the // tls inspector will consume. google.protobuf.UInt32Value initial_read_buffer_size = 2 [(validate.rules).uint32 = {lt: 65537 gt: 255}]; @@ -48,4 +49,11 @@ message TlsInspector { // counter to be incremented if the ClientHello message is over implementation defined limit // (currently 16Kb). bool close_connection_on_client_hello_parsing_errors = 4; + + // The maximum size in bytes of the ClientHello that the tls_inspector will + // process. If the ClientHello is larger than this size, the tls_inspector + // will stop processing and indicate failure. If not defined, defaults to + // 16KiB. + google.protobuf.UInt32Value max_client_hello_size = 5 + [(validate.rules).uint32 = {lte: 16384 gt: 255}]; } diff --git a/src/main/proto/envoy/extensions/filters/network/dynamic_modules/v3/dynamic_modules.proto b/src/main/proto/envoy/extensions/filters/network/dynamic_modules/v3/dynamic_modules.proto new file mode 100644 index 0000000..808acc6 --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/network/dynamic_modules/v3/dynamic_modules.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; + +package envoy.extensions.filters.network.dynamic_modules.v3; + +import "envoy/extensions/dynamic_modules/v3/dynamic_modules.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.network.dynamic_modules.v3"; +option java_outer_classname = "DynamicModulesProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/dynamic_modules/v3;dynamic_modulesv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Dynamic Modules Network Filter] +// [#extension: envoy.filters.network.dynamic_modules] + +// Configuration for the Dynamic Modules network filter. This filter allows loading shared object +// files that can be loaded via ``dlopen`` to extend the network filter chain. +// +// A module can be loaded by multiple network filters; the module is loaded only once and shared +// across multiple filters. +// +// Unlike HTTP filters which operate on structured headers, body, and trailers, network filters work +// with raw TCP byte streams. The filter can: +// +// * Inspect, modify, or inject data into the downstream connection. +// * Access connection-level information such as addresses and TLS status. +// * Control connection lifecycle (e.g., close the connection). +message DynamicModuleNetworkFilter { + // Specifies the shared-object level configuration. + envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1; + + // The name for this filter configuration. + // + // This can be used to distinguish between different filter implementations inside a dynamic + // module. For example, a module can have completely different filter implementations. When Envoy + // receives this configuration, it passes the ``filter_name`` to the dynamic module's network + // filter config init function together with the ``filter_config``. That way a module can decide + // which in-module filter implementation to use based on the name at load time. + string filter_name = 2; + + // The configuration for the filter chosen by ``filter_name``. + // + // This is passed to the module's network filter initialization function. Together with the + // ``filter_name``, the module can decide which in-module filter implementation to use and + // fine-tune the behavior of the filter. + // + // For example, if a module has two filter implementations, one for echo and one for rate + // limiting, ``filter_name`` is used to choose either echo or rate limiting. The + // ``filter_config`` can be used to configure the echo behavior or the rate limiting parameters. + // + // ``google.protobuf.Struct`` is serialized as JSON before passing it to the module. + // ``google.protobuf.BytesValue`` and ``google.protobuf.StringValue`` are passed directly + // without the wrapper. + // + // .. code-block:: yaml + // + // # Passing a string value + // filter_config: + // "@type": "type.googleapis.com/google.protobuf.StringValue" + // value: hello + // + // # Passing raw bytes + // filter_config: + // "@type": "type.googleapis.com/google.protobuf.BytesValue" + // value: aGVsbG8= # echo -n "hello" | base64 + // + google.protobuf.Any filter_config = 3; + + // If ``true``, the dynamic module is a terminal filter to use without an upstream connection. + // + // The dynamic module is responsible for creating and sending the response to downstream. + // + // Defaults to ``false``. + bool terminal_filter = 4; +} diff --git a/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto b/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto index afd0197..64668a7 100644 --- a/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto +++ b/src/main/proto/envoy/extensions/filters/network/ext_authz/v3/ext_authz.proto @@ -25,7 +25,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // gRPC Authorization API defined by // :ref:`CheckRequest `. // A failed check will cause this filter to close the TCP connection. -// [#next-free-field: 9] +// [#next-free-field: 12] message ExtAuthz { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.ext_authz.v2.ExtAuthz"; @@ -68,4 +68,36 @@ message ExtAuthz { // When this field is true, Envoy will include the SNI name used for TLSClientHello, if available, in the // :ref:`tls_session`. bool include_tls_session = 8; + + // When set to ``true``, the filter will send a TLS ``access_denied(49)`` alert before closing + // the connection when authorization is denied. This provides better visibility to TLS clients + // about the reason for connection closure. This alert is only sent for TLS connections. The + // non-TLS connections will be closed without sending an alert. + // + // Defaults to ``false``. + bool send_tls_alert_on_denial = 9; + + // Specifies a list of metadata namespaces whose values, if present, will be passed to the + // ext_authz service. The :ref:`filter_metadata ` + // is passed as an opaque ``protobuf::Struct``. + // + // For example, if the ``proxy_protocol`` listener filter is used and populates TLV metadata, + // then the following will pass that metadata to the authorization server for making decisions + // based on proxy protocol information. + // + // .. code-block:: yaml + // + // metadata_context_namespaces: + // - envoy.filters.listener.proxy_protocol + // + repeated string metadata_context_namespaces = 10; + + // Specifies a list of metadata namespaces whose values, if present, will be passed to the + // ext_authz service. :ref:`typed_filter_metadata ` + // is passed as a ``protobuf::Any``. + // + // This works similarly to ``metadata_context_namespaces`` but allows Envoy and the ext_authz server to share + // the protobuf message definition in order to perform safe parsing. + // + repeated string typed_metadata_context_namespaces = 11; } diff --git a/src/main/proto/envoy/extensions/filters/network/ext_proc/v3/ext_proc.proto b/src/main/proto/envoy/extensions/filters/network/ext_proc/v3/ext_proc.proto index 744c6f7..f37feaa 100644 --- a/src/main/proto/envoy/extensions/filters/network/ext_proc/v3/ext_proc.proto +++ b/src/main/proto/envoy/extensions/filters/network/ext_proc/v3/ext_proc.proto @@ -45,11 +45,9 @@ message NetworkExternalProcessor { // prematurely with an error, the filter will fail, leading to the close of connection. // With this parameter set to true, however, then if the gRPC stream is prematurely closed // or could not be opened, processing continues without error. - // [#not-implemented-hide:] bool failure_mode_allow = 2; // Options for controlling processing behavior. - // [#not-implemented-hide:] ProcessingMode processing_mode = 3; // Specifies the timeout for each individual message sent on the stream and @@ -57,7 +55,6 @@ message NetworkExternalProcessor { // the proxy sends a message on the stream that requires a response, it will // reset this timer, and will stop processing and return an error (subject // to the processing mode) if the timer expires. Default is 200 ms. - // [#not-implemented-hide:] google.protobuf.Duration message_timeout = 4 [(validate.rules).duration = { lte {seconds: 3600} gte {} diff --git a/src/main/proto/envoy/extensions/filters/network/geoip/v3/geoip.proto b/src/main/proto/envoy/extensions/filters/network/geoip/v3/geoip.proto new file mode 100644 index 0000000..c5138f0 --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/network/geoip/v3/geoip.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; + +package envoy.extensions.filters.network.geoip.v3; + +import "envoy/config/core/v3/extension.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.network.geoip.v3"; +option java_outer_classname = "GeoipProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/geoip/v3;geoipv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: Geoip] +// Geoip :ref:`configuration overview `. +// [#extension: envoy.filters.network.geoip] + +// The network geolocation filter performs IP geolocation lookups on incoming connections +// and stores the results in the connection's filter state under the well-known key +// ``envoy.geoip``. The stored data is a ``GeoipInfo`` object that supports +// serialization for access logging and field-level access. +// +// See :ref:`well known filter state ` for details on accessing +// the geolocation data. +message Geoip { + // The prefix to use when emitting statistics. This is useful when there are multiple + // listeners configured with geoip filters, allowing stats to be grouped per listener. + // For example, with ``stat_prefix: "listener_1."``, stats would be emitted as + // ``listener_1.geoip.total``. + string stat_prefix = 1; + + // Geoip driver specific configuration which depends on the driver being instantiated. + // [#extension-category: envoy.geoip_providers] + config.core.v3.TypedExtensionConfig provider = 2 [(validate.rules).message = {required: true}]; + + // Configuration for dynamically extracting the client IP address used for geolocation lookups. + // + // This field accepts the same :ref:`format specifiers ` as used for + // :ref:`HTTP access logging ` to extract the client IP. + // The formatted result must be a valid IPv4 or IPv6 address string. For example: + // + // * ``%FILTER_STATE(my.custom.client.ip:PLAIN)%`` - Read from filter state populated by a preceding filter. + // * ``%DYNAMIC_METADATA(namespace:key)%`` - Read from dynamic metadata. + // * ``%REQ(X-Forwarded-For)%`` - Extract from request header (if applicable in context). + // + // If not specified, defaults to the downstream connection's remote address. + // If specified but the result is empty, ``-``, or not a valid IP address, the filter + // falls back to the downstream connection's remote address. + // + // Example reading from filter state: + // + // .. code-block:: yaml + // + // client_ip: "%FILTER_STATE(my.custom.client.ip:PLAIN)%" + // + string client_ip = 3; +} diff --git a/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index e0282af..9d8cf8b 100644 --- a/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/src/main/proto/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -20,6 +20,8 @@ import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; +import "xds/type/matcher/v3/matcher.proto"; + import "envoy/annotations/deprecation.proto"; import "udpa/annotations/migrate.proto"; import "udpa/annotations/security.proto"; @@ -37,7 +39,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 59] +// [#next-free-field: 61] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; @@ -139,11 +141,13 @@ message HttpConnectionManager { UNESCAPE_AND_FORWARD = 4; } - // [#next-free-field: 11] + // [#next-free-field: 13] message Tracing { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager.Tracing"; + // This OperationName makes no sense and is unnecessary in the current tracing API. + // [#not-implemented-hide:] enum OperationName { // The HTTP listener is used for ingress/incoming requests. INGRESS = 0; @@ -217,6 +221,28 @@ message HttpConnectionManager { // // The default value is false for now for backward compatibility. google.protobuf.BoolValue spawn_upstream_span = 10; + + // The operation name of the span which will be used for tracing. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + // + // This field will take precedence over and make following settings ineffective: + // + // * :ref:`route decorator ` and + // * :ref:`x-envoy-decorator-operation ` + // header will be ignored. + string operation = 11; + + // The operation name of the upstream span which will be used for tracing. + // This only takes effect when ``spawn_upstream_span`` is set to true and the upstream + // span is created. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + string upstream_operation = 12; } message InternalAddressConfig { @@ -263,6 +289,15 @@ message HttpConnectionManager { bool uri = 5; } + // The configuration for forwarding client cert details. + message ForwardClientCertConfig { + // How to handle the XFCC header. + ForwardClientCertDetails forward_client_cert_details = 1; + + // How to set the current client cert details. + SetCurrentClientCertDetails set_current_client_cert_details = 2; + } + // The configuration for HTTP upgrades. // For each upgrade type desired, an UpgradeConfig must be added. // @@ -527,16 +562,6 @@ message HttpConnectionManager { // is terminated with a 408 Request Timeout error code if no upstream response // header has been received, otherwise a stream reset occurs. // - // This timeout also specifies the amount of time that Envoy will wait for the peer to open enough - // window to write any remaining stream data once the entirety of stream data (local end stream is - // true) has been buffered pending available window. In other words, this timeout defends against - // a peer that does not release enough window to completely write the stream, even though all - // data has been proxied within available flow control windows. If the timeout is hit in this - // case, the :ref:`tx_flush_timeout ` counter will be - // incremented. Note that :ref:`max_stream_duration - // ` does not apply to - // this corner case. - // // If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" // is configured, this timeout is scaled according to the value for // :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. @@ -549,9 +574,29 @@ message HttpConnectionManager { // // A value of 0 will completely disable the connection manager stream idle // timeout, although per-route idle timeout overrides will continue to apply. + // + // This timeout is also used as the default value for :ref:`stream_flush_timeout + // `. google.protobuf.Duration stream_idle_timeout = 24 [(udpa.annotations.security).configure_for_untrusted_downstream = true]; + // The stream flush timeout for connections managed by the connection manager. + // + // If not specified, the value of stream_idle_timeout is used. This is for backwards compatibility + // since this was the original behavior. In essence this timeout is an override for the + // stream_idle_timeout that applies specifically to the end of stream flush case. + // + // This timeout specifies the amount of time that Envoy will wait for the peer to open enough + // window to write any remaining stream data once the entirety of stream data (local end stream is + // true) has been buffered pending available window. In other words, this timeout defends against + // a peer that does not release enough window to completely write the stream, even though all + // data has been proxied within available flow control windows. If the timeout is hit in this + // case, the :ref:`tx_flush_timeout ` counter will be + // incremented. Note that :ref:`max_stream_duration + // ` does not apply to + // this corner case. + google.protobuf.Duration stream_flush_timeout = 59; + // The amount of time that Envoy will wait for the entire request to be received. // The timer is activated when the request is initiated, and is disarmed when the last byte of the // request is sent upstream (i.e. all decoding filters have processed the request), OR when the @@ -774,6 +819,53 @@ message HttpConnectionManager { // value. SetCurrentClientCertDetails set_current_client_cert_details = 17; + // The matcher for forwarding client cert details. This allows per-request configuration + // of forward client cert behavior based on request properties. If a matcher is configured + // and matches a request, the matched action's forward client cert config will be used. + // If the matcher is not configured or doesn't match, the static + // :ref:`forward_client_cert_details + // ` + // and + // :ref:`set_current_client_cert_details + // ` + // config will be used as fallback. + // + // Example: If the x-forwarded-client-cert header contains "trusted-client", use APPEND_FORWARD, + // otherwise use SANITIZE_SET: + // + // .. code-block:: yaml + // + // forward_client_cert_matcher: + // matcher_list: + // matchers: + // - predicate: + // single_predicate: + // input: + // name: envoy.matching.inputs.request_headers + // typed_config: + // "@type": type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput + // header_name: "x-forwarded-client-cert" + // value_match: + // string_match: + // contains: "trusted-client" + // on_match: + // action: + // name: forward_client_cert + // typed_config: + // "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.ForwardClientCertConfig + // forward_client_cert_details: APPEND_FORWARD + // set_current_client_cert_details: + // uri: true + // on_no_match: + // action: + // name: forward_client_cert + // typed_config: + // "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.ForwardClientCertConfig + // forward_client_cert_details: SANITIZE_SET + // set_current_client_cert_details: + // uri: true + xds.type.matcher.v3.Matcher forward_client_cert_matcher = 60; + // If proxy_100_continue is true, Envoy will proxy incoming "Expect: // 100-continue" headers upstream, and forward "100 Continue" responses // downstream. If this is false or not set, Envoy will instead strip the @@ -1036,7 +1128,7 @@ message Rds { "envoy.config.filter.network.http_connection_manager.v2.Rds"; // Configuration source specifier for RDS. - config.core.v3.ConfigSource config_source = 1 [(validate.rules).message = {required: true}]; + config.core.v3.ConfigSource config_source = 1; // The name of the route configuration. This name will be passed to the RDS // API. This allows an Envoy configuration with multiple HTTP listeners (and diff --git a/src/main/proto/envoy/extensions/filters/network/rbac/v3/rbac.proto b/src/main/proto/envoy/extensions/filters/network/rbac/v3/rbac.proto index 9032a65..a65bbab 100644 --- a/src/main/proto/envoy/extensions/filters/network/rbac/v3/rbac.proto +++ b/src/main/proto/envoy/extensions/filters/network/rbac/v3/rbac.proto @@ -6,7 +6,6 @@ import "envoy/config/rbac/v3/rbac.proto"; import "google/protobuf/duration.proto"; -import "xds/annotations/v3/status.proto"; import "xds/type/matcher/v3/matcher.proto"; import "udpa/annotations/migrate.proto"; @@ -55,10 +54,8 @@ message RBAC { // not match any matcher will be denied. // If absent, no enforcing RBAC matcher will be applied. // If present and empty, deny all connections. - xds.type.matcher.v3.Matcher matcher = 6 [ - (udpa.annotations.field_migrate).oneof_promotion = "rules_specifier", - (xds.annotations.v3.field_status).work_in_progress = true - ]; + xds.type.matcher.v3.Matcher matcher = 6 + [(udpa.annotations.field_migrate).oneof_promotion = "rules_specifier"]; // Shadow rules are not enforced by the filter but will emit stats and logs // and can be used for rule testing. @@ -70,10 +67,8 @@ message RBAC { // The match tree to use for emitting stats and logs which can be used for rule testing for // incoming connections. // If absent, no shadow matcher will be applied. - xds.type.matcher.v3.Matcher shadow_matcher = 7 [ - (udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier", - (xds.annotations.v3.field_status).work_in_progress = true - ]; + xds.type.matcher.v3.Matcher shadow_matcher = 7 + [(udpa.annotations.field_migrate).oneof_promotion = "shadow_rules_specifier"]; // If specified, shadow rules will emit stats with the given prefix. // This is useful to distinguish the stat when there are more than 1 RBAC filter configured with diff --git a/src/main/proto/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto b/src/main/proto/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto index 40cc285..f24ee63 100644 --- a/src/main/proto/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto +++ b/src/main/proto/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package envoy.extensions.filters.network.redis_proxy.v3; +import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/grpc_service.proto"; import "envoy/extensions/common/aws/v3/credential_provider.proto"; @@ -380,6 +381,19 @@ message RedisProtocolOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.redis_proxy.v2.RedisProtocolOptions"; + message Credential { + // The address to which this username and password applies. + config.core.v3.Address address = 1; + + // Upstream server password as defined by the ``requirepass`` directive + // ``_ in the server's configuration file. + config.core.v3.DataSource auth_password = 2 [(udpa.annotations.sensitive) = true]; + + // Upstream server username as defined by the ``user`` directive + // ``_ in the server's configuration file. + config.core.v3.DataSource auth_username = 3 [(udpa.annotations.sensitive) = true]; + } + // Upstream server password as defined by the ``requirepass`` directive // ``_ in the server's configuration file. // If ``aws_iam`` is set, this field is ignored. @@ -393,6 +407,13 @@ message RedisProtocolOptions { // The cluster level configuration for AWS IAM authentication AwsIam aws_iam = 3; + + // If specified, these credentials are used when connecting to upstream endpoints. Which + // credential is used is determined by matching the resolved ``address`` field here with each + // endpoint's resolved ``address`` field. The first entry for a given ``address`` here takes precedence. + // If no entry in ``credentials`` matches, then the ``auth_password`` and ``auth_username`` fields + // are used as defaults. + repeated Credential credentials = 4; } // [#next-free-field: 6] diff --git a/src/main/proto/envoy/extensions/filters/network/reverse_tunnel/v3/reverse_tunnel.proto b/src/main/proto/envoy/extensions/filters/network/reverse_tunnel/v3/reverse_tunnel.proto new file mode 100644 index 0000000..98e9b72 --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/network/reverse_tunnel/v3/reverse_tunnel.proto @@ -0,0 +1,122 @@ +syntax = "proto3"; + +package envoy.extensions.filters.network.reverse_tunnel.v3; + +import "envoy/config/core/v3/base.proto"; + +import "google/protobuf/duration.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.network.reverse_tunnel.v3"; +option java_outer_classname = "ReverseTunnelProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/reverse_tunnel/v3;reverse_tunnelv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Reverse Tunnel Network Filter] +// Reverse Tunnel Network Filter :ref:`configuration overview `. +// [#extension: envoy.filters.network.reverse_tunnel] + +// Validation configuration for reverse tunnel identifiers. +// Validates the node ID and cluster ID extracted from reverse tunnel handshake headers +// against expected values specified using format strings. +message Validation { + // Format string to extract the expected node identifier for validation. + // The formatted value is compared against the ``x-envoy-reverse-tunnel-node-id`` header + // from the incoming handshake request. If they do not match, the connection is rejected + // with HTTP ``403 Forbidden``. + // + // Supports Envoy's :ref:`command operators `: + // + // * ``%DYNAMIC_METADATA(namespace:key)%``: Extract expected value from dynamic metadata. + // * ``%FILTER_STATE(key)%``: Extract expected value from filter state. + // * ``%DOWNSTREAM_REMOTE_ADDRESS%``: Use downstream connection IP address. + // * Plain strings: Use a static expected value. + // + // If empty, node ID validation is skipped. + // + // Example using dynamic metadata allowlist: + // + // .. code-block:: yaml + // + // node_id_format: "%DYNAMIC_METADATA(envoy.reverse_tunnel.allowlist:expected_node_id)%" + // + string node_id_format = 1 [(validate.rules).string = {max_len: 1024}]; + + // Format string to extract the expected cluster identifier for validation. + // The formatted value is compared against the ``x-envoy-reverse-tunnel-cluster-id`` header + // from the incoming handshake request. If they do not match, the connection is rejected + // with HTTP ``403 Forbidden``. + // + // Supports the same :ref:`command operators ` as + // ``node_id_format``. + // + // If empty, cluster ID validation is skipped. + // + // Example using filter state: + // + // .. code-block:: yaml + // + // cluster_id_format: "%FILTER_STATE(expected_cluster_id)%" + // + string cluster_id_format = 2 [(validate.rules).string = {max_len: 1024}]; + + // Whether to emit validation results as dynamic metadata. + // When enabled, the filter emits metadata under the namespace specified by + // ``dynamic_metadata_namespace`` containing: + // + // * ``node_id``: The actual node ID from the handshake request. + // * ``cluster_id``: The actual cluster ID from the handshake request. + // * ``validation_result``: Either ``allowed`` or ``denied``. + // + // This metadata can be used by subsequent filters or for access logging. + // Defaults to ``false``. + bool emit_dynamic_metadata = 3; + + // Namespace for emitted dynamic metadata when ``emit_dynamic_metadata`` is ``true``. + // If not specified, defaults to ``envoy.filters.network.reverse_tunnel``. + string dynamic_metadata_namespace = 4 [(validate.rules).string = {max_len: 255}]; +} + +// Configuration for the reverse tunnel network filter. +// This filter handles reverse tunnel connection acceptance and rejection by processing +// HTTP requests where required identification values are provided via HTTP headers. +// [#next-free-field: 7] +message ReverseTunnel { + // Ping interval for health checks on established reverse tunnel connections. + // If not specified, defaults to ``2 seconds``. + google.protobuf.Duration ping_interval = 1 [(validate.rules).duration = { + lte {seconds: 300} + gte {nanos: 1000000} + }]; + + // Whether to automatically close connections after processing reverse tunnel requests. + // + // * When set to ``true``, connections are closed after acceptance or rejection. + // * When set to ``false``, connections remain open for potential reuse. + // + // Defaults to ``false``. + bool auto_close_connections = 2; + + // HTTP path to match for reverse tunnel requests. + // If not specified, defaults to ``/reverse_connections/request``. + string request_path = 3 [(validate.rules).string = {min_len: 1 max_len: 255 ignore_empty: true}]; + + // HTTP method to match for reverse tunnel requests. + // If not specified (``METHOD_UNSPECIFIED``), this defaults to ``GET``. + config.core.v3.RequestMethod request_method = 4 [(validate.rules).enum = {defined_only: true}]; + + // Optional validation configuration for node and cluster identifiers. + // If specified, the filter validates the ``x-envoy-reverse-tunnel-node-id`` and + // ``x-envoy-reverse-tunnel-cluster-id`` headers against expected values extracted + // using format strings. Requests that fail validation are rejected with HTTP ``403 Forbidden``. + Validation validation = 5; + + // Required cluster name for validating reverse tunnel connection initiations. + // When set, the filter validates that the upstream cluster of the initiator envoy matches this name + // via ``x-envoy-reverse-tunnel-upstream-cluster-name`` header. Connections with mismatched or missing + // cluster names are rejected with HTTP ``400 Bad Request``. When empty, no cluster name validation is performed. + string required_cluster_name = 6 [(validate.rules).string = {max_len: 255 ignore_empty: true}]; +} diff --git a/src/main/proto/envoy/extensions/filters/network/set_filter_state/v3/set_filter_state.proto b/src/main/proto/envoy/extensions/filters/network/set_filter_state/v3/set_filter_state.proto index 084f516..f4be26f 100644 --- a/src/main/proto/envoy/extensions/filters/network/set_filter_state/v3/set_filter_state.proto +++ b/src/main/proto/envoy/extensions/filters/network/set_filter_state/v3/set_filter_state.proto @@ -24,4 +24,11 @@ message Config { // A sequence of the filter state values to apply in the specified order // when a new connection is received. repeated common.set_filter_state.v3.FilterStateValue on_new_connection = 1; + + // A sequence of the filter state values to apply in the specified order + // when the downstream TLS handshake is complete. + // + // For non-TLS downstream connections (where there is no TLS handshake), this + // list is applied when a new connection is received. + repeated common.set_filter_state.v3.FilterStateValue on_downstream_tls_handshake = 2; } diff --git a/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto b/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto index f4d57c9..ff21568 100644 --- a/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto +++ b/src/main/proto/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto @@ -7,7 +7,9 @@ import "envoy/config/core/v3/backoff.proto"; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/config_source.proto"; import "envoy/config/core/v3/proxy_protocol.proto"; +import "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto"; import "envoy/type/v3/hash_policy.proto"; +import "envoy/type/v3/percent.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; @@ -27,14 +29,41 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // TCP Proxy :ref:`configuration overview `. // [#extension: envoy.filters.network.tcp_proxy] -// [#next-free-field: 20] +// Specifies when the TCP proxy establishes the upstream connection. +enum UpstreamConnectMode { + // Establish the upstream connection immediately when the downstream connection is accepted. + // This is the default behavior and provides the lowest latency. + IMMEDIATE = 0; + + // Wait for initial data from the downstream connection before establishing the upstream connection. + // This allows preceding filters to inspect the initial data (e.g., extracting SNI from TLS ClientHello) + // before the upstream connection is established. + // + // This mode requires ``max_early_data_bytes`` to be set. + // + // .. warning:: + // This mode is not suitable for server-first protocols (e.g., SMTP, MySQL, POP3) where the + // server sends the initial greeting. For such protocols, use ``IMMEDIATE`` mode. + ON_DOWNSTREAM_DATA = 1; + + // Wait for the downstream TLS handshake to complete before establishing the upstream connection. + // This allows access to the full TLS connection information, including client certificates + // and negotiated parameters, which can be used for routing decisions or passed as metadata + // to the upstream. + // + // .. note:: + // This mode is only effective when the downstream connection uses TLS. For non-TLS + // connections, it behaves the same as ``IMMEDIATE``. + ON_DOWNSTREAM_TLS_HANDSHAKE = 2; +} + +// [#next-free-field: 23] message TcpProxy { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.tcp_proxy.v2.TcpProxy"; - // Allows for specification of multiple upstream clusters along with weights - // that indicate the percentage of traffic to be forwarded to each cluster. - // The router selects an upstream cluster based on these weights. + // Allows specification of multiple upstream clusters along with weights indicating the percentage of + // traffic forwarded to each cluster. The cluster selection is based on these weights. message WeightedCluster { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.tcp_proxy.v2.TcpProxy.WeightedCluster"; @@ -60,29 +89,29 @@ message TcpProxy { config.core.v3.Metadata metadata_match = 3; } - // Specifies one or more upstream clusters associated with the route. + // Specifies the upstream clusters associated with this configuration. repeated ClusterWeight clusters = 1 [(validate.rules).repeated = {min_items: 1}]; } // Configuration for tunneling TCP over other transports or application layers. - // Tunneling is supported over both HTTP/1.1 and HTTP/2. Upstream protocol is + // Tunneling is supported over HTTP/1.1 and HTTP/2. The upstream protocol is // determined by the cluster configuration. - // [#next-free-field: 7] + // [#next-free-field: 10] message TunnelingConfig { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.tcp_proxy.v2.TcpProxy.TunnelingConfig"; // The hostname to send in the synthesized CONNECT headers to the upstream proxy. - // This field evaluates command operators if set, otherwise returns hostname as is. + // This field evaluates command operators if present; otherwise, the value is used as-is. // - // Example: dynamically set hostname using downstream SNI + // For example, dynamically set the hostname using downstream SNI: // // .. code-block:: yaml // // tunneling_config: // hostname: "%REQUESTED_SERVER_NAME%:443" // - // Example: dynamically set hostname using dynamic metadata + // For example, dynamically set the hostname using dynamic metadata: // // .. code-block:: yaml // @@ -91,62 +120,92 @@ message TcpProxy { // string hostname = 1 [(validate.rules).string = {min_len: 1}]; - // Use POST method instead of CONNECT method to tunnel the TCP stream. - // The 'protocol: bytestream' header is also NOT set for HTTP/2 to comply with the spec. + // Use the ``POST`` method instead of the ``CONNECT`` method to tunnel the TCP stream. + // The ``protocol: bytestream`` header is not set for HTTP/2 to comply with the specification. // - // The upstream proxy is expected to convert POST payload as raw TCP. + // The upstream proxy is expected to interpret the POST payload as raw TCP. bool use_post = 2; - // Additional request headers to upstream proxy. This is mainly used to - // trigger upstream to convert POST requests back to CONNECT requests. + // Additional request headers to send to the upstream proxy. This is mainly used to + // trigger the upstream to convert POST requests back to CONNECT requests. // - // Neither ``:-prefixed`` pseudo-headers nor the Host: header can be overridden. + // Neither ``:``-prefixed pseudo-headers like ``:path`` nor the ``host`` header can be overridden. repeated config.core.v3.HeaderValueOption headers_to_add = 3 [(validate.rules).repeated = {max_items: 1000}]; - // Save the response headers to the downstream info filter state for consumption - // by the network filters. The filter state key is ``envoy.tcp_proxy.propagate_response_headers``. + // Save response headers to the downstream connection's filter state for consumption + // by network filters. The filter state key is ``envoy.tcp_proxy.propagate_response_headers``. bool propagate_response_headers = 4; - // The path used with POST method. Default path is ``/``. If post path is specified and + // The path used with the POST method. The default path is ``/``. If this field is specified and // :ref:`use_post field ` - // isn't true, it will be rejected. + // is not set to true, the configuration will be rejected. string post_path = 5; - // Save the response trailers to the downstream info filter state for consumption - // by the network filters. The filter state key is ``envoy.tcp_proxy.propagate_response_trailers``. + // Save response trailers to the downstream connection's filter state for consumption + // by network filters. The filter state key is ``envoy.tcp_proxy.propagate_response_trailers``. bool propagate_response_trailers = 6; + + // The configuration of the request ID extension used for generation, validation, and + // associated tracing operations when tunneling. + // + // If this field is set, a request ID is generated using the specified extension. If + // this field is not set, no request ID is generated. + // + // When a request ID is generated, it is also stored in the downstream connection's + // dynamic metadata under the namespace ``envoy.filters.network.tcp_proxy`` with the key + // ``tunnel_request_id`` to allow emission from TCP proxy access logs via the + // ``%DYNAMIC_METADATA(envoy.filters.network.tcp_proxy:tunnel_request_id)%`` formatter. + // [#extension-category: envoy.request_id] + http_connection_manager.v3.RequestIDExtension request_id_extension = 7; + + // The request header name to use for emitting the generated request ID on the tunneling + // HTTP request. + // + // If not specified or set to an empty string, the default header name ``x-request-id`` is + // used. + // + // .. note:: + // This setting does not alter the internal request ID handling elsewhere in Envoy and + // only controls the header emitted on the tunneling request. + string request_id_header = 8; + + // The dynamic metadata key to use when storing the generated request ID. The metadata is + // stored under the namespace ``envoy.filters.network.tcp_proxy``. + // + // If not specified or set to an empty string, the default key ``tunnel_request_id`` is used. + // This enables customizing the key used by access log formatters such as + // ``%DYNAMIC_METADATA(envoy.filters.network.tcp_proxy:)%``. + string request_id_metadata_key = 9; } message OnDemand { - // An optional configuration for on-demand cluster discovery - // service. If not specified, the on-demand cluster discovery will - // be disabled. When it's specified, the filter will pause a request - // to an unknown cluster and will begin a cluster discovery - // process. When the discovery is finished (successfully or not), - // the request will be resumed. + // Optional configuration for the on-demand cluster discovery service. + // If not specified, on-demand cluster discovery is disabled. When specified, the filter pauses a request + // to an unknown cluster and begins a cluster discovery process. When discovery completes (successfully + // or not), the request is resumed. config.core.v3.ConfigSource odcds_config = 1; // xdstp:// resource locator for on-demand cluster collection. // [#not-implemented-hide:] string resources_locator = 2; - // The timeout for on demand cluster lookup. If the CDS cannot return the required cluster, + // The timeout for on-demand cluster lookup. If the CDS cannot return the required cluster, // the downstream request will be closed with the error code detail NO_CLUSTER_FOUND. // [#not-implemented-hide:] google.protobuf.Duration timeout = 3; } message TcpAccessLogOptions { - // The interval to flush access log. The TCP proxy will flush only one access log when the connection - // is closed by default. If this field is set, the TCP proxy will flush access log periodically with - // the specified interval. + // The interval for flushing access logs. By default, the TCP proxy flushes a single access log when the + // connection is closed. If this field is set, the TCP proxy flushes access logs periodically at the + // specified interval. // The interval must be at least 1ms. google.protobuf.Duration access_log_flush_interval = 1 [(validate.rules).duration = {gte {nanos: 1000000}}]; - // If set to true, access log will be flushed when the TCP proxy has successfully established a - // connection with the upstream. If the connection failed, the access log will not be flushed. + // If set to true, the access log is flushed when the TCP proxy successfully establishes a + // connection with the upstream. If the connection fails, the access log is not flushed. bool flush_access_log_on_connected = 2; } @@ -164,9 +223,8 @@ message TcpProxy { // The upstream cluster to connect to. string cluster = 2; - // Multiple upstream clusters can be specified for a given route. The - // request is routed to one of the upstream clusters based on weights - // assigned to each cluster. + // Multiple upstream clusters can be specified. The request is routed to one of the upstream clusters + // based on the weights assigned to each cluster. WeightedCluster weighted_clusters = 10; } @@ -182,16 +240,14 @@ message TcpProxy { // for load balancing. The filter name should be specified as ``envoy.lb``. config.core.v3.Metadata metadata_match = 9; - // The idle timeout for connections managed by the TCP proxy filter. The idle timeout - // is defined as the period in which there are no bytes sent or received on either - // the upstream or downstream connection. If not set, the default idle timeout is 1 hour. If set - // to 0s, the timeout will be disabled. - // It is possible to dynamically override this configuration by setting a per-connection filter - // state object for the key ``envoy.tcp_proxy.per_connection_idle_timeout_ms``. + // The idle timeout for connections managed by the TCP proxy filter. The idle timeout is defined as the + // period in which there are no bytes sent or received on either the upstream or downstream connection. + // If not set, the default idle timeout is 1 hour. If set to ``0s``, the timeout is disabled. + // It is possible to dynamically override this configuration by setting a per-connection filter state + // object for the key ``envoy.tcp_proxy.per_connection_idle_timeout_ms``. // // .. warning:: - // Disabling this timeout has a highly likelihood of yielding connection leaks due to lost TCP - // FIN packets, etc. + // Disabling this timeout is likely to yield connection leaks due to lost TCP FIN packets, etc. google.protobuf.Duration idle_timeout = 8; // [#not-implemented-hide:] The idle timeout for connections managed by the TCP proxy @@ -205,8 +261,7 @@ message TcpProxy { // [#not-implemented-hide:] google.protobuf.Duration upstream_idle_timeout = 4; - // Configuration for :ref:`access logs ` - // emitted by the this tcp_proxy. + // Configuration for :ref:`access logs ` emitted by this TCP proxy. repeated config.accesslog.v3.AccessLog access_log = 5; // The maximum number of unsuccessful connection attempts that will be made before @@ -221,19 +276,25 @@ message TcpProxy { // limited to 1. repeated type.v3.HashPolicy hash_policy = 11 [(validate.rules).repeated = {max_items: 1}]; - // If set, this configures tunneling, e.g. configuration options to tunnel TCP payload over - // HTTP CONNECT. If this message is absent, the payload will be proxied upstream as per usual. - // It is possible to dynamically override this configuration and disable tunneling per connection, - // by setting a per-connection filter state object for the key ``envoy.tcp_proxy.disable_tunneling``. + // If set, this configures tunneling, for example configuration options to tunnel TCP payload over + // HTTP CONNECT. If this message is absent, the payload is proxied upstream as usual. + // It is possible to dynamically override this configuration and disable tunneling per connection by + // setting a per-connection filter state object for the key ``envoy.tcp_proxy.disable_tunneling``. TunnelingConfig tunneling_config = 12; - // The maximum duration of a connection. The duration is defined as the period since a connection - // was established. If not set, there is no max duration. When max_downstream_connection_duration - // is reached the connection will be closed. Duration must be at least 1ms. + // The maximum duration of a connection. The duration is defined as the period since a connection was + // established. If not set, there is no maximum duration. When ``max_downstream_connection_duration`` is + // reached, the connection is closed. The duration must be at least ``1ms``. google.protobuf.Duration max_downstream_connection_duration = 13 [(validate.rules).duration = {gte {nanos: 1000000}}]; - // Note that if both this field and :ref:`access_log_flush_interval + // Percentage-based jitter for ``max_downstream_connection_duration``. The jitter increases the + // ``max_downstream_connection_duration`` by a random duration up to the provided percentage. + // This field is ignored if ``max_downstream_connection_duration`` is not set. If not set, no jitter + // is added. + type.v3.Percent max_downstream_connection_duration_jitter_percentage = 20; + + // If both this field and :ref:`access_log_flush_interval // ` // are specified, the former (deprecated field) is ignored. // @@ -247,7 +308,7 @@ message TcpProxy { (envoy.annotations.deprecated_at_minor_version) = "3.0" ]; - // Note that if both this field and :ref:`flush_access_log_on_connected + // If both this field and :ref:`flush_access_log_on_connected // ` // are specified, the former (deprecated field) is ignored. // @@ -258,22 +319,49 @@ message TcpProxy { bool flush_access_log_on_connected = 16 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // Additional access log options for TCP Proxy. + // Additional access log options for the TCP proxy. TcpAccessLogOptions access_log_options = 17; - // If set, the specified PROXY protocol TLVs (Type-Length-Value) will be added to the PROXY protocol - // state created by the TCP proxy filter. These TLVs will be sent in the PROXY protocol v2 header - // to upstream. + // If set, the specified ``PROXY`` protocol TLVs (Type-Length-Value) are added to the ``PROXY`` protocol state + // created by the TCP proxy filter. These TLVs are sent in the PROXY protocol v2 header to the upstream. // - // This field only takes effect when the TCP proxy filter is creating new PROXY protocol - // state and there is an upstream proxy protocol transport socket configured in the cluster. - // If the connection already contains PROXY protocol state (including any TLVs) parsed by a - // downstream proxy protocol listener filter, the TLVs specified here are ignored. + // This field only takes effect when the TCP proxy filter is creating new ``PROXY`` protocol state and an + // upstream proxy protocol transport socket is configured in the cluster. If the connection already + // contains ``PROXY`` protocol state (including any TLVs) parsed by a downstream proxy protocol listener + // upstream proxy protocol transport socket is configured in the cluster. If the connection already + // contains PROXY protocol state (including any TLVs) parsed by a downstream proxy protocol listener + // filter, the TLVs specified here are ignored. // // .. note:: - // To ensure specified TLVs are allowed in the upstream PROXY protocol header, you must also - // configure the passthrough TLVs on the upstream proxy protocol transport. See + // To ensure the specified TLVs are allowed in the upstream ``PROXY`` protocol header, you must also + // configure passthrough TLVs on the upstream proxy protocol transport. See // :ref:`core.v3.ProxyProtocolConfig.pass_through_tlvs ` // for details. repeated config.core.v3.TlvEntry proxy_protocol_tlvs = 19; + + // Specifies when to establish the upstream connection. + // + // When not specified, defaults to ``IMMEDIATE`` for backward compatibility. + // + // .. attention:: + // Server-first protocols (e.g., SMTP, MySQL, POP3) require ``IMMEDIATE`` mode. + UpstreamConnectMode upstream_connect_mode = 21 [(validate.rules).enum = {defined_only: true}]; + + // Maximum bytes of early data to buffer from the downstream connection before + // the upstream connection is established. + // + // If not set, the TCP proxy will read-disable the downstream connection until the + // upstream connection is established (legacy behavior). + // + // If set, enables ``receive_before_connect`` mode where the filter allows the filter + // chain to read downstream data before the upstream connection exists. The data is + // buffered and forwarded once the upstream connection is ready. When the buffer exceeds + // this limit, the downstream connection is read-disabled to prevent excessive memory usage. + // + // This field is required when ``upstream_connect_mode`` is ``ON_DOWNSTREAM_DATA``. + // + // .. note:: + // Use this carefully with server-first protocols. The upstream may send data before + // receiving anything from downstream, which could fill the early data buffer. + google.protobuf.UInt32Value max_early_data_bytes = 22 [(validate.rules).uint32 = {lte: 1048576}]; } diff --git a/src/main/proto/envoy/extensions/filters/udp/dns_filter/v3/dns_filter.proto b/src/main/proto/envoy/extensions/filters/udp/dns_filter/v3/dns_filter.proto index 70c4164..621a0ff 100644 --- a/src/main/proto/envoy/extensions/filters/udp/dns_filter/v3/dns_filter.proto +++ b/src/main/proto/envoy/extensions/filters/udp/dns_filter/v3/dns_filter.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package envoy.extensions.filters.udp.dns_filter.v3; +import "envoy/config/accesslog/v3/accesslog.proto"; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/extension.proto"; @@ -102,6 +103,24 @@ message DnsFilterConfig { // Client context configuration controls Envoy's behavior when it must use external // resolvers to answer a query. This object is optional and if omitted instructs - // the filter to resolve queries from the data in the server_config + // the filter to resolve queries from the data in the server_config. + // Also, if ``client_config`` is omitted, here is the Envoy's behavior to create DNS resolver: + // + // 1. If :ref:`typed_dns_resolver_config ` + // is not empty, uses it. + // + // 2. Otherwise, uses the default c-ares DNS resolver. + // ClientContextConfig client_config = 3; + + // Configuration for :ref:`access logs ` + // emitted by the DNS filter for each DNS query received. + // Supports custom format commands for DNS-specific attributes: + // - ``QUERY_NAME``: The DNS query name being resolved + // - ``QUERY_TYPE``: The DNS query type (A, AAAA, SRV, etc.) + // - ``QUERY_CLASS``: The DNS query class + // - ``ANSWER_COUNT``: Number of answers in the response + // - ``RESPONSE_CODE``: DNS response code + // - ``PARSE_STATUS``: Whether the query was successfully parsed + repeated config.accesslog.v3.AccessLog access_log = 4; } diff --git a/src/main/proto/envoy/extensions/filters/udp/dynamic_modules/v3/dynamic_modules.proto b/src/main/proto/envoy/extensions/filters/udp/dynamic_modules/v3/dynamic_modules.proto new file mode 100644 index 0000000..7f0defc --- /dev/null +++ b/src/main/proto/envoy/extensions/filters/udp/dynamic_modules/v3/dynamic_modules.proto @@ -0,0 +1,65 @@ +syntax = "proto3"; + +package envoy.extensions.filters.udp.dynamic_modules.v3; + +import "envoy/extensions/dynamic_modules/v3/dynamic_modules.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.udp.dynamic_modules.v3"; +option java_outer_classname = "DynamicModulesProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/udp/dynamic_modules/v3;dynamic_modulesv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Dynamic Modules UDP Listener Filter] +// [#extension: envoy.filters.udp_listener.dynamic_modules] + +// Configuration for the Dynamic Modules UDP listener filter. This filter allows loading shared object +// files that can be loaded via ``dlopen`` to extend the UDP listener filter chain. +// +// A module can be loaded by multiple UDP listener filters; the module is loaded only once and shared +// across multiple filters. +message DynamicModuleUdpListenerFilter { + // Specifies the shared-object level configuration. + envoy.extensions.dynamic_modules.v3.DynamicModuleConfig dynamic_module_config = 1; + + // The name for this filter configuration. + // + // This can be used to distinguish between different filter implementations inside a dynamic + // module. For example, a module can have completely different filter implementations. When Envoy + // receives this configuration, it passes the ``filter_name`` to the dynamic module's UDP listener + // filter config init function together with the ``filter_config``. That way a module can decide + // which in-module filter implementation to use based on the name at load time. + string filter_name = 2; + + // The configuration for the filter chosen by ``filter_name``. + // + // This is passed to the module's UDP listener filter initialization function. Together with the + // ``filter_name``, the module can decide which in-module filter implementation to use and + // fine-tune the behavior of the filter. + // + // For example, if a module has two filter implementations, one for echo and one for rate + // limiting, ``filter_name`` is used to choose either echo or rate limiting. The + // ``filter_config`` can be used to configure the echo behavior or the rate limiting parameters. + // + // ``google.protobuf.Struct`` is serialized as JSON before passing it to the module. + // ``google.protobuf.BytesValue`` and ``google.protobuf.StringValue`` are passed directly + // without the wrapper. + // + // .. code-block:: yaml + // + // # Passing a string value + // filter_config: + // "@type": "type.googleapis.com/google.protobuf.StringValue" + // value: hello + // + // # Passing raw bytes + // filter_config: + // "@type": "type.googleapis.com/google.protobuf.BytesValue" + // value: aGVsbG8= # echo -n "hello" | base64 + // + google.protobuf.Any filter_config = 3; +} diff --git a/src/main/proto/envoy/extensions/formatter/cel/v3/cel.proto b/src/main/proto/envoy/extensions/formatter/cel/v3/cel.proto index 265f9dd..ced34e7 100644 --- a/src/main/proto/envoy/extensions/formatter/cel/v3/cel.proto +++ b/src/main/proto/envoy/extensions/formatter/cel/v3/cel.proto @@ -30,6 +30,23 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // * ``%CEL(request.headers['x-envoy-original-path']):10%`` // * ``%CEL(request.headers['x-log-mtls'] || request.url_path.contains('v1beta3'))%`` +// Alternatively: %TYPED_CEL(EXPRESSION):Z% +// When using a non-text access log format like JSON, this format command is +// able to emit values of non-string types, like number, boolean, and null, +// based on the output of the CEL expression. It otherwise functions the same as +// %CEL%. CEL types not native to JSON are coerced as follows: +// +// * Bytes are base64 encoded to produce a string. +// * Durations are stringified as a count of seconds, e.g. `duration("1h30m")` +// becomes "5400s". +// * Timestamps are formatted to UTC, e.g. +// `timestamp("2023-08-26T12:39:00-07:00")` becomes +// "2023-08-26T19:39:00+00:00" +// * Maps become objects, provided all keys can be coerced to strings and that +// all values can coerce to types representable in JSON. +// * Lists become lists, provided all values can coerce to types representable +// in JSON. + // Configuration for the CEL formatter. // // .. warning:: diff --git a/src/main/proto/envoy/extensions/formatter/metadata/v3/metadata.proto b/src/main/proto/envoy/extensions/formatter/metadata/v3/metadata.proto index 816a6be..ccde766 100644 --- a/src/main/proto/envoy/extensions/formatter/metadata/v3/metadata.proto +++ b/src/main/proto/envoy/extensions/formatter/metadata/v3/metadata.proto @@ -22,6 +22,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // * ROUTE // * UPSTREAM_HOST // * LISTENER +// * LISTENER_FILTER_CHAIN // * VIRTUAL_HOST // // See :ref:`here ` for more information on access log configuration. diff --git a/src/main/proto/envoy/extensions/geoip_providers/common/v3/common.proto b/src/main/proto/envoy/extensions/geoip_providers/common/v3/common.proto index e289751..778b2ca 100644 --- a/src/main/proto/envoy/extensions/geoip_providers/common/v3/common.proto +++ b/src/main/proto/envoy/extensions/geoip_providers/common/v3/common.proto @@ -18,8 +18,12 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; message CommonGeoipProviderConfig { // The set of geolocation headers to add to request. If any of the configured headers is present - // in the incoming request, it will be overridden by the :ref:`Geoip filter `. + // in the incoming request, it will be overridden by the :ref:`HTTP GeoIP filter `. // [#next-free-field: 13] + // + // .. attention:: + // This field is deprecated in favor of :ref:`geo_field_keys + // `. message GeolocationHeadersToAdd { // If set, the header will be used to populate the country ISO code associated with the IP address. string country = 1 @@ -30,7 +34,7 @@ message CommonGeoipProviderConfig { [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; // If set, the header will be used to populate the region ISO code associated with the IP address. - // The least specific subdivision will be selected as region value. + // The least specific subdivision will be selected as the region value. string region = 3 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; @@ -38,35 +42,35 @@ message CommonGeoipProviderConfig { string asn = 4 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; - // This field is being deprecated, use ``anon`` instead. + // This field is deprecated; use ``anon`` instead. string is_anon = 5 [ deprecated = true, (validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}, (envoy.annotations.deprecated_at_minor_version) = "3.0" ]; - // If set, the IP address will be checked if it belongs to any type of anonymization network (e.g. VPN, public proxy etc) - // and header will be populated with the check result. Header value will be set to either "true" or "false" depending on the check result. + // If set, the IP address will be checked if it belongs to any type of anonymization network (e.g., VPN, public proxy). + // The header will be populated with the check result. Header value will be set to either ``true`` or ``false`` depending on the check result. string anon = 12 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; - // If set, the IP address will be checked if it belongs to a VPN and header will be populated with the check result. - // Header value will be set to either "true" or "false" depending on the check result. + // If set, the IP address will be checked if it belongs to a VPN and the header will be populated with the check result. + // Header value will be set to either ``true`` or ``false`` depending on the check result. string anon_vpn = 6 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; - // If set, the IP address will be checked if it belongs to a hosting provider and header will be populated with the check result. - // Header value will be set to either "true" or "false" depending on the check result. + // If set, the IP address will be checked if it belongs to a hosting provider and the header will be populated with the check result. + // Header value will be set to either ``true`` or ``false`` depending on the check result. string anon_hosting = 7 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; - // If set, the IP address will be checked if it belongs to a TOR exit node and header will be populated with the check result. - // Header value will be set to either "true" or "false" depending on the check result. + // If set, the IP address will be checked if it belongs to a TOR exit node and the header will be populated with the check result. + // Header value will be set to either ``true`` or ``false`` depending on the check result. string anon_tor = 8 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; - // If set, the IP address will be checked if it belongs to a public proxy and header will be populated with the check result. - // Header value will be set to either "true" or "false" depending on the check result. + // If set, the IP address will be checked if it belongs to a public proxy and the header will be populated with the check result. + // Header value will be set to either ``true`` or ``false`` depending on the check result. string anon_proxy = 9 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; @@ -74,12 +78,75 @@ message CommonGeoipProviderConfig { string isp = 10 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; - // If set, the IP address will be checked if it belongs to the ISP named iCloud Private Relay and header will be populated with the check result. - // Header value will be set to either "true" or "false" depending on the check result. + // If set, the IP address will be checked if it belongs to the ISP named iCloud Private Relay and the header will be populated with the check result. + // Header value will be set to either ``true`` or ``false`` depending on the check result. string apple_private_relay = 11 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; } - // Configuration for geolocation headers to add to request. - GeolocationHeadersToAdd geo_headers_to_add = 1 [(validate.rules).message = {required: true}]; + // The set of geolocation field keys to use for storing lookup results. + // These keys define how the geolocation lookup results will be stored. The actual storage + // mechanism depends on the filter using the provider: + // + // - The :ref:`HTTP GeoIP filter ` stores results as HTTP request headers. + // - The :ref:`Network GeoIP filter ` stores results in the + // connection's filter state under the well-known key ``envoy.geoip``. + // + // [#next-free-field: 12] + message GeolocationFieldKeys { + // If set, the key will be used to populate the country ISO code associated with the IP address. + string country = 1; + + // If set, the key will be used to populate the city associated with the IP address. + string city = 2; + + // If set, the key will be used to populate the region ISO code associated with the IP address. + // The least specific subdivision will be selected as the region value. + string region = 3; + + // If set, the key will be used to populate the ASN associated with the IP address. + string asn = 4; + + // If set, the IP address will be checked if it belongs to any type of anonymization network + // (e.g., VPN, public proxy). The result will be stored with this key. Value will be set to + // either ``true`` or ``false`` depending on the check result. + string anon = 5; + + // If set, the IP address will be checked if it belongs to a VPN and the result will be stored + // with this key. Value will be set to either ``true`` or ``false`` depending on the check result. + string anon_vpn = 6; + + // If set, the IP address will be checked if it belongs to a hosting provider and the result + // will be stored with this key. Value will be set to either ``true`` or ``false`` depending on + // the check result. + string anon_hosting = 7; + + // If set, the IP address will be checked if it belongs to a TOR exit node and the result will + // be stored with this key. Value will be set to either ``true`` or ``false`` depending on the + // check result. + string anon_tor = 8; + + // If set, the IP address will be checked if it belongs to a public proxy and the result will + // be stored with this key. Value will be set to either ``true`` or ``false`` depending on the + // check result. + string anon_proxy = 9; + + // If set, the key will be used to populate the ISP associated with the IP address. + string isp = 10; + + // If set, the IP address will be checked if it belongs to the ISP named iCloud Private Relay + // and the result will be stored with this key. Value will be set to either ``true`` or ``false`` + // depending on the check result. + string apple_private_relay = 11; + } + + // Configuration for geolocation headers to add to HTTP requests. + // This field is deprecated in favor of ``geo_field_keys``. If both are set, ``geo_field_keys`` + // takes precedence. + GeolocationHeadersToAdd geo_headers_to_add = 1 + [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + + // Configuration for geolocation field keys. + // At least one of ``geo_headers_to_add`` or ``geo_field_keys`` must be set. + GeolocationFieldKeys geo_field_keys = 3; } diff --git a/src/main/proto/envoy/extensions/geoip_providers/maxmind/v3/maxmind.proto b/src/main/proto/envoy/extensions/geoip_providers/maxmind/v3/maxmind.proto index fb665ac..91e00c1 100644 --- a/src/main/proto/envoy/extensions/geoip_providers/maxmind/v3/maxmind.proto +++ b/src/main/proto/envoy/extensions/geoip_providers/maxmind/v3/maxmind.proto @@ -18,33 +18,44 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // [#protodoc-title: MaxMind Geolocation Provider] // MaxMind geolocation provider :ref:`configuration overview `. -// At least one geolocation database path :ref:`city_db_path `, -// :ref:`isp_db_path ` or -// :ref:`asn_db_path ` or -// :ref:`anon_db_path ` must be configured. +// +// At least one geolocation database path must be configured: +// +// * :ref:`city_db_path ` +// * :ref:`isp_db_path ` +// * :ref:`asn_db_path ` +// * :ref:`anon_db_path ` +// * :ref:`country_db_path ` // [#extension: envoy.geoip_providers.maxmind] -// [#next-free-field: 6] +// [#next-free-field: 7] message MaxMindConfig { - // Full file path to the Maxmind city database, e.g. /etc/GeoLite2-City.mmdb. - // Database file is expected to have .mmdb extension. + // Full file path to the MaxMind city database, e.g., ``/etc/GeoLite2-City.mmdb``. + // Database file is expected to have ``.mmdb`` extension. string city_db_path = 1 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; - // Full file path to the Maxmind ASN database, e.g. /etc/GeoLite2-ASN.mmdb. - // Database file is expected to have .mmdb extension. - // When is defined the ASN information will always be fetched from the ``asn_db``. + // Full file path to the MaxMind ASN database, e.g., ``/etc/GeoLite2-ASN.mmdb``. + // Database file is expected to have ``.mmdb`` extension. + // When this is defined, the ASN information will always be fetched from the ``asn_db``. string asn_db_path = 2 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; - // Full file path to the Maxmind anonymous IP database, e.g. /etc/GeoIP2-Anonymous-IP.mmdb. - // Database file is expected to have .mmdb extension. + // Full file path to the MaxMind Anonymous IP database, e.g., ``/etc/GeoIP2-Anonymous-IP.mmdb``. + // Database file is expected to have ``.mmdb`` extension. string anon_db_path = 3 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; - // Full file path to the Maxmind ISP database, e.g. /etc/GeoLite2-ISP.mmdb. - // Database file is expected to have .mmdb extension. + // Full file path to the MaxMind ISP database, e.g., ``/etc/GeoLite2-ISP.mmdb``. + // Database file is expected to have ``.mmdb`` extension. // If ``asn_db_path`` is not defined, ASN information will be fetched from // ``isp_db`` instead. string isp_db_path = 5 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; + // Full file path to the MaxMind Country database, e.g., ``/etc/GeoLite2-Country.mmdb``. + // Database file is expected to have ``.mmdb`` extension. + // + // If ``country_db_path`` is not specified, country information will be fetched from + // ``city_db`` if ``city_db`` is configured. + string country_db_path = 6 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; + // Common provider configuration that specifies which geolocation headers will be populated with geolocation data. common.v3.CommonGeoipProviderConfig common_provider_config = 4 [(validate.rules).message = {required: true}]; diff --git a/src/main/proto/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.proto new file mode 100644 index 0000000..45ee383 --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.call_credentials.access_token.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.call_credentials.access_token.v3"; +option java_outer_classname = "AccessTokenCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/access_token/v3;access_tokenv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Access Token Credentials] + +// [#not-implemented-hide:] +message AccessTokenCredentials { + // The access token. + string token = 1; +} diff --git a/src/main/proto/envoy/extensions/grpc_service/call_credentials/file_based_metadata/v3/file_based_metadata_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/call_credentials/file_based_metadata/v3/file_based_metadata_credentials.proto new file mode 100644 index 0000000..cacb098 --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/call_credentials/file_based_metadata/v3/file_based_metadata_credentials.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.call_credentials.file_based_metadata.v3; + +import "envoy/config/core/v3/base.proto"; + +import "udpa/annotations/sensitive.proto"; +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.call_credentials.file_based_metadata.v3"; +option java_outer_classname = "FileBasedMetadataCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/file_based_metadata/v3;file_based_metadatav3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: File-Based Metadata Call Credentials] + +// [#not-implemented-hide:] +message FileBasedMetadataCallCredentials { + // Location or inline data of secret to use for authentication of the Google gRPC connection + // this secret will be attached to a header of the gRPC connection + config.core.v3.DataSource secret_data = 1 [(udpa.annotations.sensitive) = true]; + + // Metadata header key to use for sending the secret data + // if no header key is set, "authorization" header will be used + string header_key = 2; + + // Prefix to prepend to the secret in the metadata header + // if no prefix is set, the default is to use no prefix + string header_prefix = 3; +} diff --git a/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_compute_engine/v3/google_compute_engine_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_compute_engine/v3/google_compute_engine_credentials.proto new file mode 100644 index 0000000..d73086b --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_compute_engine/v3/google_compute_engine_credentials.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.call_credentials.google_compute_engine.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.call_credentials.google_compute_engine.v3"; +option java_outer_classname = "GoogleComputeEngineCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/google_compute_engine/v3;google_compute_enginev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Google Compute Engine Credentials] + +// [#not-implemented-hide:] +message GoogleComputeEngineCredentials { +} diff --git a/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_iam/v3/google_iam_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_iam/v3/google_iam_credentials.proto new file mode 100644 index 0000000..0ed5a2d --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_iam/v3/google_iam_credentials.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.call_credentials.google_iam.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.call_credentials.google_iam.v3"; +option java_outer_classname = "GoogleIamCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/google_iam/v3;google_iamv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Google IAM Credentials] + +// [#not-implemented-hide:] +message GoogleIamCredentials { + // Authorization token. + string authorization_token = 1; + + // Authority selector. + string authority_selector = 2; +} diff --git a/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_refresh_token/v3/google_refresh_token_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_refresh_token/v3/google_refresh_token_credentials.proto new file mode 100644 index 0000000..ce32c95 --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/call_credentials/google_refresh_token/v3/google_refresh_token_credentials.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.call_credentials.google_refresh_token.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.call_credentials.google_refresh_token.v3"; +option java_outer_classname = "GoogleRefreshTokenCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/google_refresh_token/v3;google_refresh_tokenv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Google Refresh Token Credentials] + +// [#not-implemented-hide:] +message GoogleRefreshTokenCredentials { + // JSON refresh token. + string token = 1; +} diff --git a/src/main/proto/envoy/extensions/grpc_service/call_credentials/service_account_jwt_access/v3/service_account_jwt_access_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/call_credentials/service_account_jwt_access/v3/service_account_jwt_access_credentials.proto new file mode 100644 index 0000000..09c686f --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/call_credentials/service_account_jwt_access/v3/service_account_jwt_access_credentials.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.call_credentials.service_account_jwt_access.v3; + +import "google/protobuf/duration.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.call_credentials.service_account_jwt_access.v3"; +option java_outer_classname = "ServiceAccountJwtAccessCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/service_account_jwt_access/v3;service_account_jwt_accessv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Service Account JWT Access Credentials] + +// [#not-implemented-hide:] +message ServiceAccountJwtAccessCredentials { + // JSON key. + string json_key = 1; + + // Token lifetime. + google.protobuf.Duration token_lifetime = 2; +} diff --git a/src/main/proto/envoy/extensions/grpc_service/call_credentials/sts_service/v3/sts_service_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/call_credentials/sts_service/v3/sts_service_credentials.proto new file mode 100644 index 0000000..12f285d --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/call_credentials/sts_service/v3/sts_service_credentials.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.call_credentials.sts_service.v3; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.call_credentials.sts_service.v3"; +option java_outer_classname = "StsServiceCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/sts_service/v3;sts_servicev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC STS Credentials] + +// Security token service configuration that allows Google gRPC to +// fetch security token from an OAuth 2.0 authorization server. +// See https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16 and +// https://github.com/grpc/grpc/pull/19587. +// [#not-implemented-hide:] +// [#next-free-field: 10] +message StsServiceCredentials { + // URI of the token exchange service that handles token exchange requests. + // [#comment:TODO(asraa): Add URI validation when implemented. Tracked by + // https://github.com/bufbuild/protoc-gen-validate/issues/303] + string token_exchange_service_uri = 1; + + // Location of the target service or resource where the client + // intends to use the requested security token. + string resource = 2; + + // Logical name of the target service where the client intends to + // use the requested security token. + string audience = 3; + + // The desired scope of the requested security token in the + // context of the service or resource where the token will be used. + string scope = 4; + + // Type of the requested security token. + string requested_token_type = 5; + + // The path of subject token, a security token that represents the + // identity of the party on behalf of whom the request is being made. + string subject_token_path = 6 [(validate.rules).string = {min_len: 1}]; + + // Type of the subject token. + string subject_token_type = 7 [(validate.rules).string = {min_len: 1}]; + + // The path of actor token, a security token that represents the identity + // of the acting party. The acting party is authorized to use the + // requested security token and act on behalf of the subject. + string actor_token_path = 8; + + // Type of the actor token. + string actor_token_type = 9; +} diff --git a/src/main/proto/envoy/extensions/grpc_service/channel_credentials/google_default/v3/google_default_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/google_default/v3/google_default_credentials.proto new file mode 100644 index 0000000..77c3af4 --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/google_default/v3/google_default_credentials.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.channel_credentials.google_default.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.channel_credentials.google_default.v3"; +option java_outer_classname = "GoogleDefaultCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/channel_credentials/google_default/v3;google_defaultv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Google Default Credentials] + +// [#not-implemented-hide:] +message GoogleDefaultCredentials { +} diff --git a/src/main/proto/envoy/extensions/grpc_service/channel_credentials/insecure/v3/insecure_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/insecure/v3/insecure_credentials.proto new file mode 100644 index 0000000..70d5845 --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/insecure/v3/insecure_credentials.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.channel_credentials.insecure.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.channel_credentials.insecure.v3"; +option java_outer_classname = "InsecureCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/channel_credentials/insecure/v3;insecurev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Insecure Credentials] + +// [#not-implemented-hide:] +message InsecureCredentials { +} diff --git a/src/main/proto/envoy/extensions/grpc_service/channel_credentials/local/v3/local_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/local/v3/local_credentials.proto new file mode 100644 index 0000000..00514a0 --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/local/v3/local_credentials.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.channel_credentials.local.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.channel_credentials.local.v3"; +option java_outer_classname = "LocalCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/channel_credentials/local/v3;localv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC Local Credentials] + +// [#not-implemented-hide:] +message LocalCredentials { +} diff --git a/src/main/proto/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.proto new file mode 100644 index 0000000..f64c16b --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.channel_credentials.tls.v3; + +import "envoy/extensions/transport_sockets/tls/v3/tls.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.channel_credentials.tls.v3"; +option java_outer_classname = "TlsCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/channel_credentials/tls/v3;tlsv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC TLS Credentials] + +// [#not-implemented-hide:] +message TlsCredentials { + // The certificate provider instance for the root cert. Must be set. + transport_sockets.tls.v3.CommonTlsContext.CertificateProviderInstance root_certificate_provider = + 1; + + // The certificate provider instance for the identity cert. Optional; + // if unset, no identity certificate will be sent to the server. + transport_sockets.tls.v3.CommonTlsContext.CertificateProviderInstance + identity_certificate_provider = 2; +} diff --git a/src/main/proto/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.proto b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.proto new file mode 100644 index 0000000..ba8d471 --- /dev/null +++ b/src/main/proto/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package envoy.extensions.grpc_service.channel_credentials.xds.v3; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.grpc_service.channel_credentials.xds.v3"; +option java_outer_classname = "XdsCredentialsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/channel_credentials/xds/v3;xdsv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: gRPC xDS Credentials] + +// [#not-implemented-hide:] +message XdsCredentials { + // Fallback credentials. Required. + google.protobuf.Any fallback_credentials = 1; +} diff --git a/src/main/proto/envoy/extensions/http/cache_v2/file_system_http_cache/v3/file_system_http_cache.proto b/src/main/proto/envoy/extensions/http/cache_v2/file_system_http_cache/v3/file_system_http_cache.proto new file mode 100644 index 0000000..f47546b --- /dev/null +++ b/src/main/proto/envoy/extensions/http/cache_v2/file_system_http_cache/v3/file_system_http_cache.proto @@ -0,0 +1,131 @@ +syntax = "proto3"; + +package envoy.extensions.http.cache_v2.file_system_http_cache.v3; + +import "envoy/extensions/common/async_files/v3/async_file_manager.proto"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/wrappers.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.http.cache_v2.file_system_http_cache.v3"; +option java_outer_classname = "FileSystemHttpCacheProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/http/cache_v2/file_system_http_cache/v3;file_system_http_cachev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: FileSystemHttpCacheV2Config] +// [#extension: envoy.extensions.http.cache_v2.file_system_http_cache] + +// Configuration for a cache implementation that caches in the local file system. +// +// By default this cache uses a least-recently-used eviction strategy. +// +// For implementation details, see `DESIGN.md `_. +// [#next-free-field: 11] +message FileSystemHttpCacheV2Config { + // Configuration of a manager for how the file system is used asynchronously. + common.async_files.v3.AsyncFileManagerConfig manager_config = 1 + [(validate.rules).message = {required: true}]; + + // Path at which the cache files will be stored. + // + // This also doubles as the unique identifier for a cache, so a cache can be shared + // between different routes, or separate paths can be used to specify separate caches. + // + // If the same ``cache_path`` is used in more than one ``CacheV2Config``, the rest of the + // ``FileSystemHttpCacheV2Config`` must also match, and will refer to the same cache + // instance. + string cache_path = 2 [(validate.rules).string = {min_len: 1}]; + + // The maximum size of the cache in bytes - when reached, cache eviction is triggered. + // + // This is measured as the sum of file sizes, such that it includes headers, trailers, + // and metadata, but does not include e.g. file system overhead and block size padding. + // + // If unset there is no limit except file system failure. + google.protobuf.UInt64Value max_cache_size_bytes = 3; + + // The maximum size of a cache entry in bytes - larger responses will not be cached. + // + // This is measured as the file size for the cache entry, such that it includes + // headers, trailers, and metadata. + // + // If unset there is no limit. + // + // [#not-implemented-hide:] + google.protobuf.UInt64Value max_individual_cache_entry_size_bytes = 4; + + // The maximum number of cache entries - when reached, cache eviction is triggered. + // + // If unset there is no limit. + google.protobuf.UInt64Value max_cache_entry_count = 5; + + // A number of folders into which to subdivide the cache. + // + // Setting this can help with performance in file systems where a large number of inodes + // in a single branch degrades performance. The optimal value in that case would be + // ``sqrt(expected_cache_entry_count)``. + // + // On file systems that perform well with many inodes, the default value of 1 should be used. + // + // [#not-implemented-hide:] + uint32 cache_subdivisions = 6; + + // The amount of the maximum cache size or count to evict when cache eviction is + // triggered. For example, if ``max_cache_size_bytes`` is 10000000 and ``evict_fraction`` + // is 0.2, then when the cache exceeds 10MB, entries will be evicted until the cache size is + // less than or equal to 8MB. + // + // The default value of 0 means when the cache exceeds 10MB, entries will be evicted only + // until the cache is less than or equal to 10MB. + // + // Evicting a larger fraction will mean the eviction thread will run less often (sparing + // CPU load) at the cost of more cache misses due to the extra evicted entries. + // + // [#not-implemented-hide:] + float evict_fraction = 7; + + // The longest amount of time to wait before running a cache eviction pass. An eviction + // pass may not necessarily remove any files, but it will update the cache state to match + // the on-disk state. This can be important if multiple instances are accessing the same + // cache in parallel. (e.g. if two instances each independently added non-overlapping 10MB + // of content to a cache with a 15MB limit, neither instance would be aware that the limit + // was exceeded without this synchronizing pass.) + // + // If an eviction pass has not happened within this duration, the eviction thread will + // be awoken and perform an eviction pass. + // + // If unset, there will be no eviction passes except those triggered by cache limits. + // + // [#not-implemented-hide:] + google.protobuf.Duration max_eviction_period = 8; + + // The shortest amount of time between cache eviction passes. This can be used to reduce + // eviction churn, if your cache max size can be flexible. If a cache eviction pass already + // occurred more recently than this period when another would be triggered, that new + // pass is cancelled. + // + // This means the cache can potentially grow beyond ``max_cache_size_bytes`` by as much as + // can be written within the duration specified. + // + // Generally you would use *either* ``min_eviction_period`` *or* ``evict_fraction`` to + // reduce churn. Both together will work but since they're both aiming for the same goal, + // it's simpler not to. + // + // [#not-implemented-hide:] + google.protobuf.Duration min_eviction_period = 9; + + // If true, and the cache path does not exist, attempt to create the cache path, including + // any missing directories leading up to it. On failure, the config is rejected. + // + // If false, and the cache path does not exist, the config is rejected. + // + // [#not-implemented-hide:] + bool create_cache_path = 10; +} diff --git a/src/main/proto/envoy/extensions/http/cache_v2/simple_http_cache/v3/config.proto b/src/main/proto/envoy/extensions/http/cache_v2/simple_http_cache/v3/config.proto new file mode 100644 index 0000000..9db3757 --- /dev/null +++ b/src/main/proto/envoy/extensions/http/cache_v2/simple_http_cache/v3/config.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package envoy.extensions.http.cache_v2.simple_http_cache.v3; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.http.cache_v2.simple_http_cache.v3"; +option java_outer_classname = "ConfigProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/http/cache_v2/simple_http_cache/v3;simple_http_cachev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: SimpleHttpCache CacheFilter storage plugin] + +// [#extension: envoy.extensions.http.cache_v2.simple] +message SimpleHttpCacheV2Config { +} diff --git a/src/main/proto/envoy/extensions/http/ext_proc/processing_request_modifiers/mapped_attribute_builder/v3/mapped_attribute_builder.proto b/src/main/proto/envoy/extensions/http/ext_proc/processing_request_modifiers/mapped_attribute_builder/v3/mapped_attribute_builder.proto new file mode 100644 index 0000000..2093797 --- /dev/null +++ b/src/main/proto/envoy/extensions/http/ext_proc/processing_request_modifiers/mapped_attribute_builder/v3/mapped_attribute_builder.proto @@ -0,0 +1,80 @@ +syntax = "proto3"; + +package envoy.extensions.http.ext_proc.processing_request_modifiers.mapped_attribute_builder.v3; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.http.ext_proc.processing_request_modifiers.mapped_attribute_builder.v3"; +option java_outer_classname = "MappedAttributeBuilderProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/http/ext_proc/processing_request_modifiers/mapped_attribute_builder/v3;mapped_attribute_builderv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: Mapped Attribute Builder for the external processor] +// [#extension: envoy.http.ext_proc.processing_request_modifiers.mapped_attribute_builder] + +// Extension to build custom attributes in the :ref:`request +// ` based on a configurable mapping. The +// native implementation uses the CEL expression as the key, which is not always desirable. Using this +// extension, one can re-map a CEL expression that references internal filter state into a more +// user-friendly key that decouples the value from the underlying filter implementation. +// +// If a given CEL expression fails to eval, it will not be present in the attributes struct. +// +// If this extension is configured, then the original :ref:`ProcessingRequest +// `'s ``request_attributes`` are ignored, +// and all attributes should be explicitly set via this extension. +// +// An example configuration may look like so: +// +// .. code-block:: yaml +// +// mapped_request_attributes: +// "request.path": "request.path" +// "source.country": "metadata.filter_metadata['com.example.location_filter']['country_code']" +// +// In the above example, the complex filter_metadata expression is evaluated via CEL, and the value +// is stored under the friendlier ``source.country`` key. ``The ProcessingRequest`` would look like: +// +// .. code-block:: text +// +// attributes { +// key: "envoy.filters.http.ext_proc" +// value { +// fields { +// key: "request.path" +// value { +// string_value: "/profile" +// } +// } +// fields { +// key: "source.country" +// value { +// string_value: "US" +// } +// } +// } +// } +// +// .. note:: +// Processing request modifiers are currently in alpha. +// +message MappedAttributeBuilder { + // A map of request attributes to set in the attributes struct. + // The key is the attribute name, the value is the attribute value, + // interpretable by CEL. This allows for the re-mapping of attributes, which is not supported + // by the native attribute building logic. + map mapped_request_attributes = 1; + + // Similar to ``mapped_request_attributes``, but for response attributes. The + // response nomenclature here just indicates that the attributes, whatever they may be, are sent + // with a response headers, body, or trailers ext_proc call. + // If a value contains a request key, e.g., ``request.host``, then the attribute would + // just be sent along in the response. This is useful if a given ext_proc extension is only + // enabled for response handling, e.g., ``RESPONSE_HEADERS`` but the backend wants to access request + // metadata. + map mapped_response_attributes = 2; +} diff --git a/src/main/proto/envoy/extensions/http/injected_credentials/generic/v3/generic.proto b/src/main/proto/envoy/extensions/http/injected_credentials/generic/v3/generic.proto index 7b8a178..e6c3bfa 100644 --- a/src/main/proto/envoy/extensions/http/injected_credentials/generic/v3/generic.proto +++ b/src/main/proto/envoy/extensions/http/injected_credentials/generic/v3/generic.proto @@ -31,4 +31,11 @@ message Generic { // If not set, filter will default to: ``Authorization`` string header = 2 [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; + + // The prefix to prepend to the credential value before injecting it into the header. + // This is useful for adding a scheme such as ``Bearer `` or ``Basic `` to the credential. + // For example, if the credential is ``xyz123`` and the prefix is ``Bearer ``, the + // final header value will be ``Bearer xyz123``. + // If not set, the raw credential value will be injected without any prefix. + string header_value_prefix = 3; } diff --git a/src/main/proto/envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.proto b/src/main/proto/envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.proto index 0190dc4..9b013cd 100644 --- a/src/main/proto/envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.proto +++ b/src/main/proto/envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.proto @@ -26,6 +26,7 @@ option (xds.annotations.v3.file_status).work_in_progress = true; // proxied requests. // Currently, only the Client Credentials Grant flow is supported. // The access token will be injected into the request headers using the ``Authorization`` header as a bearer token. +// [#next-free-field: 6] message OAuth2 { enum AuthType { // The ``client_id`` and ``client_secret`` will be sent using HTTP Basic authentication scheme. @@ -53,6 +54,17 @@ message OAuth2 { AuthType auth_type = 3; } + // Optional additional parameters to include in the token endpoint request body. + // These parameters will be URL-encoded and added to the request body along with the standard OAuth2 parameters. + // Refer to your authorization server's documentation for supported parameters. + message EndpointParameter { + // Parameter name. + string name = 1 [(validate.rules).string = {min_len: 1}]; + + // Parameter value. + string value = 2; + } + // Endpoint on the authorization server to retrieve the access token from. // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-3.2) for details. config.core.v3.HttpUri token_endpoint = 1 [(validate.rules).message = {required: true}]; @@ -73,4 +85,8 @@ message OAuth2 { // The interval must be at least 1 second. google.protobuf.Duration token_fetch_retry_interval = 4 [(validate.rules).duration = {gte {seconds: 1}}]; + + // Optional list of additional parameters to send to the token endpoint. + // These parameters will be URL-encoded and included in the token request body. + repeated EndpointParameter endpoint_params = 5; } diff --git a/src/main/proto/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto b/src/main/proto/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto index d1dd5f0..dcc594f 100644 --- a/src/main/proto/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto +++ b/src/main/proto/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto @@ -37,10 +37,40 @@ message XffConfig { // When the remote IP address matches a trusted CIDR and the // :ref:`config_http_conn_man_headers_x-forwarded-for` header was sent, each entry // in the ``x-forwarded-for`` header is evaluated from right to left and the first - // public non-trusted address is used as the original client address. If all + // non-trusted address is used as the original client address. If all // addresses in ``x-forwarded-for`` are within the trusted list, the first (leftmost) // entry is used. // + // .. warning:: + // + // Starting with Envoy v1.33.0, private IP address ranges are **not** automatically skipped + // when determining the original client address. We'll return the first address that is not + // in the ``xff_trusted_cidrs`` list, even if it is a private IP address. + // + // If you want to skip private IP addresses, explicitly add them to the ``xff_trusted_cidrs`` + // list. For example: + // + // .. code-block:: yaml + // + // xff_trusted_cidrs: + // cidrs: + // - address_prefix: "10.0.0.0" + // prefix_len: 8 + // - address_prefix: "172.16.0.0" + // prefix_len: 12 + // - address_prefix: "192.168.0.0" + // prefix_len: 16 + // - address_prefix: "127.0.0.0" + // prefix_len: 8 + // - address_prefix: "fc00::" + // prefix_len: 7 + // - address_prefix: "::1" + // prefix_len: 128 + // + // See :ref:`internal_address_config + // ` + // for more information about the v1.33.0 behavior change. + // // This is typically used when requests are proxied by a // `CDN `_. // diff --git a/src/main/proto/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto b/src/main/proto/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto index f913cb6..c55d30b 100644 --- a/src/main/proto/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto +++ b/src/main/proto/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package envoy.extensions.load_balancing_policies.client_side_weighted_round_robin.v3; +import "envoy/extensions/load_balancing_policies/common/v3/common.proto"; + import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; @@ -42,7 +44,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // See the :ref:`load balancing architecture // overview` for more information. // -// [#next-free-field: 8] +// [#next-free-field: 9] message ClientSideWeightedRoundRobin { // Whether to enable out-of-band utilization reporting collection from // the endpoints. By default, per-request utilization reporting is used. @@ -82,4 +84,8 @@ message ClientSideWeightedRoundRobin { // For map fields in the ORCA proto, the string will be of the form ``.``. For example, the string ``named_metrics.foo`` will mean to look for the key ``foo`` in the ORCA :ref:`named_metrics ` field. // If none of the specified metrics are present in the load report, then :ref:`cpu_utilization ` is used instead. repeated string metric_names_for_computing_utilization = 7; + + // Configuration for slow start mode. + // If this configuration is not set, slow start will not be not enabled. + common.v3.SlowStartConfig slow_start_config = 8; } diff --git a/src/main/proto/envoy/extensions/load_balancing_policies/common/v3/common.proto b/src/main/proto/envoy/extensions/load_balancing_policies/common/v3/common.proto index 3efea24..22faf11 100644 --- a/src/main/proto/envoy/extensions/load_balancing_policies/common/v3/common.proto +++ b/src/main/proto/envoy/extensions/load_balancing_policies/common/v3/common.proto @@ -24,8 +24,17 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; message LocalityLbConfig { // Configuration for :ref:`zone aware routing // `. - // [#next-free-field: 6] + // [#next-free-field: 7] message ZoneAwareLbConfig { + // Basis for computing per-locality percentages in zone-aware routing. + enum LocalityBasis { + // Use the number of healthy hosts in each locality. + HEALTHY_HOSTS_NUM = 0; + + // Use the weights of healthy hosts in each locality. + HEALTHY_HOSTS_WEIGHT = 1; + } + // Configures Envoy to always route requests to the local zone regardless of the // upstream zone structure. In Envoy's default configuration, traffic is distributed proportionally // across all upstream hosts while trying to maximize local routing when possible. The approach @@ -67,6 +76,12 @@ message LocalityLbConfig { [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; ForceLocalZone force_local_zone = 5; + + // Determines how locality percentages are computed: + // - HEALTHY_HOSTS_NUM: proportional to the count of healthy hosts. + // - HEALTHY_HOSTS_WEIGHT: proportional to the weights of healthy hosts. + // Default value is HEALTHY_HOSTS_NUM if unset. + LocalityBasis locality_basis = 6; } // Configuration for :ref:`locality weighted load balancing diff --git a/src/main/proto/envoy/extensions/load_balancing_policies/random_subsetting/v3/random_subsetting.proto b/src/main/proto/envoy/extensions/load_balancing_policies/random_subsetting/v3/random_subsetting.proto new file mode 100644 index 0000000..ce616be --- /dev/null +++ b/src/main/proto/envoy/extensions/load_balancing_policies/random_subsetting/v3/random_subsetting.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +package envoy.extensions.load_balancing_policies.random_subsetting.v3; + +import "envoy/config/cluster/v3/cluster.proto"; + +import "google/protobuf/wrappers.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.load_balancing_policies.random_subsetting.v3"; +option java_outer_classname = "RandomSubsettingProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/load_balancing_policies/random_subsetting/v3;random_subsettingv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Random Subsetting Load Balancing Policy] +// [#not-implemented-hide:] +// [#extension: envoy.load_balancing_policies.random_subsetting] +// [#next-free-field: 3] + +// Configuration for the Random Subsetting Load Balancing Policy +// +// This policy selects a subset of endpoints and passes them to the child LB policy. +// It maintains 2 important properties: +// 1. The policy tries to distribute connections among servers as equally as possible. The higher +// ``(N_clients*subset_size)/N_servers`` ratio is, the closer the resulting server connection +// distribution is to uniform. +// 2. The policy minimizes the amount of connection churn generated during server scale-ups by +// using rendezvous hashing +// +// See the :ref:`load balancing architecture +// overview` for more information. +// +// [#not-implemented-hide:] +message RandomSubsetting { + // subset_size indicates how many backends every client will be connected to. + // The value must be greater than 0. + google.protobuf.UInt32Value subset_size = 1 [(validate.rules).uint32 = {gt: 0}]; + + // The config for the child policy. + // The value is required. + config.cluster.v3.LoadBalancingPolicy child_policy = 2 + [(validate.rules).message = {required: true}]; +} diff --git a/src/main/proto/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto b/src/main/proto/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto index ab8367a..e2e4ade 100644 --- a/src/main/proto/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto +++ b/src/main/proto/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto @@ -14,7 +14,7 @@ option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/loa option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Weighted Round Robin Locality-Picking Load Balancing Policy] -// [#not-implemented-hide:] +// [#extension: envoy.load_balancing_policies.wrr_locality] // Configuration for the wrr_locality LB policy. See the :ref:`load balancing architecture overview // ` for more information. diff --git a/src/main/proto/envoy/extensions/local_address_selectors/filter_state_override/v3/config.proto b/src/main/proto/envoy/extensions/local_address_selectors/filter_state_override/v3/config.proto new file mode 100644 index 0000000..86dc67b --- /dev/null +++ b/src/main/proto/envoy/extensions/local_address_selectors/filter_state_override/v3/config.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package envoy.extensions.local_address_selectors.filter_state_override.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.local_address_selectors.filter_state_override.v3"; +option java_outer_classname = "ConfigProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/local_address_selectors/filter_state_override/v3;filter_state_overridev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Linux Network Namespace Local Address Selector] +// [#extension: envoy.upstream.local_address_selector.filter_state_override] + +// Overrides the upstream bind address Linux network namespace using a filter +// state object with the key ``envoy.network.upstream_bind_override.network_namespace`` +// passed from the downstream. The override applies over the :ref:`default +// address selector +// ` +message Config { +} diff --git a/src/main/proto/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto b/src/main/proto/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto index bea415a..b62690b 100644 --- a/src/main/proto/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto +++ b/src/main/proto/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto @@ -148,3 +148,17 @@ message DynamicMetadataInput { // The path to retrieve the Value from the Struct. repeated PathSegment path = 2 [(validate.rules).repeated = {min_items: 1}]; } + +// Input that matches by the network namespace of the listener address. +// This input returns the network namespace filepath that was used to create the listening socket. +// On Linux systems, this corresponds to the ``network_namespace_filepath`` field in the +// :ref:`SocketAddress ` configuration. +// +// .. note:: +// +// This input is only meaningful on Linux systems where network namespaces are supported. +// On other platforms, this input will always return an empty value. +// +// [#extension: envoy.matching.inputs.network_namespace] +message NetworkNamespaceInput { +} diff --git a/src/main/proto/envoy/extensions/matching/common_inputs/stats/v3/stats.proto b/src/main/proto/envoy/extensions/matching/common_inputs/stats/v3/stats.proto new file mode 100644 index 0000000..2db3a62 --- /dev/null +++ b/src/main/proto/envoy/extensions/matching/common_inputs/stats/v3/stats.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package envoy.extensions.matching.common_inputs.stats.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.matching.common_inputs.stats.v3"; +option java_outer_classname = "StatsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/common_inputs/stats/v3;statsv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Stats matcher] + +// Specifies the way to match stats with full name. +message StatFullNameMatchInput { +} diff --git a/src/main/proto/envoy/extensions/matching/common_inputs/transport_socket/v3/transport_socket_inputs.proto b/src/main/proto/envoy/extensions/matching/common_inputs/transport_socket/v3/transport_socket_inputs.proto new file mode 100644 index 0000000..9ddc1ab --- /dev/null +++ b/src/main/proto/envoy/extensions/matching/common_inputs/transport_socket/v3/transport_socket_inputs.proto @@ -0,0 +1,124 @@ +syntax = "proto3"; + +package envoy.extensions.matching.common_inputs.transport_socket.v3; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.matching.common_inputs.transport_socket.v3"; +option java_outer_classname = "TransportSocketInputsProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/matching/common_inputs/transport_socket/v3;transport_socketv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Transport Socket Matching Inputs] + +// Specifies that matching should be performed by the endpoint metadata. +// This input extracts metadata from the selected endpoint for transport socket selection. +// The metadata is extracted using a filter and path specification similar to +// :ref:`DynamicMetadataInput `. +// +// Example: Extract a metadata value for transport socket matching. +// +// .. code-block:: yaml +// +// typed_config: +// "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.transport_socket.v3.EndpointMetadataInput +// filter: "envoy.transport_socket_match" +// path: +// - key: "socket_type" +// +// This configuration extracts the value at path ``["envoy.transport_socket_match"]["socket_type"]`` +// from the endpoint metadata for use in transport socket selection. +// +// [#extension: envoy.matching.inputs.endpoint_metadata] +message EndpointMetadataInput { + // Specifies the segment in a path to retrieve value from Metadata. + // Note: Currently it's not supported to retrieve a value from a list in Metadata. This means that + // if the segment key refers to a list, it has to be the last segment in a path. + message PathSegment { + oneof segment { + option (validate.required) = true; + + // If specified, use the key to retrieve the value in a Struct. + string key = 1 [(validate.rules).string = {min_len: 1}]; + } + } + + // The filter name to retrieve the Struct from the endpoint metadata. + // If not specified, defaults to ``envoy.lb`` which is commonly used for load balancing metadata. + string filter = 1; + + // The path to retrieve the Value from the Struct. + repeated PathSegment path = 2 [(validate.rules).repeated = {min_items: 1}]; +} + +// Specifies that matching should be performed by the locality metadata. +// This input extracts metadata from the endpoint's locality for transport socket selection. +// The metadata is extracted using a filter and path specification similar to +// :ref:`DynamicMetadataInput `. +// +// Example: Extract a metadata value from locality for transport socket matching. +// +// .. code-block:: yaml +// +// typed_config: +// "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.transport_socket.v3.LocalityMetadataInput +// filter: "envoy.transport_socket_match" +// path: +// - key: "region" +// +// This configuration extracts the value at path ``["envoy.transport_socket_match"]["region"]`` +// from the locality metadata for use in transport socket selection. +// +// [#extension: envoy.matching.inputs.locality_metadata] +message LocalityMetadataInput { + // Specifies the segment in a path to retrieve value from Metadata. + // Note: Currently it's not supported to retrieve a value from a list in Metadata. This means that + // if the segment key refers to a list, it has to be the last segment in a path. + message PathSegment { + oneof segment { + option (validate.required) = true; + + // If specified, use the key to retrieve the value in a Struct. + string key = 1 [(validate.rules).string = {min_len: 1}]; + } + } + + // The filter name to retrieve the Struct from the locality metadata. + // If not specified, defaults to ``envoy.lb`` which is commonly used for load balancing metadata. + string filter = 1; + + // The path to retrieve the Value from the Struct. + repeated PathSegment path = 2 [(validate.rules).repeated = {min_items: 1}]; +} + +// Specifies that matching should be performed by filter state. +// This input extracts a value from filter state that was explicitly shared from the +// downstream connection to the upstream connection via ``TransportSocketOptions``. +// This enables flexible downstream-connection-based transport socket selection, +// such as matching on network namespace or any custom filter state data. +// +// Example: Match on network namespace stored in filter state. +// +// .. code-block:: yaml +// +// typed_config: +// "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.transport_socket.v3.FilterStateInput +// key: "envoy.network.namespace" +// +// [#extension: envoy.matching.inputs.transport_socket_filter_state] +message FilterStateInput { + // The key of the filter state object to retrieve. + // The object must implement serializeAsString() to be used for matching. + string key = 1 [(validate.rules).string = {min_len: 1}]; +} + +// Configuration for the transport socket name action. +// This action sets the name of the transport socket to use when the matcher matches. +// [#extension: envoy.matching.action.transport_socket.name] +message TransportSocketNameAction { + // The name of the transport socket to use. + // This name must reference a named transport socket in the cluster's transport_socket_matches. + string name = 1 [(validate.rules).string = {min_len: 1}]; +} diff --git a/src/main/proto/envoy/extensions/network/dns_resolver/cares/v3/cares_dns_resolver.proto b/src/main/proto/envoy/extensions/network/dns_resolver/cares/v3/cares_dns_resolver.proto index b36a3a0..d05d073 100644 --- a/src/main/proto/envoy/extensions/network/dns_resolver/cares/v3/cares_dns_resolver.proto +++ b/src/main/proto/envoy/extensions/network/dns_resolver/cares/v3/cares_dns_resolver.proto @@ -5,6 +5,7 @@ package envoy.extensions.network.dns_resolver.cares.v3; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/resolver.proto"; +import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; import "udpa/annotations/status.proto"; @@ -20,7 +21,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#extension: envoy.network.dns_resolver.cares] // Configuration for c-ares DNS resolver. -// [#next-free-field: 9] +// [#next-free-field: 12] message CaresDnsResolverConfig { // A list of DNS resolver addresses. // :ref:`use_resolvers_as_fallback ` @@ -77,4 +78,39 @@ message CaresDnsResolverConfig { // This setting overrides any system configuration for name server rotation. // bool rotate_nameservers = 8; + + // Maximum EDNS0 UDP payload size in bytes. + // If set, c-ares will include EDNS0 in DNS queries and use this value as the maximum UDP response size. + // + // Recommended values: + // + // * **1232**: Safe default (avoids fragmentation). + // * **4096**: Maximum allowed. + // + // If unset, c-ares uses its internal default (usually 1232). + google.protobuf.UInt32Value edns0_max_payload_size = 9 + [(validate.rules).uint32 = {lte: 4096 gte: 512}]; + + // The maximum duration for which a UDP channel will be kept alive before being refreshed. + // + // If set, the DNS resolver will periodically reinitialize its c-ares channel after the + // specified duration. This can help with avoiding stale socket states, and providing + // better load distribution across UDP ports. + // + // If not specified, no periodic refresh will be performed. + google.protobuf.Duration max_udp_channel_duration = 10 [(validate.rules).duration = {gte {}}]; + + // If true, reinitialize the c-ares channel when a DNS query fails with ``ARES_ETIMEOUT``. + // + // This can help recover from rare cases where the UDP sockets held by the c-ares + // channel become unusable after timeouts, causing subsequent queries to fail or + // Envoy to keep serving stale DNS results. When enabled, a timeout-triggered + // reinitialization attempts to restore healthy state quickly. In environments + // where timeouts are caused by intermittent network issues, enabling this may + // increase channel churn; consider using + // :ref:`max_udp_channel_duration ` + // for periodic refresh instead. + // + // Default is false. + bool reinit_channel_on_timeout = 11; } diff --git a/src/main/proto/envoy/extensions/quic/client_writer_factory/v3/default_client_writer.proto b/src/main/proto/envoy/extensions/quic/client_writer_factory/v3/default_client_writer.proto new file mode 100644 index 0000000..c43160e --- /dev/null +++ b/src/main/proto/envoy/extensions/quic/client_writer_factory/v3/default_client_writer.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package envoy.extensions.quic.client_writer_factory.v3; + +import "udpa/annotations/status.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.quic.client_writer_factory.v3"; +option java_outer_classname = "DefaultClientWriterProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/quic/client_writer_factory/v3;client_writer_factoryv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Default QUIC Client Packet Writer] +// [#extension: envoy.quic.packet_writer.default] + +// The default QUIC packet writer used for QUIC upstream connections which is platform independent. +message DefaultClientWriter { +} diff --git a/src/main/proto/envoy/extensions/quic/connection_id_generator/quic_lb/v3/quic_lb.proto b/src/main/proto/envoy/extensions/quic/connection_id_generator/quic_lb/v3/quic_lb.proto index 446ff95..fac2595 100644 --- a/src/main/proto/envoy/extensions/quic/connection_id_generator/quic_lb/v3/quic_lb.proto +++ b/src/main/proto/envoy/extensions/quic/connection_id_generator/quic_lb/v3/quic_lb.proto @@ -29,22 +29,23 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // // .. warning:: // -// This is still a work in progress. Performance is expected to be poor. Interoperability testing -// has not yet been performed. -// [#next-free-field: 6] +// This is still a work in progress. Interoperability testing has not yet been performed. +// [#next-free-field: 7] message Config { option (xds.annotations.v3.message_status).work_in_progress = true; - // Use the unencrypted mode. This is useful for testing, but allows for linking different CIDs - // for the same connection, and leaks information about the valid server IDs in use. This should - // only be used for testing. - bool unsafe_unencrypted_testing_mode = 1; - // Must be at least 1 octet. // The length of server_id and nonce_length_bytes must be 18 or less. // See https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers#name-server-id-allocation. config.core.v3.DataSource server_id = 2 [(validate.rules).message = {required: true}]; + // If true, indicates that the :ref:`server_id + // ` is base64 encoded. + // + // This can be useful if the ID may contain binary data and must be transmitted as a string, for example in + // an environment variable. + bool server_id_base64_encoded = 6; + // Optional validation of the expected server ID length. If this is non-zero and the value in ``server_id`` // does not have a matching length, a configuration error is generated. This can be useful for validating // that the server ID is valid. @@ -65,4 +66,14 @@ message Config { // See https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers#name-config-rotation. transport_sockets.tls.v3.SdsSecretConfig encryption_parameters = 5 [(validate.rules).message = {required: true}]; + + // Use the unencrypted mode. This is useful for testing or a simplified implementation of the + // downstream load balancer, but allows for linking different CIDs for the same connection, and + // leaks information about the valid server IDs in use. This mode does not comply with the RFC. + // + // Note that in this mode, :ref:`encryption_parameters + // ` + // is still required because it contains ``configuration_version``, which is still + // needed. ``encryption_key`` can be set to ``inline_string: '0000000000000000'``. + bool unencrypted_mode = 1; } diff --git a/src/main/proto/envoy/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto b/src/main/proto/envoy/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto index eb72322..9b29b01 100644 --- a/src/main/proto/envoy/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto +++ b/src/main/proto/envoy/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto @@ -2,10 +2,14 @@ syntax = "proto3"; package envoy.extensions.stat_sinks.open_telemetry.v3; +import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/grpc_service.proto"; import "google/protobuf/wrappers.proto"; +import "opentelemetry/proto/common/v1/common.proto"; +import "xds/type/matcher/v3/matcher.proto"; + import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -19,8 +23,24 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // Stats configuration proto schema for ``envoy.stat_sinks.open_telemetry`` sink. // [#extension: envoy.stat_sinks.open_telemetry] -// [#next-free-field: 7] +// [#next-free-field: 9] message SinkConfig { + // ConversionAction is used to convert a stat to a metric. If a stat matches, + // the metric_name and static_metric_labels will be + // used to create the metric. This can be used to rename a + // stat, add static labels, and aggregate multiple stats into a single metric. + message ConversionAction { + // The metric name to use for the stat. + string metric_name = 2; + + // Static metric labels to use for the metric. + repeated opentelemetry.proto.common.v1.KeyValue static_metric_labels = 3; + } + + // DropAction is an action that, when matched, will prevent the stat from being converted to an OTLP metric and flushed. + message DropAction { + } + oneof protocol_specifier { option (validate.required) = true; @@ -28,6 +48,10 @@ message SinkConfig { config.core.v3.GrpcService grpc_service = 1 [(validate.rules).message = {required: true}]; } + // Attributes to be associated with the resource in the OTLP message. + // [#extension-category: envoy.tracers.opentelemetry.resource_detectors] + repeated config.core.v3.TypedExtensionConfig resource_detectors = 7; + // If set to true, counters will be emitted as deltas, and the OTLP message will have // ``AGGREGATION_TEMPORALITY_DELTA`` set as AggregationTemporality. bool report_counters_as_deltas = 2; @@ -50,4 +74,12 @@ message SinkConfig { // "pre", the full stat name will be "pre.foo.bar". If this field is not set, there is no // prefix added. According to the example, the full stat name will remain "foo.bar". string prefix = 6; + + // The custom conversion from a stat to a metric. Currently, the only supported input is + // ``envoy.extensions.matching.common_inputs.stats.v3.StatFullNameMatchInput``. + // The supported actions are + // - ``envoy.extensions.stat_sinks.open_telemetry.v3.SinkConfig.DropAction``. + // - ``envoy.extensions.stat_sinks.open_telemetry.v3.SinkConfig.ConversionAction``. + // If stats are not matched, they will be directly converted to OTLP metrics as usual. + xds.type.matcher.v3.Matcher custom_metric_conversions = 8; } diff --git a/src/main/proto/envoy/extensions/transport_sockets/quic/v3/quic_transport.proto b/src/main/proto/envoy/extensions/transport_sockets/quic/v3/quic_transport.proto index 585da76..9756ff5 100644 --- a/src/main/proto/envoy/extensions/transport_sockets/quic/v3/quic_transport.proto +++ b/src/main/proto/envoy/extensions/transport_sockets/quic/v3/quic_transport.proto @@ -16,7 +16,8 @@ option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/tra option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: quic transport] -// [#comment:#extension: envoy.transport_sockets.quic] +// [#extension: envoy.transport_sockets.quic] +// The QUIC configurations below provide the transport socket configuration for downstream/upstream QUIC. // Configuration for Downstream QUIC transport socket. This provides Google's implementation of Google QUIC and IETF QUIC to Envoy. message QuicDownstreamTransport { diff --git a/src/main/proto/envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3/config.proto b/src/main/proto/envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3/config.proto new file mode 100644 index 0000000..e39abd2 --- /dev/null +++ b/src/main/proto/envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3/config.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package envoy.extensions.transport_sockets.tls.cert_mappers.sni.v3; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.transport_sockets.tls.cert_mappers.sni.v3"; +option java_outer_classname = "ConfigProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/cert_mappers/sni/v3;sniv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: SNI certificate mapper] +// [#extension: envoy.tls.certificate_mappers.sni] + +// Uses the SNI value from the TLS client hello as the secret resource name. +message SNI { + // The value to use as the secret name when SNI is empty or absent. + string default_value = 1 [(validate.rules).string = {min_len: 1}]; +} diff --git a/src/main/proto/envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3/config.proto b/src/main/proto/envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3/config.proto new file mode 100644 index 0000000..0fbd87f --- /dev/null +++ b/src/main/proto/envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3/config.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package envoy.extensions.transport_sockets.tls.cert_mappers.static_name.v3; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.transport_sockets.tls.cert_mappers.static_name.v3"; +option java_outer_classname = "ConfigProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/cert_mappers/static_name/v3;static_namev3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Static secret certificate mapper] +// [#extension: envoy.tls.certificate_mappers.static_name] + +// A mapping to a fixed secret name for all certificates. +message StaticName { + // The name for the secret to use for all connections. + string name = 1 [(validate.rules).string = {min_len: 1}]; +} diff --git a/src/main/proto/envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3/config.proto b/src/main/proto/envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3/config.proto new file mode 100644 index 0000000..97d26e8 --- /dev/null +++ b/src/main/proto/envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3/config.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package envoy.extensions.transport_sockets.tls.cert_selectors.on_demand_secret.v3; + +import "envoy/config/core/v3/config_source.proto"; +import "envoy/config/core/v3/extension.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.transport_sockets.tls.cert_selectors.on_demand_secret.v3"; +option java_outer_classname = "ConfigProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/cert_selectors/on_demand_secret/v3;on_demand_secretv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: On-demand secret certificate selector] +// [#extension: envoy.tls.certificate_selectors.on_demand_secret] + +// Fetches the secret on-demand while allowing the parent cluster or listener to accept connections +// without warming. During the handshake, a secret name is derived from the peer hello message, an +// SDS resource request starts, and the handshake is paused. Once an SDS response is received with a +// resource, the handshake is resumed with the provided certificate. If the SDS server indicates the +// resource removal, the handshake is failed, and the SDS subscription to the resource is stopped. +// +// Similar to the regular SDS, the certificate is configured using the outer common TLS context, +// e.g. by setting the FIPS compliance policy on the loaded certificate. +message Config { + // Defines the configuration source of the secrets. + config.core.v3.ConfigSource config_source = 1 [(validate.rules).message = {required: true}]; + + // Extension point to specify a function to compute the secret name. The extension is called + // during the TLS handshake after receiving the "CLIENT HELLO" message from the client. + // [#extension-category: envoy.tls.certificate_mappers] + config.core.v3.TypedExtensionConfig certificate_mapper = 2 + [(validate.rules).message = {required: true}]; + + // A list of secret resource names to start fetching on configuration load (prior to receiving any + // requests). The parent resource initializes immediately without waiting for the fetch to + // complete. + repeated string prefetch_secret_names = 3; +} diff --git a/src/main/proto/envoy/extensions/transport_sockets/tls/v3/tls.proto b/src/main/proto/envoy/extensions/transport_sockets/tls/v3/tls.proto index b292b18..d656c66 100644 --- a/src/main/proto/envoy/extensions/transport_sockets/tls/v3/tls.proto +++ b/src/main/proto/envoy/extensions/transport_sockets/tls/v3/tls.proto @@ -300,6 +300,7 @@ message CommonTlsContext { // Select TLS certificate based on TLS client hello. // If empty, defaults to native TLS certificate selection behavior: // DNS SANs or Subject Common Name in TLS certificates is extracted as server name pattern to match SNI. + // [#extension-category: envoy.tls.certificate_selectors] config.core.v3.TypedExtensionConfig custom_tls_certificate_selector = 16; // Certificate provider for fetching TLS certificates. diff --git a/src/main/proto/envoy/extensions/upstreams/http/v3/http_protocol_options.proto b/src/main/proto/envoy/extensions/upstreams/http/v3/http_protocol_options.proto index ff90cdd..03f0158 100644 --- a/src/main/proto/envoy/extensions/upstreams/http/v3/http_protocol_options.proto +++ b/src/main/proto/envoy/extensions/upstreams/http/v3/http_protocol_options.proto @@ -2,8 +2,10 @@ syntax = "proto3"; package envoy.extensions.upstreams.http.v3; +import "envoy/config/common/matcher/v3/matcher.proto"; import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/protocol.proto"; +import "envoy/config/route/v3/route_components.proto"; import "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto"; import "udpa/annotations/status.proto"; @@ -59,7 +61,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // http2_protocol_options: // max_concurrent_streams: 100 // .... [further cluster config] -// [#next-free-field: 8] +// [#next-free-field: 12] message HttpProtocolOptions { // If this is used, the cluster will only operate on one of the possible upstream protocols. // Note that HTTP/2 or above should generally be used for upstream gRPC clusters. @@ -129,6 +131,13 @@ message HttpProtocolOptions { config.core.v3.AlternateProtocolsCacheOptions alternate_protocols_cache_options = 4; } + message OutlierDetection { + // If specified, only responses matching the matcher will be treated by outlier detection as errors. + // If not specified, only 5xx codes are treated by outlier detection as errors. + config.common.matcher.v3.MatchPredicate error_matcher = 1 + [(validate.rules).message = {required: true}]; + } + // This contains options common across HTTP/1 and HTTP/2 config.core.v3.HttpProtocolOptions common_http_protocol_options = 1; @@ -174,4 +183,41 @@ message HttpProtocolOptions { // [#not-implemented-hide:] // [#extension-category: envoy.http.header_validators] config.core.v3.TypedExtensionConfig header_validation_config = 7; + + // Defines http specific outlier detection parameters. + OutlierDetection outlier_detection = 8; + + // Specifies a list of HTTP-level mirroring policies for requests routed to this cluster. + // Cluster-level policies override route-level policies when they both are configured. + // + // .. note:: + // + // Mirroring will not be triggered if the :ref:`primary cluster + // ` does not exist. + repeated config.route.v3.RouteAction.RequestMirrorPolicy request_mirror_policies = 9; + + // Specifies a list of hash policies for consistent hashing load balancing (e.g., Ring Hash or + // Maglev) for requests routed to this cluster. When configured, cluster-level policies override + // route-level policies. When not configured, route-level policies (if any) will be used. + // + // This enables consistent routing to the same upstream host for all requests to a cluster, + // which is particularly useful for stateful services like caching, session management, or + // sticky routing requirements. + // + // .. note:: + // + // Hash policies are only effective when the cluster is configured with a hash-based load + // balancing policy (e.g., :ref:`RING_HASH ` + // or :ref:`MAGLEV `). + repeated config.route.v3.RouteAction.HashPolicy hash_policy = 10; + + // Specifies the retry policy for requests routed to this cluster. When configured, + // cluster-level retry policy overrides route-level retry policy. When not configured, + // route-level retry policy (if any) will be used. + // + // .. note:: + // + // Cluster-level retry policy will override route-level retry policy entirely. Policies are + // not merged. + config.route.v3.RetryPolicy retry_policy = 11; } diff --git a/src/main/proto/envoy/service/auth/v3/external_auth.proto b/src/main/proto/envoy/service/auth/v3/external_auth.proto index 1f3ed57..520a4ff 100644 --- a/src/main/proto/envoy/service/auth/v3/external_auth.proto +++ b/src/main/proto/envoy/service/auth/v3/external_auth.proto @@ -114,6 +114,7 @@ message OkHttpResponse { } // Intended for gRPC and Network Authorization servers ``only``. +// [#next-free-field: 6] message CheckResponse { option (udpa.annotations.versioning).previous_message_type = "envoy.service.auth.v2.CheckResponse"; @@ -132,6 +133,18 @@ message CheckResponse { // Supplies http attributes for an ok response. OkHttpResponse ok_response = 3; + + // Supplies http attributes for an error response. This is used when the authorization + // service encounters an internal error and wants to return custom headers and body to the + // downstream client. When ``error_response`` is set, the ext_authz filter increments the + // ``ext_authz_error`` stat and respects the :ref:`failure_mode_allow + // ` + // configuration. The HTTP status code, headers, and body are taken from the + // :ref:`DeniedHttpResponse ` message. + // If the status field is not set, Envoy sends the status code configured via + // :ref:`status_on_error `, + // which defaults to ``403 Forbidden``. + DeniedHttpResponse error_response = 5; } // Optional response metadata that will be emitted as dynamic metadata to be consumed by the next diff --git a/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto b/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto index e77d60d..1c033c0 100644 --- a/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto +++ b/src/main/proto/envoy/service/ext_proc/v3/external_processor.proto @@ -27,29 +27,31 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // as part of a filter chain. // The overall external processing protocol works like this: // -// 1. Envoy sends to the service information about the HTTP request. -// 2. The service sends back a ProcessingResponse message that directs Envoy -// to either stop processing, continue without it, or send it the -// next chunk of the message body. -// 3. If so requested, Envoy sends the server the message body in chunks, -// or the entire body at once. In either case, the server may send back -// a ProcessingResponse for each message it receives, or wait for certain amount -// of body chunks received before streams back the ProcessingResponse messages. -// 4. If so requested, Envoy sends the server the HTTP trailers, +// 1. The data plane sends to the service information about the HTTP request. +// 2. The service sends back a ProcessingResponse message that directs +// the data plane to either stop processing, continue without it, or send +// it the next chunk of the message body. +// 3. If so requested, the data plane sends the server the message body in +// chunks, or the entire body at once. In either case, the server may send +// back a ProcessingResponse for each message it receives, or wait for +// a certain amount of body chunks received before streaming back the +// ProcessingResponse messages. +// 4. If so requested, the data plane sends the server the HTTP trailers, // and the server sends back a ProcessingResponse. // 5. At this point, request processing is done, and we pick up again -// at step 1 when Envoy receives a response from the upstream server. +// at step 1 when the data plane receives a response from the upstream +// server. // 6. At any point above, if the server closes the gRPC stream cleanly, -// then Envoy proceeds without consulting the server. +// then the data plane proceeds without consulting the server. // 7. At any point above, if the server closes the gRPC stream with an error, -// then Envoy returns a 500 error to the client, unless the filter +// then the data plane returns a 500 error to the client, unless the filter // was configured to ignore errors. // // In other words, the process is a request/response conversation, but // using a gRPC stream to make it easier for the server to // maintain state. service ExternalProcessor { - // This begins the bidirectional stream that Envoy will use to + // This begins the bidirectional stream that the data plane will use to // give the server control over what the filter does. The actual // protocol is described by the ProcessingRequest and ProcessingResponse // messages below. @@ -79,7 +81,7 @@ message ProtocolConfiguration { bool send_body_without_waiting_for_header_response = 3; } -// This represents the different types of messages that Envoy can send +// This represents the different types of messages that the data plane can send // to an external processing server. // [#next-free-field: 12] message ProcessingRequest { @@ -132,7 +134,7 @@ message ProcessingRequest { // The values of properties selected by the ``request_attributes`` // or ``response_attributes`` list in the configuration. Each entry // in the list is populated from the standard - // :ref:`attributes ` supported across Envoy. + // :ref:`attributes ` supported in the data plane. map attributes = 9; // Specify whether the filter that sent this request is running in :ref:`observability_mode @@ -153,7 +155,7 @@ message ProcessingRequest { ProtocolConfiguration protocol_config = 11; } -// This represents the different types of messages the server may send back to Envoy +// This represents the different types of messages the server may send back to the data plane // when the ``observability_mode`` field in the received ProcessingRequest is set to false. // // * If the corresponding ``BodySendMode`` in the @@ -162,7 +164,7 @@ message ProcessingRequest { // the server must send back exactly one ProcessingResponse message. // * If it is set to ``FULL_DUPLEX_STREAMED``, the server must follow the API defined // for this mode to send the ProcessingResponse messages. -// [#next-free-field: 11] +// [#next-free-field: 13] message ProcessingResponse { // The response type that is sent by the server. oneof response { @@ -200,6 +202,20 @@ message ProcessingResponse { // this will either ship the reply directly to the downstream codec, // or reset the stream. ImmediateResponse immediate_response = 7; + + // The server sends back this message to initiate or continue local response streaming. + // The server must initiate local response streaming with the ``headers_response`` in response to a ProcessingRequest + // with the ``request_headers`` only. + // The server may follow up with multiple messages containing ``body_response``. The server must indicate + // end of stream by setting ``end_of_stream`` to ``true`` in the ``headers_response`` + // or ``body_response`` message or by sending a ``trailers_response`` message. + // The client may send a ``request_body`` or ``request_trailers`` to the server depending on configuration. + // The streaming local response can only be sent when the ``request_header_mode`` in the filter + // :ref:`processing_mode ` + // is set to ``SEND``. The ext_proc server should not send StreamedImmediateResponse if it did not observe request headers, + // as it will result in the race with the upstream server response and reset of the client request. + // Presently only the FULL_DUPLEX_STREAMED or NONE body modes are supported. + StreamedImmediateResponse streamed_immediate_response = 11; } // Optional metadata that will be emitted as dynamic metadata to be consumed by @@ -212,8 +228,8 @@ message ProcessingResponse { // may use this to intelligently control how requests are processed // based on the headers and other metadata that they see. // This field is only applicable when servers responding to the header requests. - // If it is set in the response to the body or trailer requests, it will be ignored by Envoy. - // It is also ignored by Envoy when the ext_proc filter config + // If it is set in the response to the body or trailer requests, it will be ignored by the data plane. + // It is also ignored by the data plane when the ext_proc filter config // :ref:`allow_mode_override // ` // is set to false, or @@ -222,18 +238,31 @@ message ProcessingResponse { // is set to true. envoy.extensions.filters.http.ext_proc.v3.ProcessingMode mode_override = 9; + // [#not-implemented-hide:] + // Used only in ``FULL_DUPLEX_STREAMED`` and ``GRPC`` body send modes. + // Instructs the data plane to stop sending body data and to send a + // half-close on the ext_proc stream. The ext_proc server should then echo + // back all subsequent body contents as-is until it sees the client's + // half-close, at which point the ext_proc server can terminate the stream + // with an OK status. This provides a safe way for the ext_proc server + // to indicate that it does not need to see the rest of the stream; + // without this, the ext_proc server could not terminate the stream + // early, because it would wind up dropping any body contents that the + // client had already sent before it saw the ext_proc stream termination. + bool request_drain = 12; + // When ext_proc server receives a request message, in case it needs more // time to process the message, it sends back a ProcessingResponse message - // with a new timeout value. When Envoy receives this response message, - // it ignores other fields in the response, just stop the original timer, - // which has the timeout value specified in + // with a new timeout value. When the data plane receives this response + // message, it ignores other fields in the response, just stop the original + // timer, which has the timeout value specified in // :ref:`message_timeout // ` // and start a new timer with this ``override_message_timeout`` value and keep the - // Envoy ext_proc filter state machine intact. + // data plane ext_proc filter state machine intact. // Has to be >= 1ms and <= // :ref:`max_message_timeout ` - // Such message can be sent at most once in a particular Envoy ext_proc filter processing state. + // Such message can be sent at most once in a particular data plane ext_proc filter processing state. // To enable this API, one has to set ``max_message_timeout`` to a number >= 1ms. google.protobuf.Duration override_message_timeout = 10; } @@ -266,11 +295,27 @@ message HttpHeaders { message HttpBody { // The contents of the body in the HTTP request/response. Note that in // streaming mode multiple ``HttpBody`` messages may be sent. + // + // In ``GRPC`` body send mode, a separate ``HttpBody`` message will be + // sent for each message in the gRPC stream. bytes body = 1; // If ``true``, this will be the last ``HttpBody`` message that will be sent and no // trailers will be sent for the current request/response. bool end_of_stream = 2; + + // This field is used in ``GRPC`` body send mode when ``end_of_stream`` is + // true and ``body`` is empty. Those values would normally indicate an + // empty message on the stream with the end-of-stream bit set. + // However, if the half-close happens after the last message on the + // stream was already sent, then this field will be true to indicate an + // end-of-stream with *no* message (as opposed to an empty message). + bool end_of_stream_without_message = 3; + + // This field is used in ``GRPC`` body send mode to indicate whether + // the message is compressed. This will never be set to true by gRPC + // but may be set to true by a proxy like Envoy. + bool grpc_message_compressed = 4; } // This message is sent to the external server when the HTTP request and @@ -283,30 +328,47 @@ message HttpTrailers { // The following are messages that may be sent back by the server. -// This message is sent by the external server to Envoy after ``HttpHeaders`` was +// This message is sent by the external server to the data plane after ``HttpHeaders`` was // sent to it. message HeadersResponse { - // Details the modifications (if any) to be made by Envoy to the current + // Details the modifications (if any) to be made by the data plane to the current // request/response. CommonResponse response = 1; } -// This message is sent by the external server to Envoy after ``HttpBody`` was +// This message is sent by the external server to the data plane after ``HttpBody`` was // sent to it. message BodyResponse { - // Details the modifications (if any) to be made by Envoy to the current + // Details the modifications (if any) to be made by the data plane to the current // request/response. CommonResponse response = 1; } -// This message is sent by the external server to Envoy after ``HttpTrailers`` was +// This message is sent by the external server to the data plane after ``HttpTrailers`` was // sent to it. message TrailersResponse { - // Details the modifications (if any) to be made by Envoy to the current + // Details the modifications (if any) to be made by the data plane to the current // request/response trailers. HeaderMutation header_mutation = 1; } +// This message is sent by the external server to the data plane after ``HttpHeaders`` +// to initiate local response streaming. The server may follow up with multiple messages containing ``body_response``. +// The server must indicate end of stream by setting ``end_of_stream`` to ``true`` in the ``headers_response`` +// or ``body_response`` message or by sending a ``trailers_response`` message. +message StreamedImmediateResponse { + oneof response { + // Response headers to be sent downstream. The ":status" header must be set. + HttpHeaders headers_response = 1; + + // Response body to be sent downstream. + StreamedBodyResponse body_response = 2; + + // Response trailers to be sent downstream. + config.core.v3.HeaderMap trailers_response = 3; + } +} + // This message contains common fields between header and body responses. // [#next-free-field: 6] message CommonResponse { @@ -329,10 +391,12 @@ message CommonResponse { // // In other words, this response makes it possible to turn an HTTP GET // into a POST, PUT, or PATCH. + // + // Not supported if the body send mode is ``GRPC``. CONTINUE_AND_REPLACE = 1; } - // If set, provide additional direction on how the Envoy proxy should + // If set, provide additional direction on how the data plane should // handle the rest of the HTTP filter chain. ResponseStatus status = 1 [(validate.rules).enum = {defined_only: true}]; @@ -361,7 +425,7 @@ message CommonResponse { // Clear the route cache for the current client request. This is necessary // if the remote server modified headers that are used to calculate the route. // This field is ignored in the response direction. This field is also ignored - // if the Envoy ext_proc filter is in the upstream filter chain. + // if the data plane ext_proc filter is in the upstream filter chain. bool clear_route_cache = 5; } @@ -413,37 +477,56 @@ message HeaderMutation { repeated string remove_headers = 2; } -// The body response message corresponding to FULL_DUPLEX_STREAMED body mode. +// The body response message corresponding to ``FULL_DUPLEX_STREAMED`` or ``GRPC`` body modes. message StreamedBodyResponse { - // The body response chunk that will be passed to the upstream/downstream by Envoy. + // In ``FULL_DUPLEX_STREAMED`` body send mode, contains the body response chunk that will be + // passed to the upstream/downstream by the data plane. In ``GRPC`` body send mode, contains + // a serialized gRPC message to be passed to the upstream/downstream by the data plane. bytes body = 1; // The server sets this flag to true if it has received a body request with // :ref:`end_of_stream ` set to true, // and this is the last chunk of body responses. + // Note that in ``GRPC`` body send mode, this allows the ext_proc + // server to tell the data plane to send a half close after a client + // message, which will result in discarding any other messages sent by + // the client application. bool end_of_stream = 2; + + // This field is used in ``GRPC`` body send mode when ``end_of_stream`` is + // true and ``body`` is empty. Those values would normally indicate an + // empty message on the stream with the end-of-stream bit set. + // However, if the half-close happens after the last message on the + // stream was already sent, then this field will be true to indicate an + // end-of-stream with *no* message (as opposed to an empty message). + bool end_of_stream_without_message = 3; + + // This field is used in ``GRPC`` body send mode to indicate whether + // the message is compressed. This will never be set to true by gRPC + // but may be set to true by a proxy like Envoy. + bool grpc_message_compressed = 4; } -// This message specifies the body mutation the server sends to Envoy. +// This message specifies the body mutation the server sends to the data plane. message BodyMutation { // The type of mutation for the body. oneof mutation { // The entire body to replace. // Should only be used when the corresponding ``BodySendMode`` in the // :ref:`processing_mode ` - // is not set to ``FULL_DUPLEX_STREAMED``. + // is not set to ``FULL_DUPLEX_STREAMED`` or ``GRPC``. bytes body = 1; // Clear the corresponding body chunk. // Should only be used when the corresponding ``BodySendMode`` in the // :ref:`processing_mode ` - // is not set to ``FULL_DUPLEX_STREAMED``. + // is not set to ``FULL_DUPLEX_STREAMED`` or ``GRPC``. // Clear the corresponding body chunk. bool clear_body = 2; // Must be used when the corresponding ``BodySendMode`` in the // :ref:`processing_mode ` - // is set to ``FULL_DUPLEX_STREAMED``. + // is set to ``FULL_DUPLEX_STREAMED`` or ``GRPC``. StreamedBodyResponse streamed_response = 3 [(xds.annotations.v3.field_status).work_in_progress = true]; } diff --git a/src/main/proto/envoy/type/matcher/v3/value.proto b/src/main/proto/envoy/type/matcher/v3/value.proto index d773c60..8d65c45 100644 --- a/src/main/proto/envoy/type/matcher/v3/value.proto +++ b/src/main/proto/envoy/type/matcher/v3/value.proto @@ -17,7 +17,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Value matcher] -// Specifies the way to match a ProtobufWkt::Value. Primitive values and ListValue are supported. +// Specifies the way to match a Protobuf::Value. Primitive values and ListValue are supported. // StructValue is not supported and is always not matched. // [#next-free-field: 8] message ValueMatcher { diff --git a/src/main/proto/envoy/type/matcher/value.proto b/src/main/proto/envoy/type/matcher/value.proto index 89d341b..6452fce 100644 --- a/src/main/proto/envoy/type/matcher/value.proto +++ b/src/main/proto/envoy/type/matcher/value.proto @@ -16,7 +16,7 @@ option (udpa.annotations.file_status).package_version_status = FROZEN; // [#protodoc-title: Value matcher] -// Specifies the way to match a ProtobufWkt::Value. Primitive values and ListValue are supported. +// Specifies the way to match a Protobuf::Value. Primitive values and ListValue are supported. // StructValue is not supported and is always not matched. // [#next-free-field: 7] message ValueMatcher { diff --git a/src/main/proto/envoy/type/tracing/v3/custom_tag.proto b/src/main/proto/envoy/type/tracing/v3/custom_tag.proto index feb57e8..cdb42a4 100644 --- a/src/main/proto/envoy/type/tracing/v3/custom_tag.proto +++ b/src/main/proto/envoy/type/tracing/v3/custom_tag.proto @@ -17,7 +17,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom Tag] // Describes custom tags for the active span. -// [#next-free-field: 6] +// [#next-free-field: 7] message CustomTag { option (udpa.annotations.versioning).previous_message_type = "envoy.type.tracing.v2.CustomTag"; @@ -98,5 +98,12 @@ message CustomTag { // A custom tag to obtain tag value from the metadata. Metadata metadata = 5; + + // Custom tag value. + // + // The same :ref:`format specifier ` as used for + // :ref:`HTTP access logging ` applies here, however + // unknown specifier values are replaced with the empty string instead of ``-``. + string value = 6; } } diff --git a/src/main/proto/opentelemetry/proto/common/v1/common.proto b/src/main/proto/opentelemetry/proto/common/v1/common.proto index 57c9f86..7f9ffab 100644 --- a/src/main/proto/opentelemetry/proto/common/v1/common.proto +++ b/src/main/proto/opentelemetry/proto/common/v1/common.proto @@ -22,7 +22,7 @@ option java_package = "io.opentelemetry.proto.common.v1"; option java_outer_classname = "CommonProto"; option go_package = "go.opentelemetry.io/proto/otlp/common/v1"; -// AnyValue is used to represent any type of attribute value. AnyValue may contain a +// Represents any type of attribute value. AnyValue may contain a // primitive value such as a string or integer or it may contain an arbitrary nested // object containing arrays, key-value lists and primitives. message AnyValue { @@ -54,29 +54,43 @@ message ArrayValue { message KeyValueList { // A collection of key/value pairs of key-value pairs. The list may be empty (may // contain 0 elements). + // // The keys MUST be unique (it is not allowed to have more than one // value with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated KeyValue values = 1; } -// KeyValue is a key-value pair that is used to store Span attributes, Link +// Represents a key-value pair that is used to store Span attributes, Link // attributes, etc. message KeyValue { + // The key name of the pair. string key = 1; + + // The value of the pair. AnyValue value = 2; } // InstrumentationScope is a message representing the instrumentation scope information // such as the fully qualified name and version. message InstrumentationScope { + // A name denoting the Instrumentation scope. // An empty instrumentation scope name means the name is unknown. string name = 1; + + // Defines the version of the instrumentation scope. + // An empty instrumentation scope version means the version is unknown. string version = 2; // Additional attributes that describe the scope. [Optional]. // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated KeyValue attributes = 3; + + // The number of attributes that were discarded. Attributes + // can be discarded because their keys are too long or because there are too many + // attributes. If this value is 0, then no attributes were dropped. uint32 dropped_attributes_count = 4; } diff --git a/src/main/proto/opentelemetry/proto/logs/v1/logs.proto b/src/main/proto/opentelemetry/proto/logs/v1/logs.proto index 4fe1130..842c93c 100644 --- a/src/main/proto/opentelemetry/proto/logs/v1/logs.proto +++ b/src/main/proto/opentelemetry/proto/logs/v1/logs.proto @@ -78,7 +78,8 @@ message ScopeLogs { // is recorded in. Notably, the last part of the URL path is the version number of the // schema: http[s]://server[:port]/path/. To learn more about Schema URL see // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - // This schema_url applies to all logs in the "logs" field. + // This schema_url applies to the data in the "scope" field and all logs in the + // "log_records" field. string schema_url = 3; } @@ -174,6 +175,7 @@ message LogRecord { // Additional attributes that describe the specific event occurrence. [Optional]. // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 6; uint32 dropped_attributes_count = 7; diff --git a/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto b/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto index a42e51a..a6fab4e 100644 --- a/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto +++ b/src/main/proto/opentelemetry/proto/metrics/v1/metrics.proto @@ -96,7 +96,8 @@ message ScopeMetrics { // is recorded in. Notably, the last part of the URL path is the version number of the // schema: http[s]://server[:port]/path/. To learn more about Schema URL see // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - // This schema_url applies to all metrics in the "metrics" field. + // This schema_url applies to the data in the "scope" field and all metrics in the + // "metrics" field. string schema_url = 3; } @@ -187,13 +188,13 @@ message ScopeMetrics { message Metric { reserved 4, 6, 8; - // name of the metric. + // The name of the metric. string name = 1; - // description of the metric, which can be used in documentation. + // A description of the metric, which can be used in documentation. string description = 2; - // unit in which the metric value is reported. Follows the format + // The unit in which the metric value is reported. Follows the format // described by https://unitsofmeasure.org/ucum.html. string unit = 3; @@ -215,6 +216,7 @@ message Metric { // for lossless roundtrip translation to / from another data model. // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue metadata = 12; } @@ -228,25 +230,31 @@ message Metric { // AggregationTemporality is not included. Consequently, this also means // "StartTimeUnixNano" is ignored for all data points. message Gauge { + // The time series data points. + // Note: Multiple time series may be included (same timestamp, different attributes). repeated NumberDataPoint data_points = 1; } // Sum represents the type of a scalar metric that is calculated as a sum of all // reported measurements over a time interval. message Sum { + // The time series data points. + // Note: Multiple time series may be included (same timestamp, different attributes). repeated NumberDataPoint data_points = 1; // aggregation_temporality describes if the aggregator reports delta changes // since last report time, or cumulative changes since a fixed start time. AggregationTemporality aggregation_temporality = 2; - // If "true" means that the sum is monotonic. + // Represents whether the sum is monotonic. bool is_monotonic = 3; } // Histogram represents the type of a metric that is calculated by aggregating // as a Histogram of all reported measurements over a time interval. message Histogram { + // The time series data points. + // Note: Multiple time series may be included (same timestamp, different attributes). repeated HistogramDataPoint data_points = 1; // aggregation_temporality describes if the aggregator reports delta changes @@ -257,6 +265,8 @@ message Histogram { // ExponentialHistogram represents the type of a metric that is calculated by aggregating // as a ExponentialHistogram of all reported double measurements over a time interval. message ExponentialHistogram { + // The time series data points. + // Note: Multiple time series may be included (same timestamp, different attributes). repeated ExponentialHistogramDataPoint data_points = 1; // aggregation_temporality describes if the aggregator reports delta changes @@ -274,6 +284,8 @@ message ExponentialHistogram { // because the count and sum fields of a SummaryDataPoint are assumed to be // cumulative values. message Summary { + // The time series data points. + // Note: Multiple time series may be included (same timestamp, different attributes). repeated SummaryDataPoint data_points = 1; } @@ -377,6 +389,7 @@ message NumberDataPoint { // where this point belongs. The list may be empty (may contain 0 elements). // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 7; // StartTimeUnixNano is optional but strongly encouraged, see the @@ -425,6 +438,7 @@ message HistogramDataPoint { // where this point belongs. The list may be empty (may contain 0 elements). // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 9; // StartTimeUnixNano is optional but strongly encouraged, see the @@ -509,6 +523,7 @@ message ExponentialHistogramDataPoint { // where this point belongs. The list may be empty (may contain 0 elements). // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 1; // StartTimeUnixNano is optional but strongly encouraged, see the @@ -524,12 +539,12 @@ message ExponentialHistogramDataPoint { // 1970. fixed64 time_unix_nano = 3; - // count is the number of values in the population. Must be + // The number of values in the population. Must be // non-negative. This value must be equal to the sum of the "bucket_counts" // values in the positive and negative Buckets plus the "zero_count" field. fixed64 count = 4; - // sum of the values in the population. If count is zero then this field + // The sum of the values in the population. If count is zero then this field // must be zero. // // Note: Sum should only be filled out when measuring non-negative discrete @@ -556,7 +571,7 @@ message ExponentialHistogramDataPoint { // values depend on the range of the data. sint32 scale = 6; - // zero_count is the count of values that are either exactly zero or + // The count of values that are either exactly zero or // within the region considered zero by the instrumentation at the // tolerated degree of precision. This bucket stores values that // cannot be expressed using the standard exponential formula as @@ -575,12 +590,12 @@ message ExponentialHistogramDataPoint { // Buckets are a set of bucket counts, encoded in a contiguous array // of counts. message Buckets { - // Offset is the bucket index of the first entry in the bucket_counts array. + // The bucket index of the first entry in the bucket_counts array. // // Note: This uses a varint encoding as a simple form of compression. sint32 offset = 1; - // bucket_counts is an array of count values, where bucket_counts[i] carries + // An array of count values, where bucket_counts[i] carries // the count of the bucket at index (offset+i). bucket_counts[i] is the count // of values greater than base^(offset+i) and less than or equal to // base^(offset+i+1). @@ -600,10 +615,10 @@ message ExponentialHistogramDataPoint { // measurements that were used to form the data point repeated Exemplar exemplars = 11; - // min is the minimum value over (start_time, end_time]. + // The minimum value over (start_time, end_time]. optional double min = 12; - // max is the maximum value over (start_time, end_time]. + // The maximum value over (start_time, end_time]. optional double max = 13; // ZeroThreshold may be optionally set to convey the width of the zero @@ -625,6 +640,7 @@ message SummaryDataPoint { // where this point belongs. The list may be empty (may contain 0 elements). // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 7; // StartTimeUnixNano is optional but strongly encouraged, see the diff --git a/src/main/proto/opentelemetry/proto/profiles/v1development/profiles.proto b/src/main/proto/opentelemetry/proto/profiles/v1development/profiles.proto index ff03815..a6af56d 100644 --- a/src/main/proto/opentelemetry/proto/profiles/v1development/profiles.proto +++ b/src/main/proto/opentelemetry/proto/profiles/v1development/profiles.proto @@ -59,7 +59,7 @@ option go_package = "go.opentelemetry.io/proto/otlp/profiles/v1development"; // │ ScopeProfiles │ // └──────────────────┘ // │ -// │ 1-1 +// │ 1-n // ▼ // ┌──────────────────┐ // │ Profile │ @@ -67,15 +67,21 @@ option go_package = "go.opentelemetry.io/proto/otlp/profiles/v1development"; // │ n-1 // │ 1-n ┌───────────────────────────────────────┐ // ▼ │ ▽ -// ┌──────────────────┐ 1-n ┌──────────────┐ ┌──────────┐ -// │ Sample │ ──────▷ │ KeyValue │ │ Link │ -// └──────────────────┘ └──────────────┘ └──────────┘ -// │ 1-n △ △ -// │ 1-n ┌─────────────────┘ │ 1-n -// ▽ │ │ -// ┌──────────────────┐ n-1 ┌──────────────┐ -// │ Location │ ──────▷ │ Mapping │ -// └──────────────────┘ └──────────────┘ +// ┌──────────────────┐ 1-n ┌─────────────────┐ ┌──────────┐ +// │ Sample │ ──────▷ │ KeyValueAndUnit │ │ Link │ +// └──────────────────┘ └─────────────────┘ └──────────┘ +// │ △ △ +// │ n-1 │ │ 1-n +// ▽ │ │ +// ┌──────────────────┐ │ │ +// │ Stack │ │ │ +// └──────────────────┘ │ │ +// │ 1-n │ │ +// │ 1-n ┌────────────────┘ │ +// ▽ │ │ +// ┌──────────────────┐ n-1 ┌─────────────┐ +// │ Location │ ──────▷ │ Mapping │ +// └──────────────────┘ └─────────────┘ // │ // │ 1-n // ▼ @@ -91,30 +97,82 @@ option go_package = "go.opentelemetry.io/proto/otlp/profiles/v1development"; // // ProfilesDictionary represents the profiles data shared across the -// entire message being sent. +// entire message being sent. The following applies to all fields in this +// message: +// +// - A dictionary is an array of dictionary items. Users of the dictionary +// compactly reference the items using the index within the array. +// +// - A dictionary MUST have a zero value encoded as the first element. This +// allows for _index fields pointing into the dictionary to use a 0 pointer +// value to indicate 'null' / 'not set'. Unless otherwise defined, a 'zero +// value' message value is one with all default field values, so as to +// minimize wire encoded size. +// +// - There SHOULD NOT be dupes in a dictionary. The identity of dictionary +// items is based on their value, recursively as needed. If a particular +// implementation does emit duplicated items, it MUST NOT attempt to give them +// meaning based on the index or order. A profile processor may remove +// duplicate items and this MUST NOT have any observable effects for +// consumers. +// +// - There SHOULD NOT be orphaned (unreferenced) items in a dictionary. A +// profile processor may remove ("garbage-collect") orphaned items and this +// MUST NOT have any observable effects for consumers. +// message ProfilesDictionary { // Mappings from address ranges to the image/binary/library mapped // into that address range referenced by locations via Location.mapping_index. + // + // mapping_table[0] must always be zero value (Mapping{}) and present. repeated Mapping mapping_table = 1; - // Locations referenced by samples via Profile.location_indices. + // Locations referenced by samples via Stack.location_indices. + // + // location_table[0] must always be zero value (Location{}) and present. repeated Location location_table = 2; // Functions referenced by locations via Line.function_index. + // + // function_table[0] must always be zero value (Function{}) and present. repeated Function function_table = 3; // Links referenced by samples via Sample.link_index. + // + // link_table[0] must always be zero value (Link{}) and present. repeated Link link_table = 4; // A common table for strings referenced by various messages. - // string_table[0] must always be "". + // + // string_table[0] must always be "" and present. repeated string string_table = 5; - // A common table for attributes referenced by various messages. - repeated opentelemetry.proto.common.v1.KeyValue attribute_table = 6; + // A common table for attributes referenced by the Profile, Sample, Mapping + // and Location messages below through attribute_indices field. Each entry is + // a key/value pair with an optional unit. Since this is a dictionary table, + // multiple entries with the same key may be present, unlike direct attribute + // tables like Resource.attributes. The referencing attribute_indices fields, + // though, do maintain the key uniqueness requirement. + // + // It's recommended to use attributes for variables with bounded cardinality, + // such as categorical variables + // (https://en.wikipedia.org/wiki/Categorical_variable). Using an attribute of + // a floating point type (e.g., CPU time) in a sample can quickly make every + // attribute value unique, defeating the purpose of the dictionary and + // impractically increasing the profile size. + // + // Examples of attributes: + // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" + // "abc.com/myattribute": true + // "allocation_size": 128 bytes + // + // attribute_table[0] must always be zero value (KeyValueAndUnit{}) and present. + repeated KeyValueAndUnit attribute_table = 6; - // Represents a mapping between Attribute Keys and Units. - repeated AttributeUnit attribute_units = 7; + // Stacks referenced by samples via Sample.stack_index. + // + // stack_table[0] must always be zero value (Stack{}) and present. + repeated Stack stack_table = 7; } // ProfilesData represents the profiles data that can be stored in persistent storage, @@ -135,6 +193,8 @@ message ProfilesData { // from non-containerized processes. // Other resource groupings are possible as well and clarified via // Resource.attributes and semantic conventions. + // Tools that visualize profiles should prefer displaying + // resources_profiles[0].scope_profiles[0].profiles[0] by default. repeated ResourceProfiles resource_profiles = 1; // One instance of ProfilesDictionary @@ -176,7 +236,8 @@ message ScopeProfiles { // is recorded in. Notably, the last part of the URL path is the version number of the // schema: http[s]://server[:port]/path/. To learn more about Schema URL see // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - // This schema_url applies to all profiles in the "profiles" field. + // This schema_url applies to the data in the "scope" field and all profiles in the + // "profiles" field. string schema_url = 3; } @@ -192,106 +253,86 @@ message ScopeProfiles { // that is most useful to humans. There should be enough // information present to determine the original sampled values. // -// - On-disk, the serialized proto must be gzip-compressed. -// // - The profile is represented as a set of samples, where each sample -// references a sequence of locations, and where each location belongs +// references a stack trace which is a list of locations, each belonging // to a mapping. -// - There is a N->1 relationship from sample.location_id entries to -// locations. For every sample.location_id entry there must be a +// - There is a N->1 relationship from Stack.location_indices entries to +// locations. For every Stack.location_indices entry there must be a // unique Location with that index. // - There is an optional N->1 relationship from locations to // mappings. For every nonzero Location.mapping_id there must be a // unique Mapping with that index. -// Represents a complete profile, including sample types, samples, -// mappings to binaries, locations, functions, string table, and additional metadata. -// It modifies and annotates pprof Profile with OpenTelemetry specific fields. +// Represents a complete profile, including sample types, samples, mappings to +// binaries, stacks, locations, functions, string table, and additional +// metadata. It modifies and annotates pprof Profile with OpenTelemetry +// specific fields. // // Note that whilst fields in this message retain the name and field id from pprof in most cases // for ease of understanding data migration, it is not intended that pprof:Profile and // OpenTelemetry:Profile encoding be wire compatible. message Profile { - // A description of the samples associated with each Sample.value. - // For a cpu profile this might be: - // [["cpu","nanoseconds"]] or [["wall","seconds"]] or [["syscall","count"]] + // The type and unit of all Sample.values in this profile. + // For a cpu or off-cpu profile this might be: + // ["cpu","nanoseconds"] or ["off_cpu","nanoseconds"] // For a heap profile, this might be: - // [["allocations","count"], ["space","bytes"]], - // If one of the values represents the number of events represented - // by the sample, by convention it should be at index 0 and use - // sample_type.unit == "count". - repeated ValueType sample_type = 1; + // ["allocated_objects","count"] or ["allocated_space","bytes"], + ValueType sample_type = 1; // The set of samples recorded in this profile. - repeated Sample sample = 2; + repeated Sample samples = 2; - // References to locations in ProfilesDictionary.location_table. - repeated int32 location_indices = 3; - - // The following fields 4-14 are informational, do not affect + // The following fields 3-12 are informational, do not affect // interpretation of results. // Time of collection (UTC) represented as nanoseconds past the epoch. - int64 time_nanos = 4; + fixed64 time_unix_nano = 3; // Duration of the profile, if a duration makes sense. - int64 duration_nanos = 5; + uint64 duration_nano = 4; // The kind of events between sampled occurrences. // e.g [ "cpu","cycles" ] or [ "heap","bytes" ] - ValueType period_type = 6; + ValueType period_type = 5; // The number of events between sampled occurrences. - int64 period = 7; - // Free-form text associated with the profile. The text is displayed as is - // to the user by the tools that read profiles (e.g. by pprof). This field - // should not be used to store any machine-readable information, it is only - // for human-friendly content. The profile must stay functional if this field - // is cleaned. - repeated int32 comment_strindices = 8; // Indices into ProfilesDictionary.string_table. - // Index into the sample_type array to the default sample type. - int32 default_sample_type_index = 9; + int64 period = 6; // A globally unique identifier for a profile. The ID is a 16-byte array. An ID with - // all zeroes is considered invalid. - // - // This field is required. - bytes profile_id = 10; - - // dropped_attributes_count is the number of attributes that were discarded. Attributes + // all zeroes is considered invalid. It may be used for deduplication and signal + // correlation purposes. It is acceptable to treat two profiles with different values + // in this field as not equal, even if they represented the same object at an earlier + // time. + // This field is optional; an ID may be assigned to an ID-less profile in a later step. + bytes profile_id = 7; + + // The number of attributes that were discarded. Attributes // can be discarded because their keys are too long or because there are too many // attributes. If this value is 0, then no attributes were dropped. - uint32 dropped_attributes_count = 11; - - // Specifies format of the original payload. Common values are defined in semantic conventions. [required if original_payload is present] - string original_payload_format = 12; - - // Original payload can be stored in this field. This can be useful for users who want to get the original payload. - // Formats such as JFR are highly extensible and can contain more information than what is defined in this spec. - // Inclusion of original payload should be configurable by the user. Default behavior should be to not include the original payload. - // If the original payload is in pprof format, it SHOULD not be included in this field. - // The field is optional, however if it is present then equivalent converted data should be populated in other fields - // of this message as far as is practicable. - bytes original_payload = 13; + uint32 dropped_attributes_count = 8; - // References to attributes in attribute_table. [optional] - // It is a collection of key/value pairs. Note, global attributes - // like server name can be set using the resource API. Examples of attributes: + // The original payload format. See also original_payload. Optional, but the + // format and the bytes must be set or unset together. // - // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" - // "/http/server_latency": 300 - // "abc.com/myattribute": true - // "abc.com/score": 10.239 + // The allowed values for the format string are defined by the OpenTelemetry + // specification. Some examples are "jfr", "pprof", "linux_perf". // - // The OpenTelemetry API specification further restricts the allowed value types: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute - // Attribute keys MUST be unique (it is not allowed to have more than one - // attribute with the same key). - repeated int32 attribute_indices = 14; -} + // The original payload may be optionally provided when the conversion to the + // OLTP format was done from a different format with some loss of the fidelity + // and the receiver may want to store the original payload to allow future + // lossless export or reinterpretation. Some examples of the original format + // are JFR (Java Flight Recorder), pprof, Linux perf. + // + // Even when the original payload is in a format that is semantically close to + // OTLP, such as pprof, a conversion may still be lossy in some cases (e.g. if + // the pprof file contains custom extensions or conventions). + // + // The original payload can be large in size, so including the original + // payload should be configurable by the profiler or collector options. The + // default behavior should be to not include the original payload. + string original_payload_format = 9; + // The original payload bytes. See also original_payload_format. Optional, but + // format and the bytes must be set or unset together. + bytes original_payload = 10; -// Represents a mapping between Attribute Keys and Units. -message AttributeUnit { - // Index into string table. - int32 attribute_key_strindex = 1; - // Index into string table. - int32 unit_strindex = 2; + // References to attributes in attribute_table. [optional] + repeated int32 attribute_indices = 11; } // A pointer from a profile Sample to a trace Span. @@ -305,108 +346,52 @@ message Link { bytes span_id = 2; } -// Specifies the method of aggregating metric values, either DELTA (change since last report) -// or CUMULATIVE (total since a fixed start time). -enum AggregationTemporality { - /* UNSPECIFIED is the default AggregationTemporality, it MUST not be used. */ - AGGREGATION_TEMPORALITY_UNSPECIFIED = 0; - - /** DELTA is an AggregationTemporality for a profiler which reports - changes since last report time. Successive metrics contain aggregation of - values from continuous and non-overlapping intervals. - - The values for a DELTA metric are based only on the time interval - associated with one measurement cycle. There is no dependency on - previous measurements like is the case for CUMULATIVE metrics. - - For example, consider a system measuring the number of requests that - it receives and reports the sum of these requests every second as a - DELTA metric: - - 1. The system starts receiving at time=t_0. - 2. A request is received, the system measures 1 request. - 3. A request is received, the system measures 1 request. - 4. A request is received, the system measures 1 request. - 5. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+1 with a value of 3. - 6. A request is received, the system measures 1 request. - 7. A request is received, the system measures 1 request. - 8. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0+1 to - t_0+2 with a value of 2. */ - AGGREGATION_TEMPORALITY_DELTA = 1; - - /** CUMULATIVE is an AggregationTemporality for a profiler which - reports changes since a fixed start time. This means that current values - of a CUMULATIVE metric depend on all previous measurements since the - start time. Because of this, the sender is required to retain this state - in some form. If this state is lost or invalidated, the CUMULATIVE metric - values MUST be reset and a new fixed start time following the last - reported measurement time sent MUST be used. - - For example, consider a system measuring the number of requests that - it receives and reports the sum of these requests every second as a - CUMULATIVE metric: - - 1. The system starts receiving at time=t_0. - 2. A request is received, the system measures 1 request. - 3. A request is received, the system measures 1 request. - 4. A request is received, the system measures 1 request. - 5. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+1 with a value of 3. - 6. A request is received, the system measures 1 request. - 7. A request is received, the system measures 1 request. - 8. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+2 with a value of 5. - 9. The system experiences a fault and loses state. - 10. The system recovers and resumes receiving at time=t_1. - 11. A request is received, the system measures 1 request. - 12. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_1 to - t_1+1 with a value of 1. - - Note: Even though, when reporting changes since last report time, using - CUMULATIVE is valid, it is not recommended. */ - AGGREGATION_TEMPORALITY_CUMULATIVE = 2; -} - -// ValueType describes the type and units of a value, with an optional aggregation temporality. +// ValueType describes the type and units of a value. message ValueType { - int32 type_strindex = 1; // Index into ProfilesDictionary.string_table. - int32 unit_strindex = 2; // Index into ProfilesDictionary.string_table. + // Index into ProfilesDictionary.string_table. + int32 type_strindex = 1; - AggregationTemporality aggregation_temporality = 3; + // Index into ProfilesDictionary.string_table. + int32 unit_strindex = 2; } -// Each Sample records values encountered in some program -// context. The program context is typically a stack trace, perhaps -// augmented with auxiliary information like the thread-id, some -// indicator of a higher level request being handled etc. +// Each Sample records values encountered in some program context. The program +// context is typically a stack trace, perhaps augmented with auxiliary +// information like the thread-id, some indicator of a higher level request +// being handled etc. +// +// A Sample MUST have have at least one values or timestamps_unix_nano entry. If +// both fields are populated, they MUST contain the same number of elements, and +// the elements at the same index MUST refer to the same event. +// +// Examples of different ways of representing a sample with the total value of 10: +// +// Report of a stacktrace at 10 timestamps (consumers must assume the value is 1 for each point): +// values: [] +// timestamps_unix_nano: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +// +// Report of a stacktrace with an aggregated value without timestamps: +// values: [10] +// timestamps_unix_nano: [] +// +// Report of a stacktrace at 4 timestamps where each point records a specific value: +// values: [2, 2, 3, 3] +// timestamps_unix_nano: [1, 2, 3, 4] message Sample { - // locations_start_index along with locations_length refers to to a slice of locations in Profile.location_indices. - int32 locations_start_index = 1; - // locations_length along with locations_start_index refers to a slice of locations in Profile.location_indices. - // Supersedes location_index. - int32 locations_length = 2; - // The type and unit of each value is defined by the corresponding - // entry in Profile.sample_type. All samples must have the same - // number of values, the same as the length of Profile.sample_type. - // When aggregating multiple samples into a single sample, the - // result has a list of values that is the element-wise sum of the - // lists of the originals. - repeated int64 value = 3; + // Reference to stack in ProfilesDictionary.stack_table. + int32 stack_index = 1; + // The type and unit of each value is defined by Profile.sample_type. + repeated int64 values = 2; // References to attributes in ProfilesDictionary.attribute_table. [optional] - repeated int32 attribute_indices = 4; + repeated int32 attribute_indices = 3; // Reference to link in ProfilesDictionary.link_table. [optional] - optional int32 link_index = 5; + // It can be unset / set to 0 if no link exists, as link_table[0] is always a 'null' default value. + int32 link_index = 4; - // Timestamps associated with Sample represented in nanoseconds. These timestamps are expected - // to fall within the Profile's time range. [optional] - repeated uint64 timestamps_unix_nano = 6; + // Timestamps associated with Sample represented in nanoseconds. These + // timestamps should fall within the Profile's time range. + repeated fixed64 timestamps_unix_nano = 5; } // Describes the mapping of a binary in memory, including its address range, @@ -424,19 +409,21 @@ message Mapping { int32 filename_strindex = 4; // Index into ProfilesDictionary.string_table. // References to attributes in ProfilesDictionary.attribute_table. [optional] repeated int32 attribute_indices = 5; - // The following fields indicate the resolution of symbolic info. - bool has_functions = 6; - bool has_filenames = 7; - bool has_line_numbers = 8; - bool has_inline_frames = 9; +} + +// A Stack represents a stack trace as a list of locations. +message Stack { + // References to locations in ProfilesDictionary.location_table. + // The first location is the leaf frame. + repeated int32 location_indices = 1; } // Describes function and line table debug information. message Location { // Reference to mapping in ProfilesDictionary.mapping_table. - // It can be unset if the mapping is unknown or not applicable for - // this profile type. - optional int32 mapping_index = 1; + // It can be unset / set to 0 if the mapping is unknown or not applicable for + // this profile type, as mapping_table[0] is always a 'null' default mapping. + int32 mapping_index = 1; // The instruction address for this location, if available. It // should be within [Mapping.memory_start...Mapping.memory_limit] // for the corresponding mapping. A non-leaf address may be in the @@ -448,18 +435,11 @@ message Location { // preceding entries were inlined. // // E.g., if memcpy() is inlined into printf: - // line[0].function_name == "memcpy" - // line[1].function_name == "printf" - repeated Line line = 3; - // Provides an indication that multiple symbols map to this location's - // address, for example due to identical code folding by the linker. In that - // case the line information above represents one of the multiple - // symbols. This field must be recomputed when the symbolization state of the - // profile changes. - bool is_folded = 4; - + // lines[0].function_name == "memcpy" + // lines[1].function_name == "printf" + repeated Line lines = 3; // References to attributes in ProfilesDictionary.attribute_table. [optional] - repeated int32 attribute_indices = 5; + repeated int32 attribute_indices = 4; } // Details a specific line in a source code, linked to a function. @@ -475,7 +455,7 @@ message Line { // Describes a function, including its human-readable name, system name, // source file, and starting line number in the source. message Function { - // Function name. Empty string if not available. + // The function name. Empty string if not available. int32 name_strindex = 1; // Function name, as identified by the system. For instance, // it can be a C++ mangled name. Empty string if not available. @@ -485,3 +465,16 @@ message Function { // Line number in source file. 0 means unset. int64 start_line = 4; } + +// A custom 'dictionary native' style of encoding attributes which is more convenient +// for profiles than opentelemetry.proto.common.v1.KeyValue +// Specifically, uses the string table for keys and allows optional unit information. +message KeyValueAndUnit { + // The index into the string table for the attribute's key. + int32 key_strindex = 1; + // The value of the attribute. + opentelemetry.proto.common.v1.AnyValue value = 2; + // The index into the string table for the attribute's unit. + // zero indicates implicit (by semconv) or non-defined unit. + int32 unit_strindex = 3; +} diff --git a/src/main/proto/opentelemetry/proto/resource/v1/resource.proto b/src/main/proto/opentelemetry/proto/resource/v1/resource.proto index 05d4456..42c5913 100644 --- a/src/main/proto/opentelemetry/proto/resource/v1/resource.proto +++ b/src/main/proto/opentelemetry/proto/resource/v1/resource.proto @@ -29,9 +29,10 @@ message Resource { // Set of attributes that describe the resource. // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 1; - // dropped_attributes_count is the number of dropped attributes. If the value is 0, then + // The number of dropped attributes. If the value is 0, then // no attributes were dropped. uint32 dropped_attributes_count = 2; diff --git a/src/main/proto/opentelemetry/proto/trace/v1/trace.proto b/src/main/proto/opentelemetry/proto/trace/v1/trace.proto index 2444285..8a992c1 100644 --- a/src/main/proto/opentelemetry/proto/trace/v1/trace.proto +++ b/src/main/proto/opentelemetry/proto/trace/v1/trace.proto @@ -78,7 +78,8 @@ message ScopeSpans { // is recorded in. Notably, the last part of the URL path is the version number of the // schema: http[s]://server[:port]/path/. To learn more about Schema URL see // https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - // This schema_url applies to all spans and span events in the "spans" field. + // This schema_url applies to the data in the "scope" field and all spans and span + // events in the "spans" field. string schema_url = 3; } @@ -182,7 +183,7 @@ message Span { // and `SERVER` (callee) to identify queueing latency associated with the span. SpanKind kind = 6; - // start_time_unix_nano is the start time of the span. On the client side, this is the time + // The start time of the span. On the client side, this is the time // kept by the local machine where the span execution starts. On the server side, this // is the time when the server's application handler starts running. // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. @@ -190,7 +191,7 @@ message Span { // This field is semantically required and it is expected that end_time >= start_time. fixed64 start_time_unix_nano = 7; - // end_time_unix_nano is the end time of the span. On the client side, this is the time + // The end time of the span. On the client side, this is the time // kept by the local machine where the span execution ends. On the server side, this // is the time when the server application handler stops running. // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. @@ -198,7 +199,7 @@ message Span { // This field is semantically required and it is expected that end_time >= start_time. fixed64 end_time_unix_nano = 8; - // attributes is a collection of key/value pairs. Note, global attributes + // A collection of key/value pairs. Note, global attributes // like server name can be set using the resource API. Examples of attributes: // // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" @@ -206,13 +207,12 @@ message Span { // "example.com/myattribute": true // "example.com/score": 10.239 // - // The OpenTelemetry API specification further restricts the allowed value types: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 9; - // dropped_attributes_count is the number of attributes that were discarded. Attributes + // The number of attributes that were discarded. Attributes // can be discarded because their keys are too long or because there are too many // attributes. If this value is 0, then no attributes were dropped. uint32 dropped_attributes_count = 10; @@ -220,27 +220,28 @@ message Span { // Event is a time-stamped annotation of the span, consisting of user-supplied // text description and key-value pairs. message Event { - // time_unix_nano is the time the event occurred. + // The time the event occurred. fixed64 time_unix_nano = 1; - // name of the event. + // The name of the event. // This field is semantically required to be set to non-empty string. string name = 2; - // attributes is a collection of attribute key/value pairs on the event. + // A collection of attribute key/value pairs on the event. // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 3; - // dropped_attributes_count is the number of dropped attributes. If the value is 0, + // The number of dropped attributes. If the value is 0, // then no attributes were dropped. uint32 dropped_attributes_count = 4; } - // events is a collection of Event items. + // A collection of Event items. repeated Event events = 11; - // dropped_events_count is the number of dropped events. If the value is 0, then no + // The number of dropped events. If the value is 0, then no // events were dropped. uint32 dropped_events_count = 12; @@ -259,12 +260,13 @@ message Span { // The trace_state associated with the link. string trace_state = 3; - // attributes is a collection of attribute key/value pairs on the link. + // A collection of attribute key/value pairs on the link. // Attribute keys MUST be unique (it is not allowed to have more than one // attribute with the same key). + // The behavior of software that receives duplicated keys can be unpredictable. repeated opentelemetry.proto.common.v1.KeyValue attributes = 4; - // dropped_attributes_count is the number of dropped attributes. If the value is 0, + // The number of dropped attributes. If the value is 0, // then no attributes were dropped. uint32 dropped_attributes_count = 5; @@ -288,11 +290,11 @@ message Span { fixed32 flags = 6; } - // links is a collection of Links, which are references from this span to a span + // A collection of Links, which are references from this span to a span // in the same or different trace. repeated Link links = 13; - // dropped_links_count is the number of dropped links after the maximum size was + // The number of dropped links after the maximum size was // enforced. If this value is 0, then no links were dropped. uint32 dropped_links_count = 14; diff --git a/tools/API_SHAS b/tools/API_SHAS index 8492a25..4aeea77 100644 --- a/tools/API_SHAS +++ b/tools/API_SHAS @@ -1,11 +1,11 @@ # envoy (source: SHA from https://github.com/envoyproxy/envoy) -ENVOY_SHA="9a0cdcadabcb7baa2348afa1178e083f8d0fe2d7" +ENVOY_SHA="f97695a50e11f5ff6719e129a466bf9204b64a7f" -# dependencies (source: https://github.com/envoyproxy/envoy/blob/9a0cdcadabcb7baa2348afa1178e083f8d0fe2d7/api/bazel/repository_locations.bzl) +# dependencies (source: https://github.com/envoyproxy/envoy/blob/f97695a50e11f5ff6719e129a466bf9204b64a7f/api/bazel/repository_locations.bzl) GOOGLEAPIS_VERSION="fd52b5754b2b268bc3a22a10f29844f206abb327" -PGV_VERSION="1.0.4" +PGV_VERSION="1.3.0" PROMETHEUS_VERSION="0.6.2" -OPENTELEMETRY_VERSION="1.7.0" -XDS_VERSION="2ac532fd44436293585084f8d94c6bdb17835af0" -CEL_VERSION="0.24.0" +OPENTELEMETRY_VERSION="1.9.0" +XDS_VERSION="8bfbf64dc13ee1a570be4fbdcfccbdd8532463f0" +CEL_VERSION="0.25.1" OPENCENSUS_VERSION="" \ No newline at end of file