Skip to content

fix: redact end-user identifiers, locations and credentials in extproc debug logs - #2981

Open
hustxiayang wants to merge 5 commits into
theagentrouter:mainfrom
hustxiayang:redact-end-user-identifiers
Open

hustxiayang wants to merge 5 commits into
theagentrouter:mainfrom
hustxiayang:redact-end-user-identifiers

Conversation

@hustxiayang

@hustxiayang hustxiayang commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Description

With redaction enabled, the extproc debug log still carried end-user identifiers (user, safety_identifier, metadata, location, …), content that restates the prompt, and MCP credentials, because each endpoint redacts only the fields it names. This PR redacts them in the request redactors. In the translator response logs, it redacts thinking_blocks (OpenAI, Bedrock, Vertex AI and GCP Anthropic translators) and the reasoning signature and redactedContent, where only the reasoning text was redacted before. #2980 lists every field and why it must be redacted.

It also adds site/docs/capabilities/observability/debug-log-redaction.md, so operators can see what enableRedaction covers, what it keeps, the placeholder format, and how it differs from OPENINFERENCE_HIDE_* trace hiding.

Related Issues/PRs (if applicable)

Fixes #2980

Special notes for reviewers (if applicable)

  • Anthropic mcp_servers keeps a list of safe keys instead of a list of secret keys. Our schema does not model MCP server entries (type MCPServer any), so each entry is whatever map the caller sent. The redactor keeps only type, name and tool_configuration and redacts every other key. If Anthropic adds a new credential field, it is redacted without a code change, whereas a list of keys to redact would log it until someone updated the list. This is the only keep-list in the change, so it should not be converted to match the others.
  • Reasoning signatures are redacted even though they are encrypted. A signature carries the full reasoning, so it can be large, and every other copy of the reasoning is already redacted. The placeholder hash still shows whether two signatures match, which is what debugging an "invalid signature" error needs.

@hustxiayang
hustxiayang requested a review from a team as a code owner November 4, 2026 17:12
@netlify

netlify Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for theagentrouter canceled.

Name Link
🔨 Latest commit 2d35d56
🔍 Latest deploy log https://app.netlify.com/projects/theagentrouter/deploys/6aecf49fb2293804df6c7585

@codecov

codecov Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.03922% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/endpointspec/endpointspec.go 98.31% 2 Missing ⚠️
internal/translator/openai_openai.go 95.45% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@aabchoo

aabchoo commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

/retest

Signed-off-by: yxia216 <yxia216@bloomberg.net>
Signed-off-by: yxia216 <yxia216@bloomberg.net>
Signed-off-by: yxia216 <yxia216@bloomberg.net>
Signed-off-by: yxia216 <yxia216@bloomberg.net>
@hustxiayang
hustxiayang force-pushed the redact-end-user-identifiers branch from 786a9e8 to f078ea0 Compare November 5, 2026 14:51

@aabchoo aabchoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me!

- **Redacted: end-user identifiers and free-form caller annotations**, such as `user`, `safety_identifier` and `metadata` values. These are usually set by the application rather than typed by the end user, but their values identify a person, and the gateway cannot tell whether the application hashed them.
- **Kept: model and format configuration**, such as the model name, sampling parameters, tool definitions and response format schemas. These describe how to call the model rather than who is calling or what they said, and keeping them makes the logs useful for debugging.

Response bodies are redacted as a whole.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to be:

The external processor logs the response body as a single placeholder. Translators additionally log the parsed response with message content, reasoning, tool arguments and audio redacted; metadata such as the response id, model, usage and tool names is kept.

redactInPlace(&location.City, &location.Region, &location.Country, &location.Timezone)
return openai.ResponseToolUnion{OfWebSearchPreview: &webSearch}
case tool.OfUnknown != nil:
return openai.ResponseToolUnion{OfUnknown: redactRawJSON(tool.OfUnknown)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we try to parse the type if possible? Otherwise we get no info

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

# Debug log leaks end-user identifiers, locations and credentials when redaction is enabled

2 participants