Skip to content

[CRED-2625] Redact ContextAccessToken in debug request dump#4098

Draft
luczhou wants to merge 1 commit into
masterfrom
lucinda.zhou/CRED-2625/redact-context-access-token
Draft

[CRED-2625] Redact ContextAccessToken in debug request dump#4098
luczhou wants to merge 1 commit into
masterfrom
lucinda.zhou/CRED-2625/redact-context-access-token

Conversation

@luczhou
Copy link
Copy Markdown

@luczhou luczhou commented May 15, 2026

Description

The debug-dump path in CallAPI() (api/datadog/client.go:171-184) redacts api/app key values pulled from ContextAPIKeys before logging the captured request bytes. The Authorization header set from ContextAccessToken (delegated tokens, PATs) is dumped verbatim — any caller running with Cfg.Debug = true and access-token auth leaks the bearer to the global logger.

Surfaced by terraform-provider-datadog#3757, which is the first Terraform code path to set ContextAccessToken. With TF_LOG=DEBUG, the PAT would land in Terraform stderr, CI artifacts, and downstream log shippers — a self-contained bearer is full account-impersonating compromise until rotated.

Tracking ticket: CRED-2625.

Changes

  • .generator/src/generator/templates/client.j2:175-189: extend the existing redaction block to also walk ContextAccessToken from the request context. Compile a regexp.QuoteMeta-escaped pattern from the token value and ReplaceAll it with REDACTED in the dump bytes.
  • api/datadog/client.go: mirror the same edit in the generated file so the diff matches what the next regen produces.
  • tests/api/client_test.go: add TestDebugDumpRedactsAccessToken — drives CallAPI against an httptest.Server with Cfg.Debug = true and a ContextAccessToken-bearing context (plus a matching Authorization header to simulate what PrepareRequest sets in production). Captures the global logger output and asserts the token value does not appear in the dump and REDACTED does.

Out of scope, left for follow-ups:

  • The existing api-keys loop has two latent bugs (missing regexp.QuoteMeta, no empty-key guard). Keeping this PR minimal — happy to file a separate cleanup PR.
  • The response-dump block (client.go:192-200) has no redaction at all. Lower risk since responses rarely echo auth headers, but worth fixing in a follow-up.

Cross-language

Related work tracked under CRED-2625:

  • datadog-api-client-typescript PR: same fix shape (add Authorization to allowlist in isomorphic-fetch.ts:logRequest).
  • datadog-api-client-ruby PR: same fix shape (add Authorization to sanitize_request_header's keys_to_redact).
  • datadog-api-client-java GH issue: wider gap — Jersey LoggingFeature.PAYLOAD_ANY has no header redaction at all, so api/app keys and bearer leak in debug mode. Tracked as an issue for api-platform guidance on the right shape.
  • datadog-api-client-python: no equivalent gap (the rest.j2 debug path logs only response body, not request headers).

Testing

  • go test ./tests/api/... -run TestDebugDumpRedactsAccessToken passes
  • Existing tests/api/client_test.go suite still passes (4 tests, all green)
  • go build ./api/datadog/... clean
  • Regen confirms template ↔ generated parity (api-platform CI)

🤖 Generated with Claude Code

The debug-dump path at CallAPI() redacts api/app key values pulled from
ContextAPIKeys before logging the captured request bytes. The
Authorization header set from ContextAccessToken (delegated tokens,
PATs) is dumped verbatim — any caller running with Cfg.Debug = true and
access-token auth leaks the bearer to the global logger.

This was surfaced by terraform-provider-datadog#3757, which is the
first Terraform code path to set ContextAccessToken. With TF_LOG=DEBUG,
the PAT would land in Terraform stderr, CI artifacts, and downstream
log shippers.

Extend the redaction block to also walk ContextAccessToken from the
request context and ReplaceAll the token bytes with REDACTED. Apply
the change to both the .j2 template and the generated client.go so the
file matches what the next regen produces; latent bugs in the existing
api-keys loop (missing regexp.QuoteMeta, no empty-key guard) are left
for a follow-up PR to keep this one minimal.

Test (tests/api/client_test.go:TestDebugDumpRedactsAccessToken)
captures the global logger output, drives CallAPI with a
ContextAccessToken-bearing context and a matching Authorization
header, and asserts the token value does not appear in the dump and
REDACTED does.

Refs: CRED-2625, terraform-provider-datadog#3757

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant