Commit ef9e49b
feat: Add OpenTelemetry W3C Baggage support for distributed tracing (#4008)
* feat: add OTEL root and client spans for MCP flows
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* feat: extend OTEL MCP client trace lifecycle
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* feat: implement OpenTelemetry baggage header extraction (GitHub #3976)
Implements HTTP header-to-baggage conversion for distributed tracing with strict security controls:
**Core Features:**
- Dual trust model: UNTRUSTED headers (strict allowlist) vs TRUSTED baggage (permissive)
- Size limits (32 items, 8KB) apply ONLY to header-derived baggage
- Default behavior: capture as span attributes only
- Downstream propagation requires explicit opt-in via config flag
**Implementation:**
- mcpgateway/baggage.py: Core validation, parsing, and conversion logic
- mcpgateway/middleware/baggage_middleware.py: ASGI middleware for extraction
- mcpgateway/config.py: 7 new configuration fields with Pydantic validation
- mcpgateway/main.py: Middleware registration after OpenTelemetryRequestMiddleware
- mcpgateway/observability.py: Auto-inject baggage as span attributes, conditional propagation
**Security:**
- Reuses existing sanitize_header_value() and ALLOWED_HEADERS_REGEX
- Strict allowlist (only configured headers processed)
- CRLF injection prevention
- Size limits enforced (DoS prevention)
- Audit logging for rejected headers
- Fail-closed on errors
**Configuration:**
- OTEL_BAGGAGE_ENABLED: Enable/disable feature (default: false)
- OTEL_BAGGAGE_HEADER_MAPPINGS: JSON array of header-to-baggage mappings
- OTEL_BAGGAGE_PROPAGATE_TO_EXTERNAL: Enable downstream propagation (default: false)
- OTEL_BAGGAGE_MAX_ITEMS: Max items from headers (default: 32)
- OTEL_BAGGAGE_MAX_SIZE_BYTES: Max total size (default: 8192)
- OTEL_BAGGAGE_LOG_REJECTED: Log rejected headers (default: true)
- OTEL_BAGGAGE_LOG_SANITIZATION: Log sanitization events (default: true)
**Testing:**
- 44 unit tests (baggage.py logic)
- 13 integration tests (middleware flow)
- 6 E2E tests (full tracing flow)
- 18 security tests (deny-path scenarios)
Closes #3976
Signed-off-by: Bob Shell <bob@contextforge.ai>
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* fix: correct middleware order and inject baggage into request spans
- Swap BaggageMiddleware and OpenTelemetryRequestMiddleware registration order
(ASGI executes in reverse, so baggage must be set before span creation)
- Add baggage injection to OpenTelemetryRequestMiddleware request spans
- Update FastTimeUser load test to include baggage test headers
- Add baggage configuration documentation to .env.example
This ensures baggage attributes appear in all spans, including the root
request span created by OpenTelemetryRequestMiddleware.
Signed-off-by: Bob Shell <bob@example.com>
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* fix: finalize otel baggage header extraction rebase
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* chore: update test artifacts and documentation
- Update .secrets.baseline
- Refine baggage implementation and tests
- Update observability documentation
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* feat: enhance baggage configuration with comprehensive examples and security documentation
- Add structured section header with clear delineation
- Document common use cases (multi-tenant, user context, request correlation, feature flags, security)
- Provide 4 comprehensive configuration examples with multiple header mappings
- Add detailed security implications for OTEL_BAGGAGE_PROPAGATE_TO_EXTERNAL
- Include guidance on when to enable external propagation and alternatives
- Enhance descriptions for OTEL_BAGGAGE_MAX_ITEMS and OTEL_BAGGAGE_MAX_SIZE_BYTES with W3C spec references
Addresses PR feedback for comprehensive baggage configuration documentation.
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* fix: correct mock patch location in baggage tracing E2E tests
- Patch get_settings in mcpgateway.observability module where it's used
- Previously patched mcpgateway.config.get_settings which didn't affect the imported reference
- Fixes test_baggage_propagated_to_downstream and test_baggage_sanitized_before_propagation
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
* test: add comprehensive coverage for baggage middleware main flow
- Add test_baggage_middleware_main_flow.py with 7 tests covering lines 210-237
- Add test_baggage_middleware_comprehensive.py with 5 additional middleware tests
- Add test_baggage_middleware_coverage.py with 7 edge case tests
- Add test_baggage_middleware_final.py with 3 integration-style tests
- Add test_baggage_parsing.py with 2 supplementary parsing edge case tests
- Add test_observability_baggage_exceptions.py for baggage exception handling
- Add test_auth_coverage.py, test_main_baggage_coverage.py, test_main_module_init.py, test_observability_coverage.py for additional coverage
- Update test_baggage.py with improved formatting and structure
- Update mcpgateway/observability.py with formatting improvements
- Achieve 94% coverage for baggage_middleware.py (up from 71%)
- Achieve 99% coverage for baggage.py
- All 26 new/updated tests passing
Remaining coverage gaps (6% in baggage_middleware.py, 1% in baggage.py) are defensive exception paths that are difficult to trigger in unit tests without mocking internal library behavior.
Closes coverage gaps identified in diff-cover report for baggage-related files.
Signed-off-by: Jonathan Springer <jps@s390x.com>
---------
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
Signed-off-by: Bob Shell <bob@contextforge.ai>
Signed-off-by: Bob Shell <bob@example.com>
Signed-off-by: Jonathan Springer <jps@s390x.com>
Co-authored-by: Jonathan Springer <jps@s390x.com>1 parent 65dda0e commit ef9e49b
25 files changed
Lines changed: 5213 additions & 33 deletions
File tree
- docs/docs/architecture
- mcpgateway
- middleware
- services
- tests
- e2e
- integration
- loadtest
- security
- unit/mcpgateway
- middleware
- services
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2367 | 2367 | | |
2368 | 2368 | | |
2369 | 2369 | | |
| 2370 | + | |
| 2371 | + | |
| 2372 | + | |
| 2373 | + | |
| 2374 | + | |
| 2375 | + | |
| 2376 | + | |
| 2377 | + | |
| 2378 | + | |
| 2379 | + | |
| 2380 | + | |
| 2381 | + | |
| 2382 | + | |
| 2383 | + | |
| 2384 | + | |
| 2385 | + | |
| 2386 | + | |
| 2387 | + | |
| 2388 | + | |
| 2389 | + | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
| 2395 | + | |
| 2396 | + | |
| 2397 | + | |
| 2398 | + | |
| 2399 | + | |
| 2400 | + | |
| 2401 | + | |
| 2402 | + | |
| 2403 | + | |
| 2404 | + | |
| 2405 | + | |
| 2406 | + | |
| 2407 | + | |
| 2408 | + | |
| 2409 | + | |
| 2410 | + | |
| 2411 | + | |
| 2412 | + | |
| 2413 | + | |
| 2414 | + | |
| 2415 | + | |
| 2416 | + | |
| 2417 | + | |
| 2418 | + | |
| 2419 | + | |
| 2420 | + | |
| 2421 | + | |
| 2422 | + | |
| 2423 | + | |
| 2424 | + | |
| 2425 | + | |
| 2426 | + | |
| 2427 | + | |
| 2428 | + | |
| 2429 | + | |
| 2430 | + | |
| 2431 | + | |
| 2432 | + | |
| 2433 | + | |
| 2434 | + | |
| 2435 | + | |
| 2436 | + | |
| 2437 | + | |
| 2438 | + | |
| 2439 | + | |
| 2440 | + | |
| 2441 | + | |
| 2442 | + | |
| 2443 | + | |
| 2444 | + | |
| 2445 | + | |
| 2446 | + | |
| 2447 | + | |
| 2448 | + | |
| 2449 | + | |
| 2450 | + | |
| 2451 | + | |
| 2452 | + | |
| 2453 | + | |
| 2454 | + | |
| 2455 | + | |
| 2456 | + | |
| 2457 | + | |
| 2458 | + | |
| 2459 | + | |
| 2460 | + | |
| 2461 | + | |
| 2462 | + | |
| 2463 | + | |
| 2464 | + | |
| 2465 | + | |
| 2466 | + | |
| 2467 | + | |
| 2468 | + | |
| 2469 | + | |
| 2470 | + | |
| 2471 | + | |
| 2472 | + | |
| 2473 | + | |
| 2474 | + | |
| 2475 | + | |
| 2476 | + | |
| 2477 | + | |
| 2478 | + | |
| 2479 | + | |
| 2480 | + | |
| 2481 | + | |
| 2482 | + | |
| 2483 | + | |
2370 | 2484 | | |
2371 | 2485 | | |
2372 | 2486 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
9166 | 9166 | | |
9167 | 9167 | | |
9168 | 9168 | | |
9169 | | - | |
| 9169 | + | |
9170 | 9170 | | |
9171 | 9171 | | |
9172 | 9172 | | |
| |||
18920 | 18920 | | |
18921 | 18921 | | |
18922 | 18922 | | |
18923 | | - | |
| 18923 | + | |
18924 | 18924 | | |
18925 | 18925 | | |
18926 | 18926 | | |
18927 | 18927 | | |
18928 | 18928 | | |
18929 | 18929 | | |
18930 | 18930 | | |
18931 | | - | |
| 18931 | + | |
18932 | 18932 | | |
18933 | 18933 | | |
18934 | 18934 | | |
18935 | 18935 | | |
18936 | 18936 | | |
18937 | 18937 | | |
18938 | 18938 | | |
18939 | | - | |
| 18939 | + | |
18940 | 18940 | | |
18941 | 18941 | | |
18942 | 18942 | | |
18943 | 18943 | | |
18944 | 18944 | | |
18945 | 18945 | | |
18946 | 18946 | | |
18947 | | - | |
| 18947 | + | |
18948 | 18948 | | |
18949 | 18949 | | |
18950 | 18950 | | |
| |||
21436 | 21436 | | |
21437 | 21437 | | |
21438 | 21438 | | |
21439 | | - | |
| 21439 | + | |
21440 | 21440 | | |
21441 | 21441 | | |
21442 | 21442 | | |
21443 | 21443 | | |
21444 | 21444 | | |
21445 | 21445 | | |
21446 | 21446 | | |
21447 | | - | |
| 21447 | + | |
21448 | 21448 | | |
21449 | 21449 | | |
21450 | 21450 | | |
21451 | 21451 | | |
21452 | 21452 | | |
21453 | 21453 | | |
21454 | 21454 | | |
21455 | | - | |
| 21455 | + | |
21456 | 21456 | | |
21457 | 21457 | | |
21458 | 21458 | | |
21459 | 21459 | | |
21460 | 21460 | | |
21461 | 21461 | | |
21462 | 21462 | | |
21463 | | - | |
| 21463 | + | |
21464 | 21464 | | |
21465 | 21465 | | |
21466 | 21466 | | |
21467 | 21467 | | |
21468 | 21468 | | |
21469 | 21469 | | |
21470 | 21470 | | |
21471 | | - | |
| 21471 | + | |
21472 | 21472 | | |
21473 | 21473 | | |
21474 | 21474 | | |
21475 | 21475 | | |
21476 | 21476 | | |
21477 | 21477 | | |
21478 | 21478 | | |
21479 | | - | |
| 21479 | + | |
21480 | 21480 | | |
21481 | 21481 | | |
21482 | 21482 | | |
21483 | 21483 | | |
21484 | 21484 | | |
21485 | 21485 | | |
21486 | 21486 | | |
21487 | | - | |
| 21487 | + | |
21488 | 21488 | | |
21489 | 21489 | | |
21490 | 21490 | | |
| |||
0 commit comments