Skip to content

Commit 1eeb9dc

Browse files
committed
fix: harden rust validation middleware sidecar
Signed-off-by: lucarlig <luca.carlig@ibm.com>
1 parent c8209c7 commit 1eeb9dc

File tree

13 files changed

+384
-95
lines changed

13 files changed

+384
-95
lines changed

.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ SECURE_COOKIES=false
143143

144144
# Enable validation middleware and experimental IO validation for visibility
145145
EXPERIMENTAL_VALIDATE_IO=true
146+
# Optional: enable the Rust JSON validation sidecar after `make rust-sidecar-install`
147+
# EXPERIMENTAL_RUST_VALIDATION_MIDDLEWARE_ENABLED=false
146148
VALIDATION_MIDDLEWARE_ENABLED=true
147149

148150
# Permission audit logging (RBAC checks) - disabled by default for performance
@@ -792,10 +794,15 @@ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
792794
# Phase 0: EXPERIMENTAL_VALIDATE_IO=false (disabled, default)
793795
# Phase 1: EXPERIMENTAL_VALIDATE_IO=true, VALIDATION_STRICT=false (log-only)
794796
# Phase 2: EXPERIMENTAL_VALIDATE_IO=true, VALIDATION_STRICT=true (enforce in staging)
797+
# Optional accelerator: EXPERIMENTAL_RUST_VALIDATION_MIDDLEWARE_ENABLED=true after `make rust-sidecar-install`
795798
# Phase 3: Production deployment with all features enabled
796799
# Project defaults block enables EXPERIMENTAL_VALIDATE_IO for local dev
797800
# EXPERIMENTAL_VALIDATE_IO=false
798801

802+
# Enable the experimental Rust sidecar for recursive JSON validation checks
803+
# Requires `make rust-sidecar-install` before enabling.
804+
# EXPERIMENTAL_RUST_VALIDATION_MIDDLEWARE_ENABLED=false
805+
799806
# Enable validation middleware for all requests
800807
# When enabled, validates all incoming request parameters and paths
801808
# Options: true, false (default)

.secrets.baseline

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"files": null,
44
"lines": null
55
},
6-
"generated_at": "2026-04-03T13:20:55Z",
6+
"generated_at": "2026-04-03T13:58:22Z",
77
"plugins_used": [
88
{
99
"name": "AWSKeyDetector"
@@ -92,87 +92,87 @@
9292
"hashed_secret": "08cd923367890009657eab812753379bdb321eeb",
9393
"is_secret": false,
9494
"is_verified": false,
95-
"line_number": 509,
95+
"line_number": 511,
9696
"type": "Basic Auth Credentials",
9797
"verified_result": null
9898
},
9999
{
100100
"hashed_secret": "14f8aa3e560a47851908ab0f04ec856dbc512d93",
101101
"is_secret": false,
102102
"is_verified": false,
103-
"line_number": 704,
103+
"line_number": 706,
104104
"type": "Secret Keyword",
105105
"verified_result": null
106106
},
107107
{
108108
"hashed_secret": "fa9beb99e4029ad5a6615399e7bbae21356086b3",
109109
"is_secret": false,
110110
"is_verified": false,
111-
"line_number": 964,
111+
"line_number": 971,
112112
"type": "Secret Keyword",
113113
"verified_result": null
114114
},
115115
{
116116
"hashed_secret": "7b4455a56fbf1d198e45e04c437488514645a82c",
117117
"is_secret": false,
118118
"is_verified": false,
119-
"line_number": 990,
119+
"line_number": 997,
120120
"type": "Secret Keyword",
121121
"verified_result": null
122122
},
123123
{
124124
"hashed_secret": "ac371b6dcce28a86c90d12bc57d946a800eebf17",
125125
"is_secret": false,
126126
"is_verified": false,
127-
"line_number": 1070,
127+
"line_number": 1077,
128128
"type": "Secret Keyword",
129129
"verified_result": null
130130
},
131131
{
132132
"hashed_secret": "0b6ec68df700dec4dcd64babd0eda1edccddace1",
133133
"is_secret": false,
134134
"is_verified": false,
135-
"line_number": 1075,
135+
"line_number": 1082,
136136
"type": "Secret Keyword",
137137
"verified_result": null
138138
},
139139
{
140140
"hashed_secret": "4ad6f0082ee224001beb3ca5c3e81c8ceea5ed86",
141141
"is_secret": false,
142142
"is_verified": false,
143-
"line_number": 1080,
143+
"line_number": 1087,
144144
"type": "Secret Keyword",
145145
"verified_result": null
146146
},
147147
{
148148
"hashed_secret": "cb32747fcfb55eaa194c8cd8e4ba7d49ada08a94",
149149
"is_secret": false,
150150
"is_verified": false,
151-
"line_number": 1086,
151+
"line_number": 1093,
152152
"type": "Secret Keyword",
153153
"verified_result": null
154154
},
155155
{
156156
"hashed_secret": "6c178d51b13520496dbc767ed3d9d7aa5803ac72",
157157
"is_secret": false,
158158
"is_verified": false,
159-
"line_number": 1098,
159+
"line_number": 1105,
160160
"type": "Secret Keyword",
161161
"verified_result": null
162162
},
163163
{
164164
"hashed_secret": "ca45060a53fd8a255d1a83ee8d2f025283ccc66e",
165165
"is_secret": false,
166166
"is_verified": false,
167-
"line_number": 1116,
167+
"line_number": 1123,
168168
"type": "Secret Keyword",
169169
"verified_result": null
170170
},
171171
{
172172
"hashed_secret": "910fbf00f58e9bcb095ea26a75cc1d9a3355e671",
173173
"is_secret": false,
174174
"is_verified": false,
175-
"line_number": 1165,
175+
"line_number": 1172,
176176
"type": "Secret Keyword",
177177
"verified_result": null
178178
}
@@ -780,71 +780,71 @@
780780
"hashed_secret": "7b4455a56fbf1d198e45e04c437488514645a82c",
781781
"is_secret": false,
782782
"is_verified": false,
783-
"line_number": 800,
783+
"line_number": 801,
784784
"type": "Secret Keyword",
785785
"verified_result": null
786786
},
787787
{
788788
"hashed_secret": "25ab86bed149ca6ca9c1c0d5db7c9a91388ddeab",
789789
"is_secret": false,
790790
"is_verified": false,
791-
"line_number": 955,
791+
"line_number": 956,
792792
"type": "Basic Auth Credentials",
793793
"verified_result": null
794794
},
795795
{
796796
"hashed_secret": "d08f88df745fa7950b104e4a707a31cfce7b5841",
797797
"is_secret": false,
798798
"is_verified": false,
799-
"line_number": 1055,
799+
"line_number": 1056,
800800
"type": "Secret Keyword",
801801
"verified_result": null
802802
},
803803
{
804804
"hashed_secret": "7288edd0fc3ffcbe93a0cf06e3568e28521687bc",
805805
"is_secret": false,
806806
"is_verified": false,
807-
"line_number": 1058,
807+
"line_number": 1059,
808808
"type": "Secret Keyword",
809809
"verified_result": null
810810
},
811811
{
812812
"hashed_secret": "8674c9b302d20800e4ab3808f139704d8641a6e3",
813813
"is_secret": false,
814814
"is_verified": false,
815-
"line_number": 1224,
815+
"line_number": 1225,
816816
"type": "Secret Keyword",
817817
"verified_result": null
818818
},
819819
{
820820
"hashed_secret": "cff0d14e4337fa8bdb68dfa906f04b0df6fad72f",
821821
"is_secret": false,
822822
"is_verified": false,
823-
"line_number": 1263,
823+
"line_number": 1264,
824824
"type": "Secret Keyword",
825825
"verified_result": null
826826
},
827827
{
828828
"hashed_secret": "f865b53623b121fd34ee5426c792e5c33af8c227",
829829
"is_secret": false,
830830
"is_verified": false,
831-
"line_number": 1311,
831+
"line_number": 1312,
832832
"type": "Secret Keyword",
833833
"verified_result": null
834834
},
835835
{
836836
"hashed_secret": "acde39840735314af1300688b6c2324ea89770a3",
837837
"is_secret": false,
838838
"is_verified": false,
839-
"line_number": 1406,
839+
"line_number": 1407,
840840
"type": "Secret Keyword",
841841
"verified_result": null
842842
},
843843
{
844844
"hashed_secret": "fa9beb99e4029ad5a6615399e7bbae21356086b3",
845845
"is_secret": false,
846846
"is_verified": false,
847-
"line_number": 1754,
847+
"line_number": 1755,
848848
"type": "Secret Keyword",
849849
"verified_result": null
850850
}

Makefile

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8348,7 +8348,7 @@ upgrade-validate: ## Validate fresh + upgrade DB startup
83488348
# help: rust-mcp-runtime-test - Run tests for the experimental Rust MCP runtime
83498349
# help: rust-mcp-runtime-run - Run the experimental Rust MCP runtime against local gateway /rpc
83508350

8351-
.PHONY: rust-build rust-dev rust-test rust-test-integration rust-python-test rust-test-all rust-bench rust-bench-build rust-bench-compare rust-compare rust-check rust-clean rust-verify rust-verify-stubs
8351+
.PHONY: rust-build rust-dev rust-test rust-test-integration rust-python-test rust-test-all rust-bench rust-bench-build rust-bench-compare rust-compare rust-check rust-clean rust-verify rust-verify-stubs rust-sidecar-install rust-sidecar-test
83528352
.PHONY: rust-ensure-deps rust-install-deps rust-install-targets rust-install
83538353
.PHONY: rust-build-all-linux rust-build-all-platforms rust-cross rust-cross-install-build
83548354
.PHONY: rust-mcp-runtime-build rust-mcp-runtime-test rust-mcp-runtime-run
@@ -8381,12 +8381,13 @@ rust-ensure-deps: ## Ensure Rust toolchain, maturin, and a
83818381

83828382
rust-install: rust-ensure-deps ## Install all Rust plugins into venv
83838383
@$(MAKE) -C plugins_rust install
8384+
@$(MAKE) rust-sidecar-install
83848385

83858386
rust-build: rust-ensure-deps ## Build Rust plugins (release)
83868387
@$(MAKE) -C plugins_rust build
83878388

83888389
rust-dev: rust-ensure-deps ## Build and install Rust plugins (development mode)
8389-
@$(MAKE) -C plugins_rust install
8390+
@$(MAKE) rust-install
83908391

83918392
rust-test: rust-ensure-deps ## Run Rust plugin tests
83928393
@$(MAKE) -C plugins_rust test
@@ -8410,6 +8411,16 @@ rust-compare: rust-ensure-deps ## Run compare_performance.py only (skip
84108411

84118412
rust-check: rust-ensure-deps ## Run all Rust checks (format, lint, test)
84128413
@$(MAKE) -C plugins_rust check
8414+
@$(MAKE) rust-sidecar-test
8415+
8416+
rust-sidecar-install: rust-ensure-deps ## Build and install the validation middleware sidecar into the active venv
8417+
@test -d "$(VENV_DIR)" || $(MAKE) venv
8418+
@echo "🧪 Installing validation middleware sidecar..."
8419+
@/bin/bash -c "source $(VENV_DIR)/bin/activate && maturin develop --manifest-path tools_rust/validation_middleware_sidecar/Cargo.toml"
8420+
8421+
rust-sidecar-test: rust-ensure-deps ## Run tests for the validation middleware sidecar crate
8422+
@echo "🧪 Testing validation middleware sidecar..."
8423+
@cargo test --manifest-path tools_rust/validation_middleware_sidecar/Cargo.toml
84138424

84148425
rust-doc: rust-ensure-deps ## Build Rust documentation
84158426
@$(MAKE) -C plugins_rust doc

charts/mcp-stack/values.schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@
481481
"EXPERIMENTAL_VALIDATE_IO": {
482482
"type": "string"
483483
},
484+
"EXPERIMENTAL_RUST_VALIDATION_MIDDLEWARE_ENABLED": {
485+
"type": "string"
486+
},
484487
"FEDERATION_TIMEOUT": {
485488
"type": "string",
486489
"description": "HTTP timeout in seconds for gateway and MCP server requests (health checks, tool invocations)",

charts/mcp-stack/values.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ mcpContextForge:
657657
# ─ Additional Settings (defaults from config.py) ─
658658
# Validation & sanitization
659659
EXPERIMENTAL_VALIDATE_IO: "false" # enable experimental input/output validation
660+
EXPERIMENTAL_RUST_VALIDATION_MIDDLEWARE_ENABLED: "false" # enable the experimental Rust JSON validation sidecar (requires sidecar install)
660661
VALIDATION_MIDDLEWARE_ENABLED: "false" # enable validation middleware for all requests
661662
VALIDATION_STRICT: "true" # reject requests with validation failures
662663
JSON_SCHEMA_VALIDATION_STRICT: "true" # reject tool registrations with invalid JSON schemas

docs/config.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,12 @@
874874
"title": "Experimental Validate Io",
875875
"type": "boolean"
876876
},
877+
"experimental_rust_validation_middleware_enabled": {
878+
"default": false,
879+
"description": "Enable experimental Rust sidecar for recursive validation middleware JSON checks",
880+
"title": "Experimental Rust Validation Middleware Enabled",
881+
"type": "boolean"
882+
},
877883
"failed_login_min_response_ms": {
878884
"default": 250,
879885
"description": "Minimum response duration for failed login attempts to reduce timing side channels",

docs/docs/best-practices/input-validation.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ ContextForge provides comprehensive input validation and output sanitization to
1818
# Enable experimental validation (default: false)
1919
EXPERIMENTAL_VALIDATE_IO=true
2020

21+
# Optional: enable the Rust JSON validation sidecar after `make rust-sidecar-install`
22+
EXPERIMENTAL_RUST_VALIDATION_MIDDLEWARE_ENABLED=false
23+
2124
# Enable validation middleware (default: false)
2225
VALIDATION_MIDDLEWARE_ENABLED=true
2326

@@ -49,6 +52,14 @@ The validation feature supports a phased roll-out approach:
4952
EXPERIMENTAL_VALIDATE_IO=false # Disabled in production
5053
```
5154

55+
#### Optional Rust Sidecar
56+
```bash
57+
make rust-sidecar-install
58+
EXPERIMENTAL_RUST_VALIDATION_MIDDLEWARE_ENABLED=true
59+
```
60+
61+
Enable this only after the sidecar is installed into the active virtual environment. If the sidecar is unavailable, the middleware falls back to the Python validator for standard validation failures.
62+
5263
#### Phase 1: Log-Only Mode (Dev/Staging)
5364
```bash
5465
EXPERIMENTAL_VALIDATE_IO=true

docs/docs/config.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,12 @@
477477
"title": "Experimental Validate Io",
478478
"type": "boolean"
479479
},
480+
"experimental_rust_validation_middleware_enabled": {
481+
"default": false,
482+
"description": "Enable experimental Rust sidecar for recursive validation middleware JSON checks",
483+
"title": "Experimental Rust Validation Middleware Enabled",
484+
"type": "boolean"
485+
},
480486
"validation_middleware_enabled": {
481487
"default": false,
482488
"description": "Enable validation middleware for all requests",

0 commit comments

Comments
 (0)