Add Managed Identity v2 KeyGuard mTLS PoP support - #1059
Add Managed Identity v2 KeyGuard mTLS PoP support#1059Gladwin Johnson VR (gladjohn) wants to merge 11 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds optional Windows KeyGuard-backed Managed Identity v2 mTLS PoP support, including core SDK integration, native CNG/attestation extensions, caching, tests, documentation, and manual validation.
Changes:
- Extends token acquisition, HTTP, result, and cache pipelines for mTLS-bound tokens.
- Adds the Windows CNG/KeyGuard provider and IMDS v2 credential flow.
- Adds unit tests, documentation, Maven modules, and an e2e validation app.
Reviewed changes
Copilot reviewed 61 out of 61 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
run-java-msi-v2-mtls-devapp.ps1 |
Builds and runs manual validation. |
README.md |
Introduces the mTLS extension. |
pom.xml |
Registers extension and e2e modules. |
msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/TokenRequestExecutorTest.java |
Tests mTLS OAuth request construction. |
msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsProviderLoaderTest.java |
Tests missing-provider failure. |
msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsParametersTest.java |
Tests parameters, cache partitioning, and token validation. |
msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsBindingTest.java |
Tests token endpoint validation. |
msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/DefaultHttpClientMtlsTest.java |
Tests redirect prevention. |
msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/AuthenticationResultMtlsTest.java |
Tests binding serialization and equality. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/TokenResponse.java |
Parses OAuth token type. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/TokenRequestExecutor.java |
Sends request-specific mTLS token requests. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/TokenCache.java |
Supports explicit extended cache hashes. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/OAuthHttpRequest.java |
Propagates request socket factories. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/MsalRequest.java |
Stores extended cache-key hashes. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/MsalError.java |
Defines mTLS error codes. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ManagedIdentityResponse.java |
Parses relative expiration values. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ManagedIdentityParameters.java |
Adds mTLS and attestation options. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsRequest.java |
Defines the provider request contract. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsProviderLoader.java |
Discovers optional providers. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsHttpResponse.java |
Defines callback HTTP responses. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsHttpRequest.java |
Defines callback HTTP requests. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/ManagedIdentityMtlsBinding.java |
Represents validated binding generations. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/IMtlsCapableHttpClient.java |
Marks mTLS-capable custom clients. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/IMtlsBindingContext.java |
Exposes process-local JSSE bindings. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/IManagedIdentityMtlsProvider.java |
Defines the optional provider SPI. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/IManagedIdentityMtlsHttpClient.java |
Defines the MSAL HTTP callback. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/IAuthenticationResult.java |
Exposes token and binding metadata. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/HttpRequest.java |
Carries request-specific socket factories. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/DefaultHttpClient.java |
Applies mTLS factories and disables redirects. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/AuthenticationResult.java |
Stores token type and live bindings. |
msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/AcquireTokenByManagedIdentitySupplier.java |
Integrates binding, cache, IMDS, and OAuth flows. |
msal4j-sdk/docs/managed-identity-v2-mtls-pop.md |
Documents architecture and validation. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/Pkcs10BuilderTest.java |
Tests CSR DER generation. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/KeyGuardMtlsBindingContextTest.java |
Tests binding key IDs and contexts. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/KeyGuardManagedIdentityMtlsProviderTest.java |
Tests certificate rotation timing. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/ImdsV2ClientTest.java |
Tests IMDS v2 contracts. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/CngX509ExtendedKeyManagerTest.java |
Tests RSA alias selection. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/CngSignatureParametersTest.java |
Tests PSS parameter validation. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/CngRsaPrivateKeyTest.java |
Tests non-exportability and cleanup. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/CngProviderTest.java |
Tests provider registration and delegation. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/CngKeyGuardTest.java |
Tests stale native-key deletion. |
msal4j-mtls-extensions/src/test/java/com/microsoft/aad/msal4j/mtls/AttestationTokenCacheTest.java |
Tests attestation caching and concurrency. |
msal4j-mtls-extensions/src/main/resources/META-INF/services/com.microsoft.aad.msal4j.IManagedIdentityMtlsProvider |
Registers the KeyGuard provider. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/Pkcs10Builder.java |
Builds PKCS#10 CSRs. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/NCryptLibrary.java |
Defines Windows NCrypt bindings. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/MtlsMsiException.java |
Defines extension failures. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/KeyGuardMtlsBindingContext.java |
Creates JSSE binding contexts. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/KeyGuardManagedIdentityMtlsProvider.java |
Manages binding creation and rotation. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/ImdsV2Client.java |
Implements IMDS v2 requests and parsing. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/CngX509ExtendedKeyManager.java |
Supplies KeyGuard credentials to JSSE. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/CngSignatureSpi.java |
Implements CNG-backed RSA signing. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/CngRsaPrivateKey.java |
Wraps non-exportable CNG keys. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/CngProvider.java |
Registers CNG signature services. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/CngKeyGuard.java |
Implements KeyGuard and attestation interop. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/AttestationTokenCache.java |
Caches fresh attestation JWTs. |
msal4j-mtls-extensions/src/main/java/com/microsoft/aad/msal4j/mtls/AttestationLibrary.java |
Defines attestation DLL bindings. |
msal4j-mtls-extensions/README.md |
Documents extension usage. |
msal4j-mtls-extensions/pom.xml |
Configures the extension artifact. |
msal4j-mtls-extensions-e2e/src/main/java/com/microsoft/aad/msal4j/mtls/e2e/ManagedIdentityMtlsPopKeyVaultDevApp.java |
Implements manual Key Vault validation. |
msal4j-mtls-extensions-e2e/pom.xml |
Builds the shaded validation app. |
.github/copilot-instructions.md |
Documents the new architecture and modules. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
e2b03ec to
a0b0785
Compare
Vinay Gera (g2vinay)
left a comment
There was a problem hiding this comment.
Re-reviewed after the latest fix commit. The mTLS PoP surface looks solid. Most of my remaining notes are consumer-side integration questions from the Azure SDK for Java side (azure-identity / azure-core), where these bindings will be wired into the HTTP pipeline across pluggable transports.
The higher-priority items are the SSLEngine alias path and issuer-independent alias selection in CngX509ExtendedKeyManager (our default reactor-netty and JDK HttpClient transports are engine-based and MI certs are self-issued), the resource-facing contract (whether the same cert must ride the data-plane call and what Authorization scheme to use for mtls_pop), and the transient-binding cache-reload path. The rest are clarifications on thread-safety, binding identity/rotation lifecycle, and the keyManager() vs sslContext() trust scope. None are blocking; mostly confirmations and a couple of test/javadoc asks. Thanks.
Review submitted in error and withdrawn.
97351af to
0521d1e
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Add binding capability discovery and strength enforcement, expose transport-neutral TLS material, harden native loading, and expand local mTLS coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Re-check completed capability discovery synchronously so Java 8 cannot return a transiently unavailable result before the asynchronous cache-reset callback runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Move attestation opt-in to the optional package, add bearer-over-mTLS, native logging, the IMDS v2 kill switch, DevEx documentation, and real-VM validation coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Add dedicated IMDS v1 and attested IMDS v2 pipeline jobs, preserve the existing hosted build, and bootstrap checksum-verified Java and Maven distributions on the Managed Identity agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
0521d1e to
90f2d0a
Compare
Remove the unreleased changelog entry and move the manual Managed Identity v2 validation script into the build directory while preserving repository-root execution and documentation links. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Move the existing IMDS v1 coverage into a separate managed identity E2E change so this PR remains focused on attested mTLS PoP. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Disable redirects for credential-bound OAuth requests, clean failed attestation DLL extractions, and retain returned binding generations until certificate expiry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30714a3c-b1e6-4578-8223-e07611e44e1d
Summary
Adds production-shaped Managed Identity v2 mTLS support for Java using Windows
VBS KeyGuard and optional Microsoft Azure Attestation.
Java retains native interop only for KeyGuard/CNG signing and attestation.
JCA/JSSE owns TLS, and mTLS PoP callers receive a reusable
IMtlsBindingContextfor independent downstream Java HTTP calls.Reviewer entry point:
managed-identity-v2-mtls-pop-review-guide.mdArchitecture
Native signing remains limited to:
Changes
type, complete leaf-certificate DER SHA-256 identity, and attestation mode.
claims, client capabilities, telemetry, correlation IDs, retries, error
handling, and response parsing.
attestation, certificate rotation, and reusable JSSE binding contexts.
Microsoft.Azure.Security.KeyGuardAttestation1.1.5AttestationClientLib.dll.token_type=mtls_pop, HTTPS token endpoints, IMDS-specificretry behavior, validated IMDS response origin, and disabled redirects for
credential-bound requests.
IMtlsCapableHttpClientfor custom transports and fails fast when acustom client does not consume request-specific mTLS configuration.
liveness probe.
.NET parity follow-up
The following parity changes are included in this PR branch:
com.microsoft.azure:msal4j-key-attestationartifact throughManagedIdentityAttestationExtensions.withAttestationSupport(...), matchingthe MSAL.NET package boundary.
withRequestOverMtls(). It authenticates theESTS connection with KeyGuard, requests
token_type=bearer, uses a distinctcache partition, and intentionally returns no downstream binding context.
callback lifetime, and suppression of raw native debug payloads.
MSAL_MI_DISABLE_IMDS_V2;trueor1disables v2, capabilitydiscovery reports no mTLS binding, and explicit PoP or bearer-over-mTLS
requests fail before metadata, key, CSR, certificate, or attestation work.
binding context process-memory only. No Windows certificate-store persistence
is required.
replacement, or
bypass_cache.The optional bounded capability-discovery timeout proposed in MSAL.NET issue
#6180 remains a separate follow-up. It is useful for credential-chain failover,
but is not currently shipped by MSAL.NET and requires a Java cancellation and
transport-budget contract rather than a superficial future timeout.
Validation
msal4j-sdktests pass.the production extension excludes the manual E2E app.
mtls_poptoken;SSLContext;cnf.x5t#S256against SHA-256 of the complete leaf certificateDER;
HttpsURLConnectionand received HTTP 200;401
Unauthorized;TokenSource.CACHEwith the matchinglive binding context;
TokenSource.IDENTITY_PROVIDER, then completedanother HTTP 200 Key Vault call;
Bearertoken over attested mTLS, exposed no bindingcontext, and verified the second acquisition was a cache hit;
MSAL_MI_DISABLE_IMDS_V2and verified mTLS PoP failed before nativeattestation work.
Security properties
entries cannot cross-hit.
complete certificate DER changes.
MSAL.NET parity gap analysis
A feature-by-feature comparison, intentional platform differences, validation evidence, and prioritized remaining release gaps are documented in managed-identity-v2-dotnet-java-parity-gap-analysis.md.