Repository navigation
License validation: isolate from the host app's CryptoProviderFactory - #4674
Merged
Merged
Conversation
The license key used CryptoProviderFactory.Default, which is process-wide: the host app may customize it, and it shares the signature provider cache with the app's own token validation. IdentityModel reports any failure there as IDX10511 "signature validation failed", which looks exactly like a corrupted key. Give the key its own factory with signature provider caching off. Validation runs once per configuration, so the cache isn't needed. Part of #4659. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues block approval of the license-validation isolation change.
No open issues 🎉
What changed in this PR
This PR hardens license validation against host application customizations to the process-wide crypto provider, implementing the optional isolation work described in #4659.
Changes:
- Assigns license verification a dedicated static
CryptoProviderFactorywith signature-provider caching disabled. - Adds a non-parallel regression test that checks validation never consults the host’s custom crypto provider.
- Makes existing license test data and helpers available to other tests.
| File | Description |
|---|---|
| src/UnitTests/Licensing/LicenseCryptoProviderIsolationTests.cs | Adds the isolation test and restores global state afterward; excludes .NET Framework. |
| src/UnitTests/Licensing/LicenseAccessorTests.cs | Exposes shared license test data and validation helpers internally. |
| src/AutoMapper/Licensing/LicenseAccessor.cs | Uses a dedicated, uncached crypto provider factory for the license verification key. |
Review effort: Balanced
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
The license key's
RsaSecurityKeyusedCryptoProviderFactory.Default. That factory is process-wide: the host app can customize it (for example with aCustomCryptoProvider), and its signature-provider cache is shared with the app's own JWT validation.When something goes wrong there, IdentityModel doesn't surface it. It reports IDX10511 signature validation failed, so we log "its signature does not match… copy the full key again". I confirmed this locally: a custom provider installed on
CryptoProviderFactory.Defaultproduces exactly that message for a key whose signature never got checked by our code. That's the same symptom as many of the unresolved support cases in #4659.The fix gives the license key its own static
CryptoProviderFactory { CacheSignatureProviders = false }. Validation runs once perMapperConfiguration, so skipping the cache costs about 5 µs once.This is the optional hardening item from #4659. MediatR gets the same change in a separate PR.
Tests
LicenseCryptoProviderIsolationTestsinstalls a recording provider onCryptoProviderFactory.Defaultand asserts license validation never consults it. It fails before the fix and passes after. It's in a non-parallel collection because it mutates global state, the same pattern asLicenseKeyEnvironmentVariableTests.SecurityTokenInvalidSignatureException.🤖 Generated with Claude Code