Add DPoP (RFC 9449) proof creation and server-side validation#3443
Merged
Conversation
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
requested changes
Apr 11, 2026
Member
bgavrilMS
left a comment
There was a problem hiding this comment.
Too much public API. Creation APIs for proofs are not needed .
bgavrilMS
reviewed
Apr 11, 2026
bgavrilMS
reviewed
Apr 11, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new Microsoft.IdentityModel.Dpop package to Wilson that implements DPoP (RFC 9449) proof creation and server-side validation, plus updates to Microsoft.IdentityModel.Tokens to support cnf.jkt and DPoP-specific JWK/header serialization.
Changes:
- Introduces the
Microsoft.IdentityModel.Dpoplibrary (proof creation, validation, options/result types, replay-cache interface). - Adds a new
Microsoft.IdentityModel.Dpop.Teststest project with unit tests and an (skipped) integration test. - Updates
Microsoft.IdentityModel.Tokensfor DPoP support (minimal JWK header representation,cnf.jkt, JSON serialization support).
Reviewed changes
Copilot reviewed 38 out of 38 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| Wilson.sln | Adds the new DPoP library and test projects to the main solution. |
| buildConfiguration.xml | Includes the new DPoP projects in build/test project lists. |
| test/Microsoft.IdentityModel.Dpop.Tests/Microsoft.IdentityModel.Dpop.Tests.csproj | New test project for DPoP. |
| test/Microsoft.IdentityModel.Dpop.Tests/DpopTests.cs | Adds basic proof/validation tests and a skipped Keycloak integration test. |
| test/Microsoft.IdentityModel.Dpop.Tests/DPoPProofValidatorTests.cs | Adds detailed validator tests covering many RFC scenarios. |
| src/Microsoft.IdentityModel.Tokens/Properties/AssemblyInfo.cs | Grants internals visibility to the new DPoP assembly. |
| src/Microsoft.IdentityModel.Tokens/Microsoft.IdentityModel.Tokens.csproj | Adds RS0016 suppression (PublicApiAnalyzer). |
| src/Microsoft.IdentityModel.Tokens/JsonWebKey.cs | Adds DPoP-specific minimal public JWK representation and modifies existing JWK serialization. |
| src/Microsoft.IdentityModel.Tokens/Json/JsonSerializerPrimitives.cs | Adds JsonNode support when writing objects. |
| src/Microsoft.IdentityModel.Tokens/ConfirmationClaimTypes.cs | Adds jkt confirmation claim constant + UTF8 bytes span. |
| src/Microsoft.IdentityModel.Tokens/Cnf.cs | Adds parsing + property for cnf.jkt. |
| src/Microsoft.IdentityModel.Dpop/Microsoft.IdentityModel.Dpop.csproj | New DPoP library project definition including PublicAPI analyzer files. |
| src/Microsoft.IdentityModel.Dpop/IJtiReplayCache.cs | Adds replay cache abstraction for jti replay detection. |
| src/Microsoft.IdentityModel.Dpop/GlobalSuppressions.cs | Adds targeted suppressions for analyzer warnings in validator/options. |
| src/Microsoft.IdentityModel.Dpop/DPoPValidationResult.cs | Adds structured result type for server-side validation outcomes. |
| src/Microsoft.IdentityModel.Dpop/DPoPValidationOptions.cs | Adds configurable server-side validation settings (algorithms, lifetime, nonce, replay cache, TimeProvider). |
| src/Microsoft.IdentityModel.Dpop/DPoPProofValidator.cs | Implements server-side validation + helper methods for binding/hash/thumbprint. |
| src/Microsoft.IdentityModel.Dpop/DPopProofOptions.cs | Adds proof creation options (signing creds, nonce, TimeProvider, etc.). |
| src/Microsoft.IdentityModel.Dpop/DPoPProof.cs | Implements client-side DPoP proof JWT creation. |
| src/Microsoft.IdentityModel.Dpop/DPoPErrorCodes.cs | Adds RFC 9449 error code constants. |
| src/Microsoft.IdentityModel.Dpop/DPoPConstants.cs | Adds DPoP protocol/header/token-type constants. |
| src/Microsoft.IdentityModel.Dpop/DPoPClaimTypes.cs | Adds DPoP claim name constants. |
| src/Microsoft.IdentityModel.Dpop/PublicAPI.Unshipped.txt | Adds the public surface area listing for the DPoP package (non-TFM file). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI.Shipped.txt | Adds (empty) shipped API baseline file for the DPoP package (non-TFM file). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | Adds per-TFM public API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt | Adds per-TFM shipped API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net462/PublicAPI.Unshipped.txt | Adds per-TFM public API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net462/PublicAPI.Shipped.txt | Adds per-TFM shipped API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net472/PublicAPI.Unshipped.txt | Adds per-TFM public API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net472/PublicAPI.Shipped.txt | Adds per-TFM shipped API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net6.0/PublicAPI.Unshipped.txt | Adds per-TFM public API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net6.0/PublicAPI.Shipped.txt | Adds per-TFM shipped API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net8.0/PublicAPI.Unshipped.txt | Adds per-TFM public API entries for TimeProvider members. |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net8.0/PublicAPI.Shipped.txt | Adds per-TFM shipped API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net9.0/PublicAPI.Unshipped.txt | Adds per-TFM public API entries for TimeProvider members. |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net9.0/PublicAPI.Shipped.txt | Adds per-TFM shipped API file (currently empty). |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net10.0/PublicAPI.Unshipped.txt | Adds per-TFM public API entries for TimeProvider members. |
| src/Microsoft.IdentityModel.Dpop/PublicAPI/net10.0/PublicAPI.Shipped.txt | Adds per-TFM shipped API file (currently empty). |
Comments suppressed due to low confidence (1)
src/Microsoft.IdentityModel.Dpop/DPoPProof.cs:152
- There are stray non-printable characters (a standalone carriage return) after the closing brace. Please remove it to avoid mixed line-ending / formatting issues in source control and analyzers.
return Convert.ToBase64String(bytes);
}
}
This was referenced May 21, 2026
Merged
Open
Closed
Merged
This was referenced May 28, 2026
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
PBI 3549154: Implement dPoP validation primitives in Wilson
Adds
Microsoft.IdentityModel.Dpop— a new package implementing DPoP (Demonstrating Proof-of-Possession) per RFC 9449.Provides both client-side proof creation and server-side proof validation with no
System.Net.Httpdependency.What's included
Core types:
DPoPProof— client-side: creates signed DPoP proof JWTs withhtm,htu,iat,jti,ath, and optionalnonceclaimsDPoPProofValidator— server-side: validates DPoP proofs per RFC 9449 §4.3 (all 12 steps), returns structuredDPoPValidationResultDPoPValidationOptions— configurable algorithms, lifetime, clock skew, nonce, andIJtiReplayCacheplug-inDPoPValidationResult— sealed result type with factory methods (Success,Failed,NonceRequired)Interface:
IJtiReplayCache— plug-in point for jti-based replay detectionDesign decisions
iatfreshness (MUST per RFC) is always enforced;nonce(MAY) andjtitracking ("can") are opt-in viaExpectedNonceandJtiReplayCacheathuses ASCII encoding with strictEncoderFallback.ExceptionFallbackper RFC 9449 §4.2Alg,Kid,Useper RFC 7638 §3.2 (only required members)DPoPProofValidatoris virtualMulti-TFM support
Targets
$(SrcTargets)fromcommon.props. Uses#ifguards matching Wilson conventions:#if NET6_0_OR_GREATER—SHA256.HashData,RandomNumberGenerator.Fill#if NET—CryptographicOperations.FixedTimeEquals#if NET8_0_OR_GREATER—TimeProviderJsonWebKey.RepresentAsAsymmetricPublicJwkForDpop(): RSA branch was includingAlg,Kid,Usein the JWK — these must be excluded per RFC 7638 §3.2 forcorrect thumbprint computation
Tests
47 tests covering all RFC §4.3 validation steps, edge cases (expired proof, wrong algorithm, symmetric key rejection, private key detection, replay cache, RSA + EC keys,
nonce handling). Tests excluded on
net462(#if !NET462) due to missingECCurve/RSA.Create(int)APIs.Code quality
PublicAPI.Shipped.txt/PublicAPI.Unshipped.txtwith per-TFM files (no RS0016 suppression)GlobalSuppressions.cswith targeted member-level suppressions (CA1031, CA2227, CA1805)CancellationTokenforwarded end-to-end throughValidateTokenAsyncPBI 3549154: Implement dPoP validation primitives in Wilson