Skip to content

Redact PII (paths, URIs, GUIDs, component names) from LSP telemetry#340

Draft
anderson-joyle wants to merge 2 commits into
mainfrom
andersonf/pii-fixes
Draft

Redact PII (paths, URIs, GUIDs, component names) from LSP telemetry#340
anderson-joyle wants to merge 2 commits into
mainfrom
andersonf/pii-fixes

Conversation

@anderson-joyle

Copy link
Copy Markdown
Contributor

Summary

Redacts personal data (EUII) that C# language-server log call sites were emitting into telemetry (App Insights). This originated from analysis of a support telemetry export where full file paths (containing a user name and org-unit), agent/component names, and environment/bot GUIDs were visible in the traces table.

The fix routes the leaking call sites through the existing LogSensitiveInformation mechanism (or does in-place redaction where that API isn't available). Geo information is intentionally left untouched — it is derived by App Insights from the request IP, not from log message content.

Changes

File Leak removed from telemetry Approach
LanguageServer.cs Full file URI in "Failed to get language" LogError(URI-free) + LogSensitiveInformation(full)
LspExceptionHandler.cs File paths in FileNotFound / DirectoryNotFound messages path-free LogError + LogSensitiveInformation(full); full message is still returned to the client
DidChangeWatchedFilesHandler.cs Agent / component file names (4 log lines) Info lines → LogSensitiveInformation; the "file does not exist" warning drops the name (retained in Debug)
LspUriFactory.cs URI/path sample in unsupported-scheme log LogSensitiveInformation(full, scheme-only safe message)
LoggingHttpHandler.cs Environment / bot GUIDs in HTTP request paths in-place regex → {id}
HostApplicationBuilderExtensions.cs Named-pipe / unix-socket path at IPC startup log transport kind only

Behavior notes

  • Severity preserved. Error/Warning sites keep their Error/Warning level in telemetry; the full (sensitive) detail is available locally in Debug via LogSensitiveInformation.
  • The FileNotFound / DirectoryNotFound telemetry message becomes generic ("File not found." / "Directory not found."). The full, path-bearing message is unchanged in the client response and in Debug.
  • The "file does not exist" watched-file warning no longer includes the file name in telemetry (kept in Debug).

Tests

  • Updated ChangeMethodTests (the per-file "file does not exist" message now surfaces at Info via LogSensitiveInformation in Debug/test builds).
  • Added GetPathAndQuery_Redacts_Guids_In_Path to LoggingHttpHandlerTests.
  • Full unit suite: 873 passing, solution builds with 0 warnings.

Out of scope (possible follow-ups)

  • GetCloudCacheFileHandler.cs schema-name logs (a separate PII class).
  • JsonRpcStream.cs {ex} last-resort diagnostic dumps.
  • Non-file exception branches in LspExceptionHandler (InvalidOperation / Http / etc.).

Copilot AI review requested due to automatic review settings July 10, 2026 15:56

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.

Pull request overview

This PR reduces exposure of end-user identifiable information (EUII/PII) in App Insights telemetry emitted by the PowerPlatformLS language server by routing sensitive log content through ILspLogger.LogSensitiveInformation (or by redacting GUIDs inline) while keeping telemetry-visible messages path/URI/name-free.

Changes:

  • Reworked several LSP/server log call sites to emit safe telemetry messages while preserving sensitive detail for local Debug/test logging via LogSensitiveInformation.
  • Redacted GUIDs from HTTP request PathAndQuery in LoggingHttpHandler to avoid leaking environment/bot identifiers in telemetry.
  • Updated/added unit tests to reflect the new logging/redaction behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/LanguageServers/PowerPlatformLS/UnitTests/PowerPlatformLS.UnitTests/Impl.PullAgent/LoggingHttpHandlerTests.cs Adds coverage ensuring GUIDs are redacted from logged HTTP request paths.
src/LanguageServers/PowerPlatformLS/UnitTests/PowerPlatformLS.UnitTests/Impl.Core/ChangeMethodTests.cs Updates expectations for watched-file logging now that sensitive details flow via LogSensitiveInformation.
src/LanguageServers/PowerPlatformLS/Impl.PullAgent/LspExceptionHandler.cs Prevents filesystem paths in FileNotFound/DirectoryNotFound exception messages from entering telemetry while returning full messages to the client.
src/LanguageServers/PowerPlatformLS/Impl.PullAgent/LoggingHttpHandler.cs Introduces GUID redaction in logged request paths/queries using a compiled regex replacement.
src/LanguageServers/PowerPlatformLS/Impl.Core/LSP/Uris/LspUriFactory.cs Ensures unsupported-scheme logs only include scheme in telemetry, keeping full samples local-only.
src/LanguageServers/PowerPlatformLS/Impl.Core/LSP/LanguageServer.cs Removes raw URI/file-path logging from telemetry when language resolution fails, preserving detail locally.
src/LanguageServers/PowerPlatformLS/Impl.Core/LSP/Handlers/DidChangeWatchedFilesHandler.cs Routes agent/component file-name-bearing watched-file logs through LogSensitiveInformation; makes the Warning message telemetry-safe.
src/LanguageServers/PowerPlatformLS/Impl.Core/DependencyInjection/HostApplicationBuilderExtensions.cs Removes named-pipe/unix-socket path details from IPC startup logs.

Comment on lines +73 to 76
// The full message (with file name) is routed through LogSensitiveInformation,
// which surfaces at Info level in Debug/test builds; the Warning is now file-name-free.
Assert.Single(logs.Info.Where(x => x == $"Can't process 'Changed' event for '{entry.filepath.Split('/')[^1]}': The file does not exist."));
}
Route language-server log call sites that leaked full file URIs/paths,
environment/bot GUIDs, and agent/component file names into telemetry through
the existing LogSensitiveInformation mechanism (or in-place redaction where
that API isn't available). Geo information is unaffected (it derives from
App Insights IP geolocation, not log messages).

- LanguageServer: "Failed to get language" now logs a URI-free Error plus the
  full URI via LogSensitiveInformation (debug-only).
- LspUriFactory: unsupported-scheme sample redacted to scheme-only in telemetry.
- LspExceptionHandler: File/DirectoryNotFound log a path-free Error; full
  message still returned to the client and surfaced locally.
- DidChangeWatchedFilesHandler: file-name log lines redacted (Info lines via
  LogSensitiveInformation; the "file does not exist" warning drops the name,
  preserved in debug).
- LoggingHttpHandler: GUIDs in request paths replaced with {id}.
- HostApplicationBuilderExtensions: IPC startup logs transport kind only.

Updated ChangeMethodTests (per-file message now surfaces at Info) and added a
GUID-redaction test for LoggingHttpHandler. Full unit suite: 873 passing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f6d50381-bfe9-4a08-9a2d-d650cd7f5b42
Copilot AI review requested due to automatic review settings July 13, 2026 15:11

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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment on lines +73 to +75
// The full message (with file name) is routed through LogSensitiveInformation,
// which surfaces at Info level in Debug/test builds; the Warning is now file-name-free.
Assert.Single(logs.Info.Where(x => x == $"Can't process 'Changed' event for '{entry.filepath.Split('/')[^1]}': The file does not exist."));
@anderson-joyle

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Copilot AI review requested due to automatic review settings July 20, 2026 16:27

Copilot AI commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved the merge conflicts and merged main into this branch in 40126ae.

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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

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.

3 participants