Skip to content

[release/13.5] Ensure the typescript app host trusts the dev cert - #19365

Merged
Jose Perez Rodriguez (joperezr) merged 1 commit into
release/13.5from
danegsta-backport-15634-release-13-5
Aug 13, 2026
Merged

[release/13.5] Ensure the typescript app host trusts the dev cert#19365
Jose Perez Rodriguez (joperezr) merged 1 commit into
release/13.5from
danegsta-backport-15634-release-13-5

Conversation

@danegsta

Copy link
Copy Markdown
Member

Backport of #15634 to release/13.5

/cc David Negstad (@danegsta)

Customer Impact

TypeScript AppHosts cannot validate Aspire-managed development certificates when custom AppHost code connects to TLS-enabled resources, forcing customers to disable certificate validation as a workaround.

Testing

Validated real Node TLS connections on macOS and Linux, existing CA preservation, secure cache permissions and reuse, missing-bundle fallback, and the publish-mode boundary. On release/13.5, 105 focused unit tests passed and the CLI E2E test project built successfully.

Risk

Medium — this changes cross-platform certificate export, caching, and TypeScript AppHost process environment setup, but is scoped to run mode and has extensive platform and regression coverage.

Regression?

No — this fixes an existing gap.

* Build a PEM bundle for the dev cert

* Use response from cert bundle directly

* Combine existing Node CA certificate bundles

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Refine TypeScript development certificate handling

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f0f2521e-b6ba-4441-9d8d-08483d863485

* Handle duplicate certificate environment aliases

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f0f2521e-b6ba-4441-9d8d-08483d863485

* Clarify certificate trust scope

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f0f2521e-b6ba-4441-9d8d-08483d863485

* Handle case-sensitive certificate bundle paths

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f0f2521e-b6ba-4441-9d8d-08483d863485

* Use standard Windows path comparison

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f0f2521e-b6ba-4441-9d8d-08483d863485

* Address certificate bundle review feedback

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f0f2521e-b6ba-4441-9d8d-08483d863485

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f0f2521e-b6ba-4441-9d8d-08483d863485
@github-actions

Copy link
Copy Markdown
Contributor

🚀 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/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19365

Or

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

@github-actions

Copy link
Copy Markdown
Contributor

Tests selector (audit mode)

The full test matrix and all jobs still run in audit mode. The tests and jobs below are what selective CI would run under enforcement.

100 / 100 test projects · 8 jobs, from 26 changed files.

Selected test projects (100 / 100)

Aspire.Acquisition.Tests, Aspire.Azure.AI.Inference.Tests, Aspire.Azure.AI.OpenAI.Tests, Aspire.Azure.Data.Tables.Tests, Aspire.Azure.Messaging.EventHubs.Tests, Aspire.Azure.Messaging.ServiceBus.Tests, Aspire.Azure.Messaging.WebPubSub.Tests, Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL.Tests, Aspire.Azure.Npgsql.Tests, Aspire.Azure.Search.Documents.Tests, Aspire.Azure.Security.KeyVault.Tests, Aspire.Azure.Storage.Blobs.Tests, Aspire.Azure.Storage.Files.DataLake.Tests, Aspire.Azure.Storage.Queues.Tests, Aspire.Cli.EndToEnd.Tests, Aspire.Cli.Tests, Aspire.Confluent.Kafka.Tests, Aspire.Dashboard.Components.Tests, Aspire.Dashboard.Tests, Aspire.Deployment.EndToEnd.Tests, Aspire.EndToEnd.Tests, Aspire.Hosting.Analyzers.Tests, Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Kusto.Tests, Aspire.Hosting.Azure.Tests, Aspire.Hosting.Blazor.Tests, Aspire.Hosting.Browsers.Tests, Aspire.Hosting.CodeGeneration.Go.Tests, Aspire.Hosting.CodeGeneration.Java.Tests, Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.Rust.Tests, Aspire.Hosting.CodeGeneration.TypeScript.Tests, Aspire.Hosting.Containers.Tests, Aspire.Hosting.DevTunnels.Tests, Aspire.Hosting.Docker.Tests, Aspire.Hosting.Dotnet.Tests, Aspire.Hosting.DotnetTool.Tests, Aspire.Hosting.EntityFrameworkCore.Tests, Aspire.Hosting.Foundry.Tests, Aspire.Hosting.Garnet.Tests, Aspire.Hosting.GitHub.Models.Tests, Aspire.Hosting.Go.Tests, Aspire.Hosting.JavaScript.Tests, Aspire.Hosting.Kafka.Tests, Aspire.Hosting.Keycloak.Tests, Aspire.Hosting.Kubernetes.Tests, Aspire.Hosting.Maui.Tests, Aspire.Hosting.Milvus.Tests, Aspire.Hosting.MongoDB.Tests, Aspire.Hosting.MySql.Tests, Aspire.Hosting.Nats.Tests, Aspire.Hosting.OpenAI.Tests, Aspire.Hosting.Oracle.Tests, Aspire.Hosting.Orleans.Tests, Aspire.Hosting.PostgreSQL.Tests, Aspire.Hosting.Python.Tests, Aspire.Hosting.Qdrant.Tests, Aspire.Hosting.RabbitMQ.Tests, Aspire.Hosting.Radius.Tests, Aspire.Hosting.Redis.Tests, Aspire.Hosting.RemoteHost.Tests, Aspire.Hosting.Sdk.Tests, Aspire.Hosting.Seq.Tests, Aspire.Hosting.SqlServer.Tests, Aspire.Hosting.Testing.Tests, Aspire.Hosting.Tests, Aspire.Hosting.Valkey.Tests, Aspire.Hosting.Yarp.Tests, Aspire.Keycloak.Authentication.Tests, Aspire.Managed.Tests, Aspire.Microsoft.Azure.Cosmos.Tests, Aspire.Microsoft.Azure.StackExchangeRedis.Tests, Aspire.Microsoft.Data.SqlClient.Tests, Aspire.Microsoft.EntityFrameworkCore.Cosmos.Tests, Aspire.Microsoft.EntityFrameworkCore.SqlServer.Tests, Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration.Tests, Aspire.Milvus.Client.Tests, Aspire.MongoDB.Driver.Tests, Aspire.MongoDB.Driver.v2.Tests, Aspire.MongoDB.EntityFrameworkCore.Tests, Aspire.MySqlConnector.Tests, Aspire.NATS.Net.Tests, Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.Tests, Aspire.Npgsql.Tests, Aspire.OpenAI.Tests, Aspire.Oracle.EntityFrameworkCore.Tests, Aspire.Playground.Tests, Aspire.Pomelo.EntityFrameworkCore.MySql.Tests, Aspire.Qdrant.Client.Tests, Aspire.RabbitMQ.Client.Tests, Aspire.RabbitMQ.Client.v6.Tests, Aspire.Seq.Tests, Aspire.StackExchange.Redis.DistributedCaching.Tests, Aspire.StackExchange.Redis.OutputCaching.Tests, Aspire.StackExchange.Redis.Tests, Aspire.Templates.Tests, Aspire.TerminalHost.Tests, ConfigurationSchemaGenerator.Tests, Infrastructure.Tests, QuarantineTools.Tests

Selected jobs (8)

cli-starter, deployment-e2e, extension-e2e, homebrew-installer, polyglot, typescript-api-compat, typescript-sdk, winget-installer


How these were chosen — grouped by what changed

⚠️ 89 of the 100 selected test projects come from a single change — src/Shared/X509Certificate2Extensions.cs.

🔧 src/Shared/X509Certificate2Extensions.cs (changed source)
89 via the project graph

show 89

Aspire.Acquisition.Tests, Aspire.Azure.AI.Inference.Tests, Aspire.Azure.AI.OpenAI.Tests, Aspire.Azure.Data.Tables.Tests, Aspire.Azure.Messaging.EventHubs.Tests, Aspire.Azure.Messaging.ServiceBus.Tests, Aspire.Azure.Messaging.WebPubSub.Tests, Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL.Tests, Aspire.Azure.Npgsql.Tests, Aspire.Azure.Search.Documents.Tests, Aspire.Azure.Security.KeyVault.Tests, Aspire.Azure.Storage.Blobs.Tests, Aspire.Azure.Storage.Files.DataLake.Tests, Aspire.Azure.Storage.Queues.Tests, Aspire.Confluent.Kafka.Tests, Aspire.Dashboard.Components.Tests, Aspire.Dashboard.Tests, Aspire.Deployment.EndToEnd.Tests, Aspire.EndToEnd.Tests, Aspire.Hosting.Analyzers.Tests, Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Kusto.Tests, Aspire.Hosting.Blazor.Tests, Aspire.Hosting.Browsers.Tests, Aspire.Hosting.Containers.Tests, Aspire.Hosting.DevTunnels.Tests, Aspire.Hosting.Docker.Tests, Aspire.Hosting.Dotnet.Tests, Aspire.Hosting.DotnetTool.Tests, Aspire.Hosting.EntityFrameworkCore.Tests, Aspire.Hosting.Foundry.Tests, Aspire.Hosting.Garnet.Tests, Aspire.Hosting.GitHub.Models.Tests, Aspire.Hosting.Go.Tests, Aspire.Hosting.JavaScript.Tests, Aspire.Hosting.Kafka.Tests, Aspire.Hosting.Keycloak.Tests, Aspire.Hosting.Kubernetes.Tests, Aspire.Hosting.Milvus.Tests, Aspire.Hosting.MongoDB.Tests, Aspire.Hosting.MySql.Tests, Aspire.Hosting.Nats.Tests, Aspire.Hosting.OpenAI.Tests, Aspire.Hosting.Oracle.Tests, Aspire.Hosting.Orleans.Tests, Aspire.Hosting.PostgreSQL.Tests, Aspire.Hosting.Python.Tests, Aspire.Hosting.Qdrant.Tests, Aspire.Hosting.RabbitMQ.Tests, Aspire.Hosting.Radius.Tests, Aspire.Hosting.Redis.Tests, Aspire.Hosting.Sdk.Tests, Aspire.Hosting.Seq.Tests, Aspire.Hosting.SqlServer.Tests, Aspire.Hosting.Testing.Tests, Aspire.Hosting.Valkey.Tests, Aspire.Hosting.Yarp.Tests, Aspire.Keycloak.Authentication.Tests, Aspire.Managed.Tests, Aspire.Microsoft.Azure.Cosmos.Tests, Aspire.Microsoft.Azure.StackExchangeRedis.Tests, Aspire.Microsoft.Data.SqlClient.Tests, Aspire.Microsoft.EntityFrameworkCore.Cosmos.Tests, Aspire.Microsoft.EntityFrameworkCore.SqlServer.Tests, Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration.Tests, Aspire.Milvus.Client.Tests, Aspire.MongoDB.Driver.Tests, Aspire.MongoDB.Driver.v2.Tests, Aspire.MongoDB.EntityFrameworkCore.Tests, Aspire.MySqlConnector.Tests, Aspire.NATS.Net.Tests, Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.Tests, Aspire.Npgsql.Tests, Aspire.OpenAI.Tests, Aspire.Oracle.EntityFrameworkCore.Tests, Aspire.Playground.Tests, Aspire.Pomelo.EntityFrameworkCore.MySql.Tests, Aspire.Qdrant.Client.Tests, Aspire.RabbitMQ.Client.Tests, Aspire.RabbitMQ.Client.v6.Tests, Aspire.Seq.Tests, Aspire.StackExchange.Redis.DistributedCaching.Tests, Aspire.StackExchange.Redis.OutputCaching.Tests, Aspire.StackExchange.Redis.Tests, Aspire.Templates.Tests, Aspire.TerminalHost.Tests, ConfigurationSchemaGenerator.Tests, Infrastructure.Tests, QuarantineTools.Tests

🔧 src/Aspire.Hosting/DeveloperCertificateService.cs (changed source)
6 via the project graph: Aspire.Hosting.Azure.Tests, Aspire.Hosting.CodeGeneration.Go.Tests, Aspire.Hosting.CodeGeneration.Java.Tests, Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.Rust.Tests, Aspire.Hosting.Maui.Tests

🔧 src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptLanguageSupport.cs (changed source)
1 directly: Aspire.Hosting.CodeGeneration.TypeScript.Tests
1 via the project graph: Aspire.Hosting.RemoteHost.Tests

📦 affected project Aspire.Cli
1 test: Aspire.Cli.EndToEnd.Tests

📦 affected project Aspire.Hosting
1 test: Aspire.EndToEnd.Tests

🔧 src/Aspire.TypeSystem/ILanguageSupport.cs (changed source)
1 via the project graph: Aspire.Hosting.Tests

🧪 tests/Aspire.Cli.EndToEnd.Tests/TypeScriptEmptyAppHostTemplateTests.cs (changed test)
1 directly: Aspire.Cli.EndToEnd.Tests

🧪 tests/Aspire.Cli.Tests/Certificates/CertificateServiceTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Certificates/NativeCertificateToolRunnerTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Commands/CertificatesCommandTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Commands/RunCommandTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Projects/GuestAppHostProjectTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Projects/TypeScriptAppHostToolchainResolverTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Templating/DotNetTemplateFactoryTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/TestServices/TestCertificateService.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/TestServices/TestCertificateToolRunner.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/TypeScriptLanguageSupportTests.cs (changed test)
1 directly: Aspire.Hosting.CodeGeneration.TypeScript.Tests

Job reasons

Job Triggered by
cli-starter • affected project Aspire.Cli
• selected test Aspire.Cli.Tests
• selected test Aspire.Acquisition.Tests
deployment-e2e affected project Aspire.Cli
extension-e2e src/Aspire.Cli/Certificates/CertificateCacheWriter.cs, src/Aspire.Cli/Certificates/CertificateService.cs, src/Aspire.Cli/Certificates/ICertificateToolRunner.cs, src/Aspire.Cli/Certificates/NativeCertificateToolRunner.cs, src/Aspire.Cli/Projects/GuestAppHostProject.cs, src/Aspire.Cli/Projects/GuestRuntime.cs, src/Aspire.Cli/Projects/TypeScriptAppHostToolchainResolver.cs, src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptLanguageSupport.cs, src/Aspire.Hosting/DeveloperCertificateService.cs, tests/Aspire.Cli.EndToEnd.Tests/TypeScriptEmptyAppHostTemplateTests.cs, tests/Aspire.Cli.Tests/Certificates/CertificateServiceTests.cs, tests/Aspire.Cli.Tests/Certificates/NativeCertificateToolRunnerTests.cs, tests/Aspire.Cli.Tests/Commands/CertificatesCommandTests.cs, tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs, tests/Aspire.Cli.Tests/Commands/RunCommandTests.cs, tests/Aspire.Cli.Tests/Projects/GuestAppHostProjectTests.cs, tests/Aspire.Cli.Tests/Projects/TypeScriptAppHostToolchainResolverTests.cs, tests/Aspire.Cli.Tests/Templating/DotNetTemplateFactoryTests.cs, tests/Aspire.Cli.Tests/TestServices/TestCertificateService.cs, tests/Aspire.Cli.Tests/TestServices/TestCertificateToolRunner.cs, tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs, tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs
• affected project Aspire.Cli
homebrew-installer selected test Aspire.Acquisition.Tests
polyglot affected project Aspire.Cli
typescript-api-compat affected project Aspire.Cli
typescript-sdk affected project Aspire.Hosting.CodeGeneration.TypeScript
winget-installer selected test Aspire.Acquisition.Tests

Selection computed for commit 46748de.

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.

Pull request overview

Backports TypeScript AppHost development-certificate trust support to release/13.5.

Changes:

  • Adds runtime metadata for PEM certificate bundles.
  • Exports and securely caches trusted development certificates.
  • Preserves existing CA bundles and adds unit/E2E coverage.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/TypeScriptLanguageSupportTests.cs Tests TypeScript certificate metadata.
tests/Aspire.Cli.Tests/Utils/TestExecutionContextHelper.cs Supports custom Aspire home paths.
tests/Aspire.Cli.Tests/Utils/CliTestHelper.cs Updates certificate service construction.
tests/Aspire.Cli.Tests/TestServices/TestCertificateToolRunner.cs Adds certificate export test hook.
tests/Aspire.Cli.Tests/TestServices/TestCertificateService.cs Implements the new test contract.
tests/Aspire.Cli.Tests/Templating/DotNetTemplateFactoryTests.cs Updates certificate test stub.
tests/Aspire.Cli.Tests/Projects/TypeScriptAppHostToolchainResolverTests.cs Verifies metadata preservation.
tests/Aspire.Cli.Tests/Projects/GuestAppHostProjectTests.cs Tests bundle merging, caching, and fallback.
tests/Aspire.Cli.Tests/Commands/RunCommandTests.cs Updates certificate stub.
tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs Updates certificate stub.
tests/Aspire.Cli.Tests/Commands/CertificatesCommandTests.cs Updates service dependencies.
tests/Aspire.Cli.Tests/Certificates/NativeCertificateToolRunnerTests.cs Tests export and secure caching.
tests/Aspire.Cli.Tests/Certificates/CertificateServiceTests.cs Tests explicit export behavior.
tests/Aspire.Cli.EndToEnd.Tests/TypeScriptEmptyAppHostTemplateTests.cs Verifies the launched AppHost receives a PEM path.
src/Shared/X509Certificate2Extensions.cs Shares trusted-certificate selection logic.
src/Aspire.TypeSystem/RuntimeSpec.cs Adds certificate bundle metadata.
src/Aspire.TypeSystem/ILanguageSupport.cs Adds language-level certificate metadata.
src/Aspire.Hosting/DeveloperCertificateService.cs Reuses shared trust filtering.
src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptLanguageSupport.cs Enables NODE_EXTRA_CA_CERTS.
src/Aspire.Cli/Projects/TypeScriptAppHostToolchainResolver.cs Preserves certificate metadata.
src/Aspire.Cli/Projects/GuestRuntime.cs Exposes runtime certificate metadata.
src/Aspire.Cli/Projects/GuestAppHostProject.cs Configures and combines certificate bundles.
src/Aspire.Cli/Certificates/NativeCertificateToolRunner.cs Exports trusted certificates as PEM.
src/Aspire.Cli/Certificates/ICertificateToolRunner.cs Adds the export contract.
src/Aspire.Cli/Certificates/CertificateService.cs Coordinates best-effort export.
src/Aspire.Cli/Certificates/CertificateCacheWriter.cs Adds secure atomic cache writes.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Aspire.TypeSystem/ILanguageSupport.cs
Comment thread src/Aspire.Cli/Projects/GuestAppHostProject.cs
@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Merging this to fix this issue which impacts callbacks to resources from the apphost. Given risk is not low, let's do some extra bashing here across OSes to ensure things are good to go once we have a build.

@joperezr
Jose Perez Rodriguez (joperezr) merged commit f05c52d into release/13.5 Aug 13, 2026
678 of 682 checks passed
@joperezr
Jose Perez Rodriguez (joperezr) deleted the danegsta-backport-15634-release-13-5 branch August 13, 2026 23:58
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.5 milestone Aug 13, 2026
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

✅ No documentation update needed.

Step 5 branch taken: excluded → base_branch_is_release, title_release_prefix, body_backport_marker

This PR is a backport (Backport of #15634 to release/13.5, title prefixed [release/13.5], base branch release/13.5), so per the exclusion rule it is out of scope for docs generation — documentation for this change should be authored against the original forward PR (#15634) on main, not duplicated here.

  • Triggered signals: polyglot_code_generator_changed (evidence: src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptLanguageSupport.cs modified, matching the polyglot code generator path pattern).
  • Exclusion reasons from signals.json: base_branch_is_release (base is release/13.5), title_release_prefix (title starts with [release/13.5]), body_backport_marker (body contains "Backport of Ensure the typescript app host trusts the dev cert #15634 to release/13.5").

No documentation PR was drafted.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants