Affected area
Middleware or guardrails; Plugins; Observability or exporters
Current behavior
The built-in PII request sanitizer redacts LlmRequest.content but leaves LlmRequest.headers unchanged. The complete request, including headers, is serialized into the LLM start event. A direct API caller, custom integration, or request interceptor can therefore place a credential or identifier in a header and have it reach subscribers/exporters even though the request body is successfully redacted.
A real emitted-event probe preserved authorization: sk-header-secret while replacing matching secrets in the message body. This reproduces on current main (9d16c074) and PR #546 (3bff1751). The CLI gateway already filters common credential headers before constructing its observable request, so the standard gateway path is not the primary affected case.
Expected behavior
The PII plugin should define and enforce header sanitization for the emitted event copy without changing the request sent to the provider. A compatible contract would keep existing normalized content paths unchanged, add /headers/<escaped-name> for explicit header targeting, and make empty target_paths sanitize matching string leaves across both headers and content.
Steps to reproduce
- Enable built-in PII request sanitization with a pattern matching
sk-* and empty target_paths.
- Emit an
LlmRequest with authorization: sk-header-secret and a message containing sk-body-secret.
- Capture the LLM start event through a subscriber.
- Observe that the body contains
[REDACTED] while the header still contains sk-header-secret.
Environment
- NeMo Relay commits:
9d16c074 and 3bff1751
- OS and architecture: macOS arm64
- Rust: repository-pinned toolchain
- Reproduction: focused
nemo-relay-pii-redaction Rust unit test using the real event subscriber path
Impact
This affects direct managed-LLM API users, custom framework integrations, and interceptors that populate observable request headers. The standard gateway filters common authentication headers, which reduces exposure there, but the core/plugin contract does not protect arbitrary headers or custom integrations. The current workaround is for every producer to strip or sanitize headers before calling Relay.
Affected area
Middleware or guardrails; Plugins; Observability or exporters
Current behavior
The built-in PII request sanitizer redacts
LlmRequest.contentbut leavesLlmRequest.headersunchanged. The complete request, including headers, is serialized into the LLM start event. A direct API caller, custom integration, or request interceptor can therefore place a credential or identifier in a header and have it reach subscribers/exporters even though the request body is successfully redacted.A real emitted-event probe preserved
authorization: sk-header-secretwhile replacing matching secrets in the message body. This reproduces on currentmain(9d16c074) and PR #546 (3bff1751). The CLI gateway already filters common credential headers before constructing its observable request, so the standard gateway path is not the primary affected case.Expected behavior
The PII plugin should define and enforce header sanitization for the emitted event copy without changing the request sent to the provider. A compatible contract would keep existing normalized content paths unchanged, add
/headers/<escaped-name>for explicit header targeting, and make emptytarget_pathssanitize matching string leaves across both headers and content.Steps to reproduce
sk-*and emptytarget_paths.LlmRequestwithauthorization: sk-header-secretand a message containingsk-body-secret.[REDACTED]while the header still containssk-header-secret.Environment
9d16c074and3bff1751nemo-relay-pii-redactionRust unit test using the real event subscriber pathImpact
This affects direct managed-LLM API users, custom framework integrations, and interceptors that populate observable request headers. The standard gateway filters common authentication headers, which reduces exposure there, but the core/plugin contract does not protect arbitrary headers or custom integrations. The current workaround is for every producer to strip or sanitize headers before calling Relay.