Skip to content

License validation: isolate from the host app's CryptoProviderFactory - #4674

Merged
jbogard merged 1 commit into
mainfrom
license-crypto-provider-isolation
Oct 28, 2026
Merged

jbogard merged 1 commit into
mainfrom
license-crypto-provider-isolation

Conversation

@jbogard

@jbogard jbogard commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Summary

The license key's RsaSecurityKey used CryptoProviderFactory.Default. That factory is process-wide: the host app can customize it (for example with a CustomCryptoProvider), 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.Default produces 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 per MapperConfiguration, 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

  • New LicenseCryptoProviderIsolationTests installs a recording provider on CryptoProviderFactory.Default and 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 as LicenseKeyEnvironmentVariableTests.
  • Existing invalid-signature tests still pass, so the private factory does real RSA verification.
  • Separately checked with a throwaway RS256 key and token: valid tokens validate on repeated calls with the uncached factory, and tampered ones fail with SecurityTokenInvalidSignatureException.
  • Unit tests 1289/1289, DI tests 33/33

🤖 Generated with Claude Code

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>
Copilot AI balanced review requested due to automatic review settings October 28, 2026 15:14
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-28T15:16:15.919144Z 2a1fbbf PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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.

🟢 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 CryptoProviderFactory with 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

@jbogard
jbogard merged commit 272bdb1 into main Oct 28, 2026
6 checks passed
@jbogard
jbogard deleted the license-crypto-provider-isolation branch October 28, 2026 21:08
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