Skip to content

Conversation

danegsta
Copy link
Member

@danegsta danegsta commented Oct 7, 2025

Description

This PR implements custom certificate trust support (including implicit trust for the ASP.NET developer certificate). Users can override the default dev cert trust via configuration ("DcpPublisher:TrustDeveloperCertificate": false) and explicit trust per-resource can be configured via .WithDeveloperCertificateTrust(true/false).

Additionally, users can create custom certificate collections via .AddCertificateAuthorityCollection and load their own X509Certificate2 certificates into it via .WithCertificate and .WithCertificates, then assign these CertificateAuthorityCollection resources to Executables and Containers with .WithCertificateAuthorityCollection. Resources will be initialized with the union of all the CertificateAuthorityCollections that were passed to them. Additionally, you can use .WithCustomCertificateAuthoritiesScope to indicate how you want custom certificates applied to the resource. Setting the scope to the default value of CustomCertificateAuthoritiesScope.Append will indicate that you want to append any custom trusted certificates to the default certificate trust behavior for the resource. CustomCertificateAuthoritiesScope.Override indicates you want to only trust the provided certificates.

Integrations can configure how certificate trust is applied using .WithExecutableCertificateTrustCallback and .WithContainerCertificateTrustCallback, each of which take a callback that receives a context object that can be used to configure the command line arguments and environment variables required to implement trust for the given resource.

This PR is a work in progress; core functionality and support for OpenSSL based containerized resources has been implemented, but additional test coverage and support for other app integrations is still in progress.

Fixes #11679

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

@Copilot Copilot AI review requested due to automatic review settings October 7, 2025 22:08
Copy link
Contributor

github-actions bot commented Oct 7, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 11889

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 11889"

@github-actions github-actions bot added the area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication label Oct 7, 2025
@danegsta danegsta marked this pull request as draft October 7, 2025 22:08
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements initial support for custom certificate trust in Aspire, allowing users to configure certificate authorities for resources. The feature includes implicit trust for ASP.NET developer certificates by default, with override capabilities through configuration and explicit resource-level settings.

Key Changes

  • Added certificate trust framework with new resource types and annotations for managing certificate authorities
  • Integrated developer certificate service for automatic detection and trust of ASP.NET Core development certificates
  • Extended DCP executor to handle certificate trust configuration for both executable and container resources

Reviewed Changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
X509Certificate2Extensions.cs New utility for identifying and validating ASP.NET Core development certificates
ResourceBuilderExtensions.cs Added extension methods for configuring certificate trust on resources
IDeveloperCertificateService.cs Service interface for accessing development certificate information
DeveloperCertificateService.cs Implementation of certificate discovery and validation service
DcpOptions.cs Added configuration option for developer certificate trust
DcpExecutor.cs Core logic for applying certificate trust to executables and containers
ContainerResourceBuilderExtensions.cs Minor refactoring to use consistent annotation behavior
Certificate annotation classes New annotation types for managing certificate trust callbacks and collections
CertificateAuthorityCollection classes Resource type and extensions for managing certificate collections
YarpResourceExtensions.cs Updated to use developer certificate service for conditional configuration
Python/NodeJs extensions Added certificate trust support for respective runtimes

@danegsta danegsta marked this pull request as ready for review October 10, 2025 22:30
@danegsta danegsta requested a review from mitchdenny as a code owner October 10, 2025 22:30
@danegsta
Copy link
Member Author

Marking this as ready to review; there's likely some tweaks to be made to the APIs and a few additional test cases, but the core functionality is working. There's additional work to be done to implement support for this in individual resources (such as Python projects) and I need to figure out the best way to demonstrate this feature in a playground.

/// <param name="certificateAuthorityCollections">Additional certificate authority collections to include.</param>
/// <param name="trustDeveloperCertificates">A value indicating whether platform developer certificates should be considered trusted.</param>
/// <param name="scope">The <see cref="CustomCertificateAuthoritiesScope"/> of the custom certificate authorities.</param>
public sealed class CertificateAuthorityCollectionAnnotation(CertificateAuthorityCollection[]? certificateAuthorityCollections = null, bool? trustDeveloperCertificates = null, CustomCertificateAuthoritiesScope? scope = null) : IResourceAnnotation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to use init only properties and get rid of the constructor. This feels like something that will grow over time.

/// <param name="builder">The <see cref="IResourceBuilder{CertificateAuthorityCollection}"/>.</param>
/// <param name="filePath">The path to the PEM file.</param>
/// <returns>The updated <see cref="IResourceBuilder{CertificateAuthorityCollection}"/>.</returns>
public static IResourceBuilder<CertificateAuthorityCollection> WithCertificatesFromFile(this IResourceBuilder<CertificateAuthorityCollection> builder, string filePath)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pemFilePath?

/// <param name="resourceEnvironment">The existing list of executable environment variables.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
/// <returns>A tuple containing additional command line arguments and environment variables, as well as a boolean indicating whether the operation was successful.</returns>
private async Task<(List<string>, List<EnvVar>, bool)> BuildExecutableCertificateAuthorityTrustAsync(IResource modelResource, List<string> resourceArguments, List<EnvVar> resourceEnvironment, CancellationToken cancellationToken)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to do this at the DCP level rather than the apphost level? Do we care about users being able to observe manipulate these or observe these as container files/env vars/args?

/// Whether to attempt to implicitly add trust for developer certificates (currently the ASP.NET developer certificate)
/// by default.
/// </summary>
public bool TrustDeveloperCertificate { get; set; } = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this go to the DistributedApplicationOptions instead?


public DeveloperCertificateService()
{
_certificates = new Lazy<ImmutableList<X509Certificate2>>(() =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure this does not throw. Also should this log anything?

Comment on lines +2139 to +2140
Directory.CreateDirectory(Path.Join(_locations.DcpSessionDir, modelResource.Name));
File.WriteAllText(caBundlePath, caBundleBuilder.ToString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, unsure if this should be in the dcp session dir. Where do we store other temp files (we really need a single place..._

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom Certificate Trust API Proposal

2 participants