From 0d58f28dbf58cede54c3f8713073a8edfaaf8c9f Mon Sep 17 00:00:00 2001 From: Pawel Rzepecki Date: Fri, 28 Aug 2026 13:49:33 +0200 Subject: [PATCH 1/9] relax conditions for kfs to accept redundant inputs --- src/predict_request_validation_utils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/predict_request_validation_utils.hpp b/src/predict_request_validation_utils.hpp index 31e7eb8fb5..61ee7c6ca3 100644 --- a/src/predict_request_validation_utils.hpp +++ b/src/predict_request_validation_utils.hpp @@ -290,7 +290,7 @@ Status RequestValidator Date: Mon, 31 Aug 2026 10:55:43 +0200 Subject: [PATCH 2/9] relaxed input count validation flag --- src/capi_frontend/server_settings.hpp | 1 + src/cli_parser.cpp | 6 ++++++ src/config.cpp | 1 + src/config.hpp | 1 + src/predict_request_validation_utils.hpp | 7 ++++++- 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/capi_frontend/server_settings.hpp b/src/capi_frontend/server_settings.hpp index fa21d03be2..e7b25b535f 100644 --- a/src/capi_frontend/server_settings.hpp +++ b/src/capi_frontend/server_settings.hpp @@ -230,6 +230,7 @@ struct ServerSettingsImpl { std::string logLevel = "INFO"; std::string logPath; bool verboseResponse = false; + bool relaxedInputCountValidation = false; bool allowCredentials = false; std::string allowedOrigins{"*"}; std::string allowedMethods{"*"}; diff --git a/src/cli_parser.cpp b/src/cli_parser.cpp index d7125abc87..229c05c488 100644 --- a/src/cli_parser.cpp +++ b/src/cli_parser.cpp @@ -125,6 +125,10 @@ std::variant> CLIParser::parse(int argc, char* "\"__verbose\" object with additional debug information.", cxxopts::value()->default_value("false"), "VERBOSE_RESPONSE") + ("relaxed_input_count_validation", + "When enabled, inference requests containing input names not defined in the model/pipeline signature are ignored instead of rejected. Does not affect shape/precision validation of recognized inputs. Default: false (extra inputs cause the request to be rejected).", + cxxopts::value()->default_value("false"), + "RELAXED_INPUT_COUNT_VALIDATION") #ifdef MTR_ENABLED ("trace_path", "Path to the trace file", @@ -577,6 +581,8 @@ void CLIParser::prepareServer(ServerSettingsImpl& serverSettings) { serverSettings.logPath = result->operator[]("log_path").as(); if (result->count("verbose_response")) serverSettings.verboseResponse = result->operator[]("verbose_response").as(); + if (result->count("relaxed_input_count_validation")) + serverSettings.relaxedInputCountValidation = result->operator[]("relaxed_input_count_validation").as(); if (result->count("grpc_channel_arguments")) serverSettings.grpcChannelArguments = result->operator[]("grpc_channel_arguments").as(); diff --git a/src/config.cpp b/src/config.cpp index cdbd47c6f0..e1c12699c4 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -432,6 +432,7 @@ const std::string& Config::tracePath() const { return this->serverSettings.trace const std::string& Config::grpcChannelArguments() const { return this->serverSettings.grpcChannelArguments; } uint32_t Config::filesystemPollWaitMilliseconds() const { return this->serverSettings.filesystemPollWaitMilliseconds; } uint32_t Config::resourcesCleanerPollWaitSeconds() const { return this->serverSettings.resourcesCleanerPollWaitSeconds; } +bool Config::relaxedInputCountValidation() const { return this->serverSettings.relaxedInputCountValidation; } bool Config::allowCredentials() const { return this->serverSettings.allowCredentials; } const std::string& Config::allowedOrigins() const { return this->serverSettings.allowedOrigins; } const std::string& Config::allowedMethods() const { return this->serverSettings.allowedMethods; } diff --git a/src/config.hpp b/src/config.hpp index d710bc4e9a..6a8757ae7b 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -312,6 +312,7 @@ class Config { */ uint32_t resourcesCleanerPollWaitSeconds() const; + bool relaxedInputCountValidation() const; bool allowCredentials() const; const std::string& allowedOrigins() const; const std::string& allowedMethods() const; diff --git a/src/predict_request_validation_utils.hpp b/src/predict_request_validation_utils.hpp index 61ee7c6ca3..e7013cdae6 100644 --- a/src/predict_request_validation_utils.hpp +++ b/src/predict_request_validation_utils.hpp @@ -20,6 +20,7 @@ #include #include +#include "config.hpp" #include "logging.hpp" #include "modelversion.hpp" #include "shape.hpp" @@ -290,7 +291,11 @@ Status RequestValidator Date: Mon, 31 Aug 2026 11:43:00 +0200 Subject: [PATCH 3/9] adding flag for disabling input count validation this change has introduced the parameter for disabling input count validation to match TFS's behavior as the customer requested --- docs/parameters.md | 1 + docs/security_considerations.md | 4 +++ src/BUILD | 2 ++ src/capi_frontend/server_settings.hpp | 2 +- src/cli_parser.cpp | 10 +++--- src/config.cpp | 2 +- src/config.hpp | 2 +- src/predict_request_validation_utils.hpp | 4 +-- src/test/ovmsconfig_test.cpp | 17 +++++++++- src/test/predict_validation_test.cpp | 42 ++++++++++++++++++++++++ 10 files changed, 74 insertions(+), 12 deletions(-) diff --git a/docs/parameters.md b/docs/parameters.md index 1b4ce9ca71..f6920bad7d 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -58,6 +58,7 @@ Configuration options for the server are defined only via command-line options a | `allowed_local_media_path` | `string` | Path to the directory containing images to include in requests. If unset, local filesystem images in requests are not supported.| | `allowed_media_domains` | `string` | Comma separated list of media domains from which URLs can be used as input for LLMs. Set to \"all\" to disable this restrictions. If unset, URLs in requests are not supported." | `verbose_response` | `NA` | When enabled, responses include an extra `__verbose` object with additional debug information. Applies for text generation models | +| `disable_input_count_validation` | `bool` (default: false) | When enabled, the number and names of inputs in an inference request are not validated against the model/pipeline signature; requests with extra, unrecognized input names are no longer rejected for that reason. Does not affect shape/precision validation of recognized inputs. **Not recommended** - see [Security Considerations](security_considerations.md). | ## Config management mode options diff --git a/docs/security_considerations.md b/docs/security_considerations.md index 56f33c2a87..1c3d1be059 100644 --- a/docs/security_considerations.md +++ b/docs/security_considerations.md @@ -42,3 +42,7 @@ OpenVINO Model Server has a set of mechanisms preventing denial of service attac - MediaPipe does not validate all the settings during graph initialization. Some settings are checked during graph creation phase (upon request processing). Therefore it is a good practice to always test the configuration by sending example requests to the KServe endpoints before deployment. +--- + +By default, OVMS rejects inference requests whose input count/names don't match the model/pipeline signature. The `--disable_input_count_validation` flag turns this check off, allowing requests with extra, unrecognized inputs to be processed. **This flag is not recommended for production use** - disabling it may expose the model to malformed or malicious requests carrying unexpected inputs and weakens the server's input validation guarantees. Only enable it if you fully trust the clients sending requests to the server. + diff --git a/src/BUILD b/src/BUILD index 1e2368327b..8bfa935254 100644 --- a/src/BUILD +++ b/src/BUILD @@ -1468,6 +1468,8 @@ ovms_cc_library( srcs = ["capi_frontend/inferenceparameter.cpp",], deps = [ "ovms_header", + "libovms_config", + "cpp_headers", "libovmscapi_utils_h", # TODO @atobisze ], visibility = ["//visibility:public"], diff --git a/src/capi_frontend/server_settings.hpp b/src/capi_frontend/server_settings.hpp index e7b25b535f..df3913a13c 100644 --- a/src/capi_frontend/server_settings.hpp +++ b/src/capi_frontend/server_settings.hpp @@ -230,7 +230,7 @@ struct ServerSettingsImpl { std::string logLevel = "INFO"; std::string logPath; bool verboseResponse = false; - bool relaxedInputCountValidation = false; + bool disableInputCountValidation = false; bool allowCredentials = false; std::string allowedOrigins{"*"}; std::string allowedMethods{"*"}; diff --git a/src/cli_parser.cpp b/src/cli_parser.cpp index 229c05c488..e328036bbb 100644 --- a/src/cli_parser.cpp +++ b/src/cli_parser.cpp @@ -125,10 +125,10 @@ std::variant> CLIParser::parse(int argc, char* "\"__verbose\" object with additional debug information.", cxxopts::value()->default_value("false"), "VERBOSE_RESPONSE") - ("relaxed_input_count_validation", - "When enabled, inference requests containing input names not defined in the model/pipeline signature are ignored instead of rejected. Does not affect shape/precision validation of recognized inputs. Default: false (extra inputs cause the request to be rejected).", + ("disable_input_count_validation", + "When enabled, the number and names of inputs in an inference request are not validated against the model/pipeline signature; requests with extra, unrecognized input names are no longer rejected for that reason. Does not affect shape/precision validation of recognized inputs. Default: false (extra inputs cause the request to be rejected).", cxxopts::value()->default_value("false"), - "RELAXED_INPUT_COUNT_VALIDATION") + "DISABLE_INPUT_COUNT_VALIDATION") #ifdef MTR_ENABLED ("trace_path", "Path to the trace file", @@ -581,8 +581,8 @@ void CLIParser::prepareServer(ServerSettingsImpl& serverSettings) { serverSettings.logPath = result->operator[]("log_path").as(); if (result->count("verbose_response")) serverSettings.verboseResponse = result->operator[]("verbose_response").as(); - if (result->count("relaxed_input_count_validation")) - serverSettings.relaxedInputCountValidation = result->operator[]("relaxed_input_count_validation").as(); + if (result->count("disable_input_count_validation")) + serverSettings.disableInputCountValidation = result->operator[]("disable_input_count_validation").as(); if (result->count("grpc_channel_arguments")) serverSettings.grpcChannelArguments = result->operator[]("grpc_channel_arguments").as(); diff --git a/src/config.cpp b/src/config.cpp index e1c12699c4..28e15bbf12 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -432,7 +432,7 @@ const std::string& Config::tracePath() const { return this->serverSettings.trace const std::string& Config::grpcChannelArguments() const { return this->serverSettings.grpcChannelArguments; } uint32_t Config::filesystemPollWaitMilliseconds() const { return this->serverSettings.filesystemPollWaitMilliseconds; } uint32_t Config::resourcesCleanerPollWaitSeconds() const { return this->serverSettings.resourcesCleanerPollWaitSeconds; } -bool Config::relaxedInputCountValidation() const { return this->serverSettings.relaxedInputCountValidation; } +bool Config::disableInputCountValidation() const { return this->serverSettings.disableInputCountValidation; } bool Config::allowCredentials() const { return this->serverSettings.allowCredentials; } const std::string& Config::allowedOrigins() const { return this->serverSettings.allowedOrigins; } const std::string& Config::allowedMethods() const { return this->serverSettings.allowedMethods; } diff --git a/src/config.hpp b/src/config.hpp index 6a8757ae7b..45cea149c3 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -312,7 +312,7 @@ class Config { */ uint32_t resourcesCleanerPollWaitSeconds() const; - bool relaxedInputCountValidation() const; + bool disableInputCountValidation() const; bool allowCredentials() const; const std::string& allowedOrigins() const; const std::string& allowedMethods() const; diff --git a/src/predict_request_validation_utils.hpp b/src/predict_request_validation_utils.hpp index e7013cdae6..8923b28337 100644 --- a/src/predict_request_validation_utils.hpp +++ b/src/predict_request_validation_utils.hpp @@ -291,9 +291,7 @@ Status RequestValidatorset_name("Some_Input"); + request.add_raw_input_contents(); // keep raw_input_contents count in sync with inputs count + auto status = instance->mockValidate(&request); + EXPECT_TRUE(status.ok()) << status.string(); +} + +TEST_F(KFSPredictValidationInputCountConfig, RequestTooManyInputsWithEnabledInputCountValidation) { + setDisableInputCountValidation(false); + + auto inputWrongName = request.add_inputs(); + inputWrongName->set_name("Some_Input"); + auto status = instance->mockValidate(&request); + EXPECT_EQ(status, ovms::StatusCode::INVALID_NO_OF_INPUTS) << status.string(); +} + TEST_F(KFSPredictValidation, RequestWrongInputName) { request.mutable_inputs()->RemoveLast(); // remove redundant input auto inputWrongName = request.add_inputs(); From 6d3ddb9959cba7fd93fb07233f20e62540959b14 Mon Sep 17 00:00:00 2001 From: Pawel Rzepecki Date: Mon, 31 Aug 2026 11:44:48 +0200 Subject: [PATCH 4/9] style --- src/test/ovmsconfig_test.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/ovmsconfig_test.cpp b/src/test/ovmsconfig_test.cpp index a94cf8140e..a9a3f65885 100644 --- a/src/test/ovmsconfig_test.cpp +++ b/src/test/ovmsconfig_test.cpp @@ -2552,9 +2552,12 @@ TEST(OvmsConfigTest, positiveMulti) { TEST(OvmsConfigTest, disableInputCountValidationDefaultsToFalse) { char* n_argv[] = { "ovms", - "--rest_port", "45", - "--model_name", "model", - "--model_path", "/path", + "--rest_port", + "45", + "--model_name", + "model", + "--model_path", + "/path", }; int arg_count = 7; ConstructorEnabledConfig config; From 5a761e714988a0164ddee3eb27301d6ac9236ebd Mon Sep 17 00:00:00 2001 From: Pawel Rzepecki Date: Mon, 31 Aug 2026 13:02:56 +0200 Subject: [PATCH 5/9] copilot's review --- docs/parameters.md | 2 +- docs/security_considerations.md | 2 +- src/cli_parser.cpp | 2 +- src/test/predict_validation_test.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/parameters.md b/docs/parameters.md index f6920bad7d..8b99b6e18d 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -58,7 +58,7 @@ Configuration options for the server are defined only via command-line options a | `allowed_local_media_path` | `string` | Path to the directory containing images to include in requests. If unset, local filesystem images in requests are not supported.| | `allowed_media_domains` | `string` | Comma separated list of media domains from which URLs can be used as input for LLMs. Set to \"all\" to disable this restrictions. If unset, URLs in requests are not supported." | `verbose_response` | `NA` | When enabled, responses include an extra `__verbose` object with additional debug information. Applies for text generation models | -| `disable_input_count_validation` | `bool` (default: false) | When enabled, the number and names of inputs in an inference request are not validated against the model/pipeline signature; requests with extra, unrecognized input names are no longer rejected for that reason. Does not affect shape/precision validation of recognized inputs. **Not recommended** - see [Security Considerations](security_considerations.md). | +| `disable_input_count_validation` | `bool` (default: false) | When enabled, OVMS allows inference requests to include additional, unrecognized inputs beyond the model/pipeline signature (extra inputs are ignored). Required inputs must still be present, and shape/precision validation is still performed for recognized inputs. **Not recommended** - see [Security Considerations](security_considerations.md). | ## Config management mode options diff --git a/docs/security_considerations.md b/docs/security_considerations.md index 1c3d1be059..e70cf7b378 100644 --- a/docs/security_considerations.md +++ b/docs/security_considerations.md @@ -44,5 +44,5 @@ OpenVINO Model Server has a set of mechanisms preventing denial of service attac --- -By default, OVMS rejects inference requests whose input count/names don't match the model/pipeline signature. The `--disable_input_count_validation` flag turns this check off, allowing requests with extra, unrecognized inputs to be processed. **This flag is not recommended for production use** - disabling it may expose the model to malformed or malicious requests carrying unexpected inputs and weakens the server's input validation guarantees. Only enable it if you fully trust the clients sending requests to the server. +By default, OVMS rejects inference requests whose input count/names don't match the model/pipeline signature. The `--disable_input_count_validation` flag turns off the *extra input* check, allowing requests with additional, unrecognized inputs to be processed (extra inputs are ignored; required inputs are still validated). **This flag is not recommended for production use** - disabling it may expose the model to malformed or malicious requests carrying unexpected inputs and weakens the server's input validation guarantees. Only enable it if you fully trust the clients sending requests to the server. diff --git a/src/cli_parser.cpp b/src/cli_parser.cpp index e328036bbb..44d533f1c2 100644 --- a/src/cli_parser.cpp +++ b/src/cli_parser.cpp @@ -126,7 +126,7 @@ std::variant> CLIParser::parse(int argc, char* cxxopts::value()->default_value("false"), "VERBOSE_RESPONSE") ("disable_input_count_validation", - "When enabled, the number and names of inputs in an inference request are not validated against the model/pipeline signature; requests with extra, unrecognized input names are no longer rejected for that reason. Does not affect shape/precision validation of recognized inputs. Default: false (extra inputs cause the request to be rejected).", + "When enabled, OVMS allows inference requests to include additional, unrecognized inputs beyond the model/pipeline signature (extra inputs are ignored). Required inputs must still be present, and shape/precision validation is still performed for recognized inputs. Default: false (extra inputs cause the request to be rejected).", cxxopts::value()->default_value("false"), "DISABLE_INPUT_COUNT_VALIDATION") #ifdef MTR_ENABLED diff --git a/src/test/predict_validation_test.cpp b/src/test/predict_validation_test.cpp index 312aae73f9..0fb91f27e4 100644 --- a/src/test/predict_validation_test.cpp +++ b/src/test/predict_validation_test.cpp @@ -137,7 +137,7 @@ class KFSPredictValidationInputCountConfig : public KFSPredictValidation { void setDisableInputCountValidation(bool value) { ovms::ServerSettingsImpl testServerSettings = originalServerSettings; testServerSettings.disableInputCountValidation = value; - ovms::Config::instance().parse(&testServerSettings, &originalModelsSettings); + ASSERT_TRUE(ovms::Config::instance().parse(&testServerSettings, &originalModelsSettings)); } void TearDown() override { From e86555570bc71011dadc44f4487db0df273f31cf Mon Sep 17 00:00:00 2001 From: Pawel Rzepecki Date: Mon, 31 Aug 2026 13:12:42 +0200 Subject: [PATCH 6/9] fix tests --- src/BUILD | 2 ++ src/test/predict_validation_test.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/BUILD b/src/BUILD index 8bfa935254..fe3a1c6f16 100644 --- a/src/BUILD +++ b/src/BUILD @@ -1425,6 +1425,8 @@ ovms_cc_library( "libovms_kfs_utils", "libovms_tensorinfo", "libovmsprecision", + "libovms_config", + "cpp_headers", ], visibility = ["//visibility:public",], ) diff --git a/src/test/predict_validation_test.cpp b/src/test/predict_validation_test.cpp index 0fb91f27e4..312aae73f9 100644 --- a/src/test/predict_validation_test.cpp +++ b/src/test/predict_validation_test.cpp @@ -137,7 +137,7 @@ class KFSPredictValidationInputCountConfig : public KFSPredictValidation { void setDisableInputCountValidation(bool value) { ovms::ServerSettingsImpl testServerSettings = originalServerSettings; testServerSettings.disableInputCountValidation = value; - ASSERT_TRUE(ovms::Config::instance().parse(&testServerSettings, &originalModelsSettings)); + ovms::Config::instance().parse(&testServerSettings, &originalModelsSettings); } void TearDown() override { From e5e3c1bf32a10f17c5819f156114f119a1ba1106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Rzepecki?= Date: Wed, 2 Sep 2026 07:28:47 +0100 Subject: [PATCH 7/9] Apply suggestion from @dtrawins Co-authored-by: Trawinski, Dariusz --- docs/parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/parameters.md b/docs/parameters.md index 8b99b6e18d..890927501d 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -58,7 +58,7 @@ Configuration options for the server are defined only via command-line options a | `allowed_local_media_path` | `string` | Path to the directory containing images to include in requests. If unset, local filesystem images in requests are not supported.| | `allowed_media_domains` | `string` | Comma separated list of media domains from which URLs can be used as input for LLMs. Set to \"all\" to disable this restrictions. If unset, URLs in requests are not supported." | `verbose_response` | `NA` | When enabled, responses include an extra `__verbose` object with additional debug information. Applies for text generation models | -| `disable_input_count_validation` | `bool` (default: false) | When enabled, OVMS allows inference requests to include additional, unrecognized inputs beyond the model/pipeline signature (extra inputs are ignored). Required inputs must still be present, and shape/precision validation is still performed for recognized inputs. **Not recommended** - see [Security Considerations](security_considerations.md). | +| `disable_input_count_validation` | `bool` (default: false) | Disables enforcement for the KServe requests to match all the model inputs. It ignores all inputs which are not used in the model. Not recommended for performance reasons but in some cases might simplify the client. | ## Config management mode options From c7b3c7ba16d0f084e90cc68e9eb4938a45338e84 Mon Sep 17 00:00:00 2001 From: Pawel Rzepecki Date: Wed, 2 Sep 2026 08:48:35 +0200 Subject: [PATCH 8/9] review changes --- docs/security_considerations.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/security_considerations.md b/docs/security_considerations.md index e70cf7b378..6263ff68e4 100644 --- a/docs/security_considerations.md +++ b/docs/security_considerations.md @@ -44,5 +44,4 @@ OpenVINO Model Server has a set of mechanisms preventing denial of service attac --- -By default, OVMS rejects inference requests whose input count/names don't match the model/pipeline signature. The `--disable_input_count_validation` flag turns off the *extra input* check, allowing requests with additional, unrecognized inputs to be processed (extra inputs are ignored; required inputs are still validated). **This flag is not recommended for production use** - disabling it may expose the model to malformed or malicious requests carrying unexpected inputs and weakens the server's input validation guarantees. Only enable it if you fully trust the clients sending requests to the server. - +By default, OVMS rejects inference requests whose input count/names don't match the model/pipeline signature. The `--disable_input_count_validation` flag turns off the *extra input* check, allowing requests with additional, unrecognized inputs to be processed (extra inputs are ignored; required inputs are still validated). **This flag is not recommended for production use** - disabling it weakens the server's input validation and may have inpact on performence. From 8d2828ff0f40877a3764679b7717f5e338c6349f Mon Sep 17 00:00:00 2001 From: Pawel Rzepecki Date: Wed, 2 Sep 2026 14:43:04 +0200 Subject: [PATCH 9/9] removed security considerations for this feature --- docs/security_considerations.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/security_considerations.md b/docs/security_considerations.md index 6263ff68e4..564349e3f2 100644 --- a/docs/security_considerations.md +++ b/docs/security_considerations.md @@ -41,7 +41,3 @@ OpenVINO Model Server has a set of mechanisms preventing denial of service attac --- - MediaPipe does not validate all the settings during graph initialization. Some settings are checked during graph creation phase (upon request processing). Therefore it is a good practice to always test the configuration by sending example requests to the KServe endpoints before deployment. - ---- - -By default, OVMS rejects inference requests whose input count/names don't match the model/pipeline signature. The `--disable_input_count_validation` flag turns off the *extra input* check, allowing requests with additional, unrecognized inputs to be processed (extra inputs are ignored; required inputs are still validated). **This flag is not recommended for production use** - disabling it weakens the server's input validation and may have inpact on performence.