Repository: envoyproxy/envoy
File: api/envoy/config/route/v3/route_components.proto (Protocol Buffers)

Code before:
      QueryParameterValueMatch query_parameter_value_match = 11;

      // [#not-implemented-hide:]
      // Rate limit on remote address match.
      RemoteAddressMatch remote_address_match = 13;
    }
  }

  message Override {
    // Fetches the override from the dynamic metadata.
    message DynamicMetadata {
      // Metadata struct that defines the key and path to retrieve the struct value.
      // The value must be a struct containing an integer "requests_per_unit" property
      // and a "unit" property with a value parseable to :ref:`RateLimitUnit
      // enum <envoy_v3_api_enum_type.v3.RateLimitUnit>`
      type.metadata.v3.MetadataKey metadata_key = 1 [(validate.rules).message = {required: true}];
    }

    oneof override_specifier {
      option (validate.required) = true;

      // Limit override from dynamic metadata.
      DynamicMetadata dynamic_metadata = 1;
    }
  }

  message HitsAddend {
    // Fixed number of hits to add to the rate limit descriptor.
    //
    // One of the ``number`` or ``format`` fields should be set but not both.
    google.protobuf.UInt64Value number = 1 [(validate.rules).uint64 = {lte: 1000000000}];

    // Substitution format string to extract the number of hits to add to the rate limit descriptor.
    // The same :ref:`format specifier <config_access_log_format>` as used for
    // :ref:`HTTP access logging <config_access_log>` applies here.
    //
    // .. note::
    //
    //   The format string must contains only single valid substitution field. If the format string
    //   not meets the requirement, the configuration will be rejected.
    //
    //   The substitution field should generates a non-negative number or string representation of
    //   a non-negative number. The value of the non-negative number should be less than or equal
    //   to 1000000000 like the ``number`` field. If the output of the substitution field not meet
    //   the requirement, this will be treated as an error and the current descriptor will be ignored.
    //
    // For example, the ``%BYTES_RECEIVED%`` format string will be replaced with the number of bytes
    // received in the request.
    //
    // One of the ``number`` or ``format`` fields should be set but not both.
    string format = 2 [(validate.rules).string = {prefix: "%" suffix: "%" ignore_empty: true}];

Review comment (suggestion):
I think this new field is confusing because there are already `remote_address` and `remote_address_match`. I think calrifying the reasoning behind this feature is the first step. I'm not an expert in this domain, but I would suggest one of the following:

1) consider adding options to `RemoteAddress` and `MaskedRemoteAddress` that enables the matching (the reasoning behind this is that I think that matching is more generic and orthogonal to whether the matched object is a remote address, a request header, etc).
2) See if this should be a typed-extension (using the `extension` field).

cc @wbpcode due to the [comment in #36442](https://github.com/envoyproxy/envoy/issues/36442#issuecomment-3707575919)

Code after:
        (envoy.annotations.deprecated_at_minor_version) = "3.0",
        (envoy.annotations.disallowed_by_default) = true
      ];

      // Rate limit on metadata.
      MetaData metadata = 8;

      // Rate limit descriptor extension. See the rate limit descriptor extensions documentation.
      //
      // :ref:`HTTP matching input functions <arch_overview_matching_api>` are
      // permitted as descriptor extensions. The input functions are only
      // looked up if there is no rate limit descriptor extension matching
      // the type URL.
      //
      // [#extension-category: envoy.rate_limit_descriptors]
      core.v3.TypedExtensionConfig extension = 9;

      // Rate limit on masked remote address.
      MaskedRemoteAddress masked_remote_address = 10;

      // Rate limit on the existence of query parameters.
      QueryParameterValueMatch query_parameter_value_match = 11;

      // [#not-implemented-hide:]
      // Rate limit on remote address match.
      RemoteAddressMatch remote_address_match = 13;
    }
  }

  message Override {
    // Fetches the override from the dynamic metadata.
    message DynamicMetadata {
      // Metadata struct that defines the key and path to retrieve the struct value.
      // The value must be a struct containing an integer "requests_per_unit" property
      // and a "unit" property with a value parseable to :ref:`RateLimitUnit
      // enum <envoy_v3_api_enum_type.v3.RateLimitUnit>`
      type.metadata.v3.MetadataKey metadata_key = 1 [(validate.rules).message = {required: true}];
    }

    oneof override_specifier {
      option (validate.required) = true;

      // Limit override from dynamic metadata.
      DynamicMetadata dynamic_metadata = 1;
    }
  }

  message HitsAddend {
    // Fixed number of hits to add to the rate limit descriptor.
    //
    // One of the ``number`` or ``format`` fields should be set but not both.