Dev Spec - Add generic exception-content redaction with WithExceptionScrubber#6094
Open
gladjohn wants to merge 2 commits into
Open
Dev Spec - Add generic exception-content redaction with WithExceptionScrubber#6094gladjohn wants to merge 2 commits into
gladjohn wants to merge 2 commits into
Conversation
Document the design for generic exception-content redaction in MSAL .NET, outlining goals, principles, public API, built-in behavior, and integration with Microsoft.Identity.Web.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a design document describing a proposed MSAL.NET mechanism for redacting sensitive, token-like content from MSAL-owned exception Message / ResponseBody, including a host-provided scrubber hook and an always-on baseline scrubber to preserve downstream routing signals (e.g., AADSTS* / AADB2C*).
Changes:
- Introduces a new design spec for exception-content redaction, including goals/non-goals, pipeline architecture, and failure-mode guarantees.
- Documents proposed public API shape (
MsalExceptionScrubberdelegate +WithExceptionScrubberbuilder hook) and downstream compatibility constraints for Microsoft.Identity.Web.
Comment on lines
+166
to
+169
| ## 13. Compatibility and behavior change | ||
| - **Additive, net-new public surface:** one delegate type (`MsalExceptionScrubber`) and one builder method (`WithExceptionScrubber`). No breaking changes to existing APIs, no exception-type or error-code changes, no control-flow changes. | ||
| - **Behavior change to call out:** with redaction at creation, `Message` and `ResponseBody` may now return redacted text where they previously returned raw content; additionally, the baseline-only `ToString` final pass changes string rendering. Document in release notes. | ||
| - **Public API review** must include `PublicAPI.Unshipped.txt` updates for the `MsalExceptionScrubber` delegate and the `WithExceptionScrubber` method. The exact entries are determined by the repo tooling. Whether any baseline redaction patterns are exposed as public API is a separate decision (see Open questions); otherwise the baseline rules remain implementation details. |
Comment on lines
+39
to
+41
| - Input: a piece of MSAL-owned exception content (a message or a response body). | ||
| - Output: redacted content, or the original content if no redaction is needed. | ||
| - Contract: may be called multiple times; should be thread-safe, deterministic, idempotent; must not assume a format (plain text vs JSON); should not throw — if it throws, MSAL treats that as scrubber failure and continues with the baseline; **should preserve diagnostic routing tokens (see Section 12).** |
Comment on lines
+43
to
+46
| **Builder hook:** | ||
| ```csharp | ||
| WithExceptionScrubber(MsalExceptionScrubber scrubber) -> T | ||
| ``` |
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
MSAL surfaces service/server error responses through exceptions, and applications commonly log those exceptions. If an exception's
Messageor rawResponseBodycontains sensitive token-like content, that content can end up in application logs or telemetry.This PR adds a developer spec for a proposed MSAL .NET exception-content redaction mechanism. The spec is intended to be implementation-ready and AI/coding-agent friendly: it defines the proposed public API shape, internal redaction pipeline, compatibility constraints, edge cases, validation matrix, and follow-up implementation decisions.
No product code, public API, tests, or
PublicAPI.Unshipped.txtchanges are included in this PR. Those will be handled in follow-up implementation PRs.What this developer spec proposes
The spec proposes a generic, partner-agnostic mechanism to redact sensitive token-like content from MSAL-owned exception content at creation, plus an always-on built-in baseline scrubber, while preserving diagnostic signals that downstream libraries rely on.
Proposed public API shape:
public delegate string MsalExceptionScrubber(string content);WithExceptionScrubber(MsalExceptionScrubber scrubber)onBaseAbstractApplicationBuilder<T>, so public-client, confidential-client, and managed-identity applications all inherit it.Intended behavior and guarantees
The developer spec defines the following intended behavior:
MessageandResponseBodycontent on service-derived exceptions is redacted when MSAL constructs the exception.ToString()rendering.Downstream compatibility requirements
The spec treats downstream compatibility as load-bearing.
Redaction must preserve diagnostic routing signals that consumers branch on:
MsalServiceException.ErrorCode.AADSTS*/AADB2C*protocol error-code tokens from in-scope redactedMessageorResponseBodycontent.ResponseBodyinto null. Empty is allowed; null is not introduced by redaction.This is required to preserve Microsoft.Identity.Web control-flow, including:
MsalServiceException.ErrorCode == invalid_clientplusResponseBodyMsalUiRequiredException.MessageAI / coding-agent friendly structure
This spec is written so that follow-up implementation work can be fed to AI-assisted coding tools or implementation agents with minimal ambiguity.
It explicitly defines:
ResponseBodynon-null compatibilityThe intent is for a follow-up implementation PR to use this spec as the source of truth for code changes, tests, public API review, and release-note wording.
Expected follow-up implementation work
Follow-up PRs are expected to add:
MsalExceptionScrubberWithExceptionScrubber(...)ToString()final-pass behavior, implemented without double-scrubbingPublicAPI.Unshipped.txtupdatesExpected test coverage in follow-up PRs
The spec calls for tests covering:
MessageandResponseBodyat creationResponseBodypreservationAADSTS*/AADB2C*routing-token preservationToString()baseline final passToJsonString()behavior based on already-redacted stored fieldsBehavior change to document in implementation PR
When implemented, redaction at creation means
MessageandResponseBodymay return redacted text where they previously returned raw service content. The proposed baseline-onlyToString()final pass may also alter string rendering.This behavior change should be called out in release notes when the implementation ships.
Public API status
This PR does not add public API.
The developer spec proposes the following public API shape for review:
MsalExceptionScrubberWithExceptionScrubber(MsalExceptionScrubber scrubber)A follow-up implementation PR must update
PublicAPI.Unshipped.txtwith the exact entries produced by the repo analyzer.Open questions