Repository navigation
Redact credentials from requests sent to external backends - #94
Merged
Merged
Conversation
Add opt-in egress redaction. With security.redactEgress (default false), the gateway replaces credentials in request text with [secret] before forwarding to a backend whose baseUrl host is outside the local network. backends.<id>.redact overrides the decision in either direction. - Patterns ported from Tessera's Steward redactor, plus URL passwords (mongodb+srv://, postgres://, redis://, ...); sk- already covers OpenRouter sk-or-v1- keys. Labelled values keep their label, need 6+ characters, and skip unquoted values that read as code. - Applied once, after protocol translation, in a fetchModelUpstream wrapper used by every JSON model route, and to the OpenRouter/Replicate audio and video provider adapters. Chat, Responses and Anthropic bridges, streaming or not, share it. - Internal: loopback, RFC1918, link-local, 100.64/10, fc00::/7, .ts.net, .local, .internal and single-label hosts, and federated LLooM gateways. - Embeddings and transcriptions are never rewritten. The caller's body is not mutated, and only a per-request count is logged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Opt-in egress redaction. The gateway replaces credentials in request text with
[secret]before it forwards a request to a backend outside the local network, such as DeepSeek or OpenRouter.Config
security.redactEgress(defaultfalse, validated as a boolean): redact for every external backend.backends.<id>.redact: true | false(validated as a boolean): overrides the automatic decision in either direction.trueapplies even when the global switch is off.baseUrlhost. Internal hosts are loopback, RFC 1918, link-local,100.64.0.0/10,fc00::/7,.ts.net/.local/.internal/.localhost, and unqualified single-label names. Backends withaudioProviderorvideoProvideralways count as external, because those adapters call OpenRouter or Replicate directly. Federated LLooM gateways (isFederatedGatewayBackend) count as internal, since the downstream gateway applies its own policy.Coverage
fetchModelUpstreamwrapper. It replaces the duplicatedheadersandbackendlines at all 11 JSONfetchUpstreamcall sites. The audio and video provider adapter calls also go through the sameegressBody./v1/completionsroute.promptis still handled generically.content(strings and text parts),tool_calls[].function.arguments,role: toolresults, replayedreasoning_content/reasoning,prompt,input,instructionsandsystem. Image, audio and file parts are untouched.Patterns
scheme://user:[secret]@host).sk-pattern already covers OpenRoutersk-or-v1-keys, and a test checks that.getToken(),process.env.X,$TOKEN, words with no digits or symbols) are skipped.The caller's object is never mutated. Matched values are never logged; one info line records the replacement count and the backend ID.
Tests
node --test test/egress-redaction.test.mjs(new, 18 tests). It covers each pattern, URL credentials, prose and code false positives, JSON validity, body shapes and non-mutation, host classification, policy and overrides, federation, config validation, and gateway integration through a mocked undici dispatcher (chat buffered and streaming, Responses, Anthropic, embeddings and transcriptions passthrough, off or overridden).openrouter-provider,security,model-failover,responses-codex,video-providers,protocol,protocol-stream,server-resilience,stream-metrics, andnode --testforaudio-generations,standby,federated-priorityandaudio-providers.🤖 Generated with Claude Code