Salta ai contenuti

Certificate trust customization

Questi contenuti non sono ancora disponibili nella tua lingua.

In Aspire, you can customize which certificates resources consider trusted for TLS/HTTPS traffic. This is particularly useful for resources that don’t use the system’s root trusted certificates by default, such as containerized applications, Python apps, and Node.js apps. By configuring certificate trust, you enable these resources to communicate securely with services that use certificates they wouldn’t otherwise trust, including the Aspire dashboard’s OTLP endpoint.

When to use certificate trust customization

Section titled “When to use certificate trust customization”

Certificate trust customization is valuable when:

  • Resources need to trust the ASP.NET Core Development Certificate for local HTTPS communication.
  • Containerized services must communicate with the dashboard over HTTPS.
  • Python or Node.js applications need to trust custom certificate authorities.
  • You’re working with services that have specific certificate trust requirements.
  • Resources need to establish secure telemetry connections to the Aspire dashboard.

By default, Aspire attempts to add trust for the ASP.NET Core Development Certificate to resources that wouldn’t otherwise trust it. This enables resources to communicate with the dashboard OTEL collector endpoint over HTTPS and any other HTTPS endpoints secured by the development certificate.

You can control this behavior at the per-resource level using the WithDeveloperCertificateTrust API or through AppHost configuration settings.

Configure development certificate trust per resource

Section titled “Configure development certificate trust per resource”

To explicitly enable or disable development certificate trust for a specific resource:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
// Explicitly enable development certificate trust
var nodeApp = builder.AddNpmApp("frontend", "../frontend")
.WithDeveloperCertificateTrust(trust: true);
// Disable development certificate trust
var pythonApp = builder.AddPythonApp("api", "../api", "main.py")
.WithDeveloperCertificateTrust(trust: false);
builder.Build().Run();

Certificate authority collections allow you to bundle custom certificates and make them available to resources. You create a collection using the AddCertificateAuthorityCollection method and then reference it from resources that need to trust those certificates.

Create and use a certificate authority collection

Section titled “Create and use a certificate authority collection”
AppHost.cs
using System.Security.Cryptography.X509Certificates;
var builder = DistributedApplication.CreateBuilder(args);
// Load your custom certificates
var certificates = new X509Certificate2Collection();
certificates.ImportFromPemFile("path/to/certificate.pem");
// Create a certificate authority collection
var certBundle = builder.AddCertificateAuthorityCollection("my-bundle")
.WithCertificates(certificates);
// Apply the certificate bundle to resources
builder.AddNpmApp("my-project", "../myapp")
.WithCertificateAuthorityCollection(certBundle);
builder.Build().Run();

In the preceding example, the certificate bundle is created with custom certificates and then applied to a Node.js application, enabling it to trust those certificates.

Certificate trust scopes control how custom certificates interact with a resource’s default trusted certificates. Different scopes provide flexibility in managing certificate trust based on your application’s requirements.

The WithCertificateTrustScope API accepts a CertificateTrustScope value to specify the trust behavior.

Different resource types have different default trust scopes:

  • Append: The default for most resources, appending custom certificates to the default trusted certificates.
  • System: The default for Python projects, which combines custom certificates with system root certificates because Python doesn’t properly support Append mode.
  • None: The default for .NET projects on Windows, as there’s no way to automatically change the default system store source.

Attempts to append the configured certificates to the default trusted certificates for a given resource. This mode is useful when you want to add trust for additional certificates while maintaining trust for the system’s default certificates.

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddNodeApp("api", "../api")
.WithCertificateTrustScope(CertificateTrustScope.Append);
builder.Build().Run();

Attempts to override a resource to only trust the configured certificates, replacing the default trusted certificates entirely. This mode is useful when you need strict control over which certificates are trusted.

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var certBundle = builder.AddCertificateAuthorityCollection("custom-certs")
.WithCertificates(myCertificates);
builder.AddPythonModule("api", "./api", "uvicorn")
.WithCertificateAuthorityCollection(certBundle)
.WithCertificateTrustScope(CertificateTrustScope.Override);
builder.Build().Run();

Attempts to combine the configured certificates with the default system root certificates and use them to override the default trusted certificates for a resource. This mode is intended to support Python or other languages that don’t work well with Append mode.

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddPythonApp("worker", "../worker", "main.py")
.WithCertificateTrustScope(CertificateTrustScope.System);
builder.Build().Run();

Disables all custom certificate trust for the resource, causing it to rely solely on its default certificate trust behavior.

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddContainer("service", "myimage")
.WithCertificateTrustScope(CertificateTrustScope.None);
builder.Build().Run();

For advanced scenarios, you can specify custom certificate trust behavior using a callback API. This callback allows you to customize the command line arguments and environment variables required to configure certificate trust for different resource types.

Configure certificate trust with a callback

Section titled “Configure certificate trust with a callback”

Use WithCertificateTrustConfiguration to customize how certificate trust is configured for a resource:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddContainer("api", "myimage")
.WithCertificateTrustConfiguration(async (ctx) =>
{
// Add a command line argument
ctx.Arguments.Add("--use-system-ca");
// Set environment variables with certificate paths
// CertificateBundlePath resolves to the path of the custom certificate bundle file
ctx.EnvironmentVariables["MY_CUSTOM_CERT_VAR"] = ctx.CertificateBundlePath;
// CertificateDirectoriesPath resolves to paths containing individual certificates
ctx.EnvironmentVariables["CERTS_DIR"] = ctx.CertificateDirectoriesPath;
await Task.CompletedTask;
});
builder.Build().Run();

The callback receives a CertificateTrustConfigurationCallbackAnnotationContext that provides:

  • Scope: The CertificateTrustScope for the resource.
  • Arguments: Command line arguments for the resource. Values can be strings or path providers like CertificateBundlePath or CertificateDirectoriesPath.
  • EnvironmentVariables: Environment variables for configuring certificate trust. The dictionary key is the environment variable name; values can be strings or path providers. By default, includes SSL_CERT_DIR and may include SSL_CERT_FILE if Override or System scope is configured.
  • CertificateBundlePath: A value provider that resolves to the path of a custom certificate bundle file.
  • CertificateDirectoriesPath: A value provider that resolves to paths containing individual certificates.

Default implementations are provided for Node.js, Python, and container resources. Container resources rely on standard OpenSSL configuration options, with default values that support the majority of common Linux distributions.

For container resources, you can customize where certificates are stored and accessed using WithContainerCertificatePaths:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddContainer("api", "myimage")
.WithContainerCertificatePaths(
customCertificatesDestination: "/custom/certs/path",
defaultCertificateBundlePaths: ["/etc/ssl/certs/ca-certificates.crt"],
defaultCertificateDirectoryPaths: ["/etc/ssl/certs"]);
builder.Build().Run();

The WithContainerCertificatePaths API accepts three optional parameters:

  • customCertificatesDestination: Overrides the base path in the container where custom certificate files are placed. If not set or set to null, the default path of /usr/lib/ssl/aspire is used.
  • defaultCertificateBundlePaths: Overrides the path(s) in the container where a default certificate authority bundle file is located. When the CertificateTrustScope is Override or System, the custom certificate bundle is additionally written to these paths. If not set or set to null, a set of default certificate paths for common Linux distributions is used.
  • defaultCertificateDirectoryPaths: Overrides the path(s) in the container where individual trusted certificate files are found. When the CertificateTrustScope is Append, these paths are concatenated with the path to the uploaded certificate artifacts. If not set or set to null, a set of default certificate paths for common Linux distributions is used.

By default, Aspire enables development certificate trust for resources, allowing them to send telemetry to the dashboard over HTTPS:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
// Development certificate trust is enabled by default
var nodeApp = builder.AddNpmApp("frontend", "../frontend");
var pythonApp = builder.AddPythonApp("api", "../api", "main.py");
builder.Build().Run();

When working with containerized services that need to trust custom certificates:

AppHost.cs
using System.Security.Cryptography.X509Certificates;
var builder = DistributedApplication.CreateBuilder(args);
// Load custom CA certificates
var customCerts = new X509Certificate2Collection();
customCerts.Import("corporate-ca.pem");
var certBundle = builder.AddCertificateAuthorityCollection("corporate-certs")
.WithCertificates(customCerts);
// Apply to container
builder.AddContainer("service", "myservice:latest")
.WithCertificateAuthorityCollection(certBundle);
builder.Build().Run();

Python projects use System mode by default. To disable certificate trust customization for a Python app:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
// Disable certificate trust for Python apps
builder.AddPythonModule("api", "./api", "uvicorn")
.WithCertificateTrustScope(CertificateTrustScope.None);
builder.Build().Run();

Certificate trust customization has the following limitations:

  • Currently supported only in run mode, not in publish mode.
  • Not all languages and runtimes support all trust scope modes.
  • Python applications don’t natively support Append mode.
  • Custom certificate trust requires appropriate runtime support within the resource.
Domande & RisposteCollaboraCommunityDiscuteGuarda