Add support for pkcs12 format certificate trust bundles to enable trust in Java service scenarios#14756
Add support for pkcs12 format certificate trust bundles to enable trust in Java service scenarios#14756danegsta wants to merge 4 commits intorelease/13.2from
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14756Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 14756" |
There was a problem hiding this comment.
Pull request overview
This pull request adds support for generating PKCS#12 format certificate trust store bundles to enable Java-based services (e.g., Kafka, Elasticsearch) to consume trusted CA certificates via javax.net.ssl.trustStore. The implementation follows the existing tracked-reference pattern used for HTTPS termination certificates, ensuring the PKCS#12 trust store is only generated when a resource's configuration callback actually references the bundle path.
Changes:
- Added PKCS#12 bundle path and password properties to certificate trust configuration contexts, enabling Java services to reference trust stores in their preferred format
- Implemented lazy generation of PKCS#12 trust stores using the tracked reference pattern, ensuring bundles are only created when actually needed
- Extended both executable and container resource flows in DcpExecutor to conditionally generate and deploy
truststore.p12files when referenced - Added comprehensive tests covering tracked reference behavior, PKCS#12 generation, and password handling
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Aspire.Hosting/ApplicationModel/CertificateTrustConfigurationCallbackAnnotation.cs | Added public API properties Pkcs12BundlePath and Pkcs12BundlePassword to callback context for Java service integration |
| src/Aspire.Hosting/ApplicationModel/CertificateTrustExecutionConfigurationGatherer.cs | Implemented tracked reference pattern for PKCS#12 bundle path and added password property to execution configuration data and context |
| src/Aspire.Hosting/Dcp/DcpExecutor.cs | Added CreatePkcs12TrustStore helper method and integrated conditional PKCS#12 generation in both executable and container resource creation flows |
| tests/Aspire.Hosting.Tests/ExecutionConfigurationGathererTests.cs | Added comprehensive test coverage for PKCS#12 tracking behavior, password handling, and trust store generation |
Comments suppressed due to low confidence (4)
src/Aspire.Hosting/ApplicationModel/CertificateTrustConfigurationCallbackAnnotation.cs:92
- The new public API properties
Pkcs12BundlePathandPkcs12BundlePasswordneed more comprehensive documentation. According to the XML documentation standards for public APIs in Aspire, you should:
- Add a
<remarks>section explaining when and how to use these properties, particularly noting that the PKCS#12 bundle is only generated if the path is referenced - Add an
<example>section showing practical usage, similar to the existing examples forArgumentsandEnvironmentVariablesproperties above (lines 37-70) - For
Pkcs12BundlePassword, consider documenting the default value and security considerations
Compare with existing properties like Arguments (lines 33-49) and EnvironmentVariables (lines 51-71) which include both <remarks> and <example> tags demonstrating proper public API documentation.
/// <summary>
/// A value provider that will resolve to a path to a PKCS#12 trust store bundle.
/// Referencing this path in a callback will trigger generation of the PKCS#12 trust store.
/// </summary>
public required ReferenceExpression Pkcs12BundlePath { get; init; }
/// <summary>
/// The password for the PKCS#12 trust store bundle. Defaults to an empty string.
/// </summary>
public required string Pkcs12BundlePassword { get; init; }
src/Aspire.Hosting/ApplicationModel/CertificateTrustExecutionConfigurationGatherer.cs:223
- The documentation for the new
Pkcs12BundlePathproperty is too brief for a public API. According to Aspire's XML documentation standards, public APIs require:
- A more detailed
<summary>explaining what the PKCS#12 trust store contains and its purpose (e.g., "contains trusted CA certificates in PKCS#12 format for Java-based services") - A
<remarks>section explaining the lazy generation behavior (only generated when referenced) and providing usage context - An
<example>section showing how to use this with Java services (e.g., settingjavax.net.ssl.trustStoreenvironment variables)
For reference, see the existing CertificateBundlePath property documentation pattern, but note that this is a new format that requires more explanation than the PEM bundle which is more commonly known.
/// <summary>
/// The path to the PKCS#12 trust store bundle file in the resource context (e.g., container filesystem).
/// Only generated if a resource's certificate trust configuration callback references this path.
/// </summary>
public required ReferenceExpression Pkcs12BundlePath { get; init; }
src/Aspire.Hosting/ApplicationModel/CertificateTrustExecutionConfigurationGatherer.cs:228
- The
Pkcs12BundlePasswordproperty documentation should be more comprehensive for a public API. Consider:
- Explaining why the default is an empty string (common for trust-only stores)
- Clarifying that this password protects the file but the certificates inside are public (no private keys)
- Adding a
<remarks>section with security context
Compare with line 315 in ContainerFileSystemCallbackAnnotation.cs which provides a <summary> that explains when the password might be null. This property should similarly explain the default behavior and security implications.
/// <summary>
/// The password for the PKCS#12 trust store bundle. Defaults to an empty string.
/// </summary>
public string Pkcs12BundlePassword { get; init; } = string.Empty;
src/Aspire.Hosting/Dcp/DcpExecutor.cs:2919
- While this is an internal method, the documentation is overly verbose according to Aspire's documentation standards. Internal APIs should have brief, concise
<summary>tags only. The current documentation includes details that would be appropriate for a public API but are unnecessary for internal code.
Consider simplifying to something like:
/// <summary>
/// Creates a PKCS#12 trust store from the specified certificates (public keys only).
/// </summary>
The detailed explanation about Java compatibility and javax.net.ssl.trustStore usage is implementation detail that doesn't need to be in the XML docs for an internal method.
/// <summary>
/// Creates a PKCS#12 trust store containing the specified certificates (public keys only, no private keys).
/// The resulting trust store is compatible with Java's keytool and can be used as a javax.net.ssl.trustStore.
/// </summary>
internal static byte[] CreatePkcs12TrustStore(X509Certificate2Collection certificates, string password)
🎬 CLI E2E Test RecordingsThe following terminal recordings are available for commit
📹 Recordings uploaded automatically from CI run #22505836544 |
|
@marshalhayes helped verify against a real live Java project; this should allow for enabling certificate trust for Java services in the community toolkit as part of 13.2. |
Description
Adds support for generating PKCS#12 format certificate trust store bundles, enabling Java-based container resources (e.g., Kafka, Elasticsearch) to consume trusted CA certificates via
javax.net.ssl.trustStore.Certificate trust currently only produces PEM artifacts (individual files and bundles). Java uses PKCS#12 (or JKS) format files for its trust stores. This change adds PKCS#12 as an additional output format, following the tracked-reference pattern already used for HTTPS termination certificates — the PKCS#12 trust store is only generated if a resource's
WithCertificateTrustConfigurationcallback actually references thePkcs12BundlePathpath.Changes
CertificateTrustExecutionConfigurationContext: AddedPkcs12BundlePathandPkcs12BundlePasswordproperties so the DCP executor can specify where the PKCS#12 trust store will be writtenCertificateTrustExecutionConfigurationData: Added aTrackedReferenceinner class (same pattern asHttpsCertificateExecutionConfigurationData) withPkcs12BundlePathReference,IsPkcs12BundlePathReferenced, andPkcs12BundlePassword— enabling conditional generationCertificateTrustConfigurationCallbackAnnotationContext: AddedPkcs12BundlePathandPkcs12BundlePasswordso resource integration callbacks can reference the trust store path and passwordDcpExecutor: AddedCreatePkcs12TrustStorehelper; updated both the executable and container certificate flows to provide and conditionally generatetruststore.p12when the PKCS#12 path is referencedExample usage
Checklist
<remarks />and<code />elements on your triple slash comments?aspire.devissue: