Skip to content

fix(logging): mask *-api-key headers in request-log pipeline - #13401

Merged
diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.51from
KooshaPari:pr/13273-header-mask-apivkey
Sep 15, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.51from
KooshaPari:pr/13273-header-mask-apivkey

Conversation

@KooshaPari

Copy link
Copy Markdown
Contributor

Summary

maskSensitiveHeaders in open-sse/utils/requestLogger.ts matched a hardcoded substring list that missed several real upstream credential headers:

Header Provider Was masked?
x-goog-api-key Gemini / Vertex ❌ unmasked
api-key Azure OpenAI ❌ unmasked
xi-api-key ElevenLabs ❌ unmasked
x-api-key Anthropic ✅ masked

These passed through verbatim into the request-log pipeline (logTargetRequest → getPipelinePayloads).

Fix

1. Compact header matching (open-sse/utils/requestLogger.ts):

Strip hyphens from both the header key and each candidate before comparing, so the "apikey" catch-all in sensitiveKeys matches every current and future *-api-key spelling:

const compactedKey = lowerKey.replace(/-/g, "");
if (!sensitiveKeys.some((c) => compactedKey.includes(c.replace(/-/g, "")))) continue;

2. Add xi-api-key to SENSITIVE_KEYS (src/lib/logPayloads.ts):

Defense-in-depth for body-level redaction via protectPayloadForLog / redactPayload.

Tests

New regression test file tests/unit/request-logger-header-mask-apikey-13273.test.ts with 7 tests covering:

  • x-goog-api-key (Gemini) — previously unmasked, now masked
  • api-key (Azure OpenAI) — previously unmasked, now masked
  • xi-api-key (ElevenLabs) — previously unmasked, now masked
  • x-api-key (Anthropic) — still masked (regression guard)
  • x-ratelimit- headers — still NOT masked (whitelist preserved)
  • protectPayloadForLog redacts xi-api-key and x-goog-api-key in body payloads

All existing tests pass: request-log-payloads (26/26), request-logger-bounded-idempotence (6/6).

Related

Fixes #13273

…uzapw#13273)

maskSensitiveHeaders in requestLogger.ts matched a hardcoded substring
list that missed several real upstream credential headers:

- x-goog-api-key (Gemini / Vertex)
- api-key (Azure OpenAI)
- xi-api-key (ElevenLabs proxy)

These passed through completely unmasked into the request-log pipeline.

Fix:
1. Normalize header names by stripping hyphens before matching
   (compacted comparison), so the "apikey" catch-all in sensitiveKeys
   matches every current and future *-api-key spelling.
2. Add xi-api-key to SENSITIVE_KEYS in logPayloads.ts for body-level
   redaction via protectPayloadForLog / redactPayload.

Regression tests cover all three previously-missing headers plus the
existing x-api-key (Anthropic) path and the x-ratelimit- whitelist.

Fixes diegosouzapw#13273
Copilot AI lite review requested due to automatic review settings September 12, 2026 05:50

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@diegosouzapw
diegosouzapw merged commit 8bad85f into diegosouzapw:release/v3.8.51 Sep 15, 2026
8 of 16 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…uzapw#13273) (diegosouzapw#13401)

Masks every `*-api-key` header spelling (`x-goog-api-key`, `api-key`, `xi-api-key`) in the request-log pipeline by matching on the hyphen-compacted key, and adds `xi-api-key` to the payload redaction set (diegosouzapw#13273). The new test drives the real `createRequestLogger` / `protectPayloadForLog` paths.

Validated in one consolidated batch of this series (37 PRs boarded together on `release/v3.8.51`): `typecheck:core`, `check:open-sse-typecheck` and `check:dashboard-typecheck` clean; ESLint clean on every changed file; file-size, complexity, cognitive-complexity, changelog-integrity, docs-counts, docs-sync and migration-numbering gates green (only the pre-existing `open-sse/utils/stream.ts` file-size red remains, inherited from the base); 3,743 focused `node:test` cases plus 34 vitest cases green.

Thanks @KooshaPari!
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.

fix(backend): request-log header mask misses *-api-key spellings, provider keys land in log pipeline unmasked

3 participants