Skip to content

Redact URL paths in network request telemetry spans#85

Merged
brandonc merged 6 commits into
mainfrom
TF-39193-redact-url-paths-in-network-req-telemetry-spans
Jul 16, 2026
Merged

Redact URL paths in network request telemetry spans#85
brandonc merged 6 commits into
mainfrom
TF-39193-redact-url-paths-in-network-req-telemetry-spans

Conversation

@brandonc

Copy link
Copy Markdown
Collaborator

Description

Redact customer data from HTTP paths in telemetry payloads.

PR Checklist

  • Run npx changie new or install changie to prepare a new changelog entry for the next set of release notes.

PCI review checklist

  • I have documented a clear reason for, and description of, the change I am making.

  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.

  • If applicable, I've documented the impact of any changes to security controls.

    Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.

@brandonc
brandonc force-pushed the TF-39193-redact-url-paths-in-network-req-telemetry-spans branch from 369b608 to e0fe6ce Compare July 16, 2026 21:56
Comment thread internal/pkg/telemetry/telemetry.go Outdated
)
hostname := info.Profile.GetHostname()
if !info.Profile.IsHCPTerraform() {
if !info.Profile.IsHCPTerraform() && hostname != "archivist.terraform.io" && hostname != "archivist.eu.terraform.io" {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This might be a better condition:

!strings.HasSuffix("terraform.io")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I like moving off the hardcoded list but it needs the two-arg form and without a dot boundary a wrong url could go through or if there's a port on the hostname, which GetHostname() allows. Something like:

func isKnownHCPHost(h string) bool {
    h, _, _ = strings.Cut(h, ":")
    return h == "terraform.io" || strings.HasSuffix(h, ".terraform.io")
}

and then if !isKnownHCPHost(hostname) { hostname = generateStableID(...) }, The main thing I want to keep is that unknown hosts still get hashed by default

var (
// Redactions should use capture groups to identify sensitive segments of a path, which
// will be replaced with a redaction placeholder.
redactions = []*regexp.Regexp{

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The module regex only redacts the namespace. I ran this against a realistic path and the module name and provider still leak:
/v1/modules/hashicorp/consul/aws/1.0.0/download/v1/modules/<redacted>/consul/aws/1.0.0/download
Compare with the registry-providers rule just below, which correctly redacts two segments. For private modules the name/provider are customer data too so should this be /v1/modules/([^/]+)/([^/]+)/([^/]+) or similar?

Comment thread TELEMETRY.md Outdated
| http.duration_ms | 855 | Request latency |
| Key | Example Value | Source |
|---------------------|--------------------------|-------------------------------------|
| http.path | “/workspaces/<redacted>” | API request path, with IDs redacted |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A bare /api/v2/workspaces/ws-abc123 is not redacted only /organizations/{org}/workspaces/{ws} matches

Comment thread internal/pkg/inputguard/inputguard.go Outdated
lastIndex := 0

// indices[0] and indices[1] are the start/end of the FULL match.
// Capture groups start at index index 2 (indices[2] to indices[3] is Group 1, etc.)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

typo

Comment thread internal/pkg/inputguard/inputguard.go Outdated
// Write whatever remains of the path after the last redacted group
result.WriteString(path[lastIndex:])

// Update path and return (or continue to next regex if paths can match multiple rules)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

the comment says continue but the loop never returns early

@brandonc
brandonc merged commit f2a10a8 into main Jul 16, 2026
2 checks passed
@brandonc
brandonc deleted the TF-39193-redact-url-paths-in-network-req-telemetry-spans branch July 16, 2026 22:41
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.

2 participants