You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make it possible to query local databases and caches directly from the Aspire dashboard without installing clients or copying credentials into a separate terminal.
Adds an explicitly opt-in REPL resource command for PostgreSQL, Redis, Valkey, MongoDB, MySQL, and SQL Server. Each integration exposes a typed WithRepl() extension. The command opens the bundled client (psql, redis-cli, valkey-cli, mongosh, mysql, or sqlcmd) in the dashboard terminal dock, already authenticated to the running container. Sessions remain available after the command returns.
Shared internal source resolves the current container ID, respects Docker/Podman runtime selection, and disables the command until the container is running and its ID is available. Commands are run-mode-only and are not registered unless explicitly enabled. Adds all six resources to the terminal playground and documents the experience in each integration README. No shared public REPL interface or terminal lifecycle API is introduced.
User-facing usage
Enable the command only for resources whose authenticated client access is appropriate for everyone who can access the dashboard:
Run the AppHost and select REPL on a running resource. PostgreSQL starts in postgres; SQL Server starts in master. MongoDB supports direct replica-member connections and uses the configured CA bundle without disabling TLS validation. SQL Server supports current and legacy bundled sqlcmd locations. PostgreSQL and MySQL respect customized container target ports.
Quit the client before closing its terminal tab. Closing the tab alone may leave the client running inside the container; stopping the container ends remaining clients.
Validation
All 135 focused REPL tests passed locally across the six integrations, including authenticated queries or commands through real docked terminals.
Coverage includes default-off and run/publish behavior, null validation, command state and cancellation, credential forwarding, custom target ports, MongoDB TLS/replica-set behavior, Redis TLS loopback routing, and SQL Server interactive GO batches.
Readiness and terminal interactions have independent timeout budgets, with terminal-screen diagnostics on interaction timeout.
Terminal playground builds with all six integrations, with dashboard/terminal-host project builds and native compilation skipped.
Generated TypeScript APIs were checked for all six withRepl() exports.
Published-artifact testing at 392e1d1877 passed on macOS ARM64/Docker using five freshly generated AppHosts: C# and TypeScript default-off/opt-in behavior, all six authenticated dashboard clients, normal exit/reopen, custom ports, Redis/MongoDB variants, stopped-command disabling, container replacement, stale-credential failure, and publish-mode exclusion. Captured 21 screenshots and CLI/browser logs.
REPL commands are disabled by default. Enabling one grants dashboard users access to a privileged, authenticated database/cache client, potentially including server-side operating-system commands. Only enable this for trusted dashboard users; consider tunnels, Codespaces, and VS Code remoting when deciding who can access it. SQL Server uses the sa account.
Passwords are forwarded through environment variables rather than command-line arguments. MongoDB retains certificate validation; SQL Server trusts the local server certificate for its in-container loopback connection. Redis uses its existing non-TLS loopback port when TLS is enabled. Review should consider credential exposure through process environments, shell/client launch handling, and access to authenticated terminal sessions. No formal threat model or security review has been completed.
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?
Status: Verified. The PR head was checked again after testing and was unchanged.
The initial install correctly failed because the current-head native CLI artifact had not yet been uploaded. Testing waited for the package and macOS ARM64 CLI jobs to succeed, then installed their artifacts. No older build was substituted.
Changes Analyzed
Hosting changes add a shared container-exec command and integration-specific client arguments, authentication, and TLS handling:
There are no CLI, dashboard-source, template, client-component, VS Code extension, or CI-infrastructure changes. Dashboard testing below exercises the new hosting commands through the existing terminal UI.
Test Scenarios Executed
1. Default authenticated REPLs
Coverage: Happy path Status: Passed
Created ReplHappy using aspire new aspire-empty, added all six integrations from the PR packages, and started it with aspire start --isolated. All six containers became healthy.
For each resource, clicked Actions > REPL in the actual dashboard, entered commands through the terminal textbox, and verified the rendered terminal screen using the dashboard's getTerminalSnapshot diagnostic API. Each session appeared in the bottom terminal dock.
Resource
Command
Observed result
PostgreSQL
SELECT current_user, current_setting('port');
postgres, 5432
Redis
PING
PONG
Valkey
PING
PONG
MongoDB
Read authenticated user through connectionStatus
admin-authenticated
MySQL
SELECT CURRENT_USER(), @@port;
root@%, 3306
SQL Server
SELECT 'repl-' + SUSER_SNAME(); followed by GO
repl-sa, one row
The Redis resource had TLS enabled; its REPL correctly used the internal plaintext secondary endpoint at port 6380. SQL Server was tested using 2022-latest under Docker's AMD64 emulation on the ARM64 host.
Evidence:pr-testing-happy-browser.log, pr-testing-happy-resources.json, and repl-{postgres,redis,valkey,mongo,mysql,sqlserver}.png.
Invoked both REPLs from the dashboard. PostgreSQL returned its actual server port as 5433; MySQL returned 3307. Both authenticated successfully. This verifies the latest port fixes against packaged PR artifacts, not only against source-level tests.
Created ReplVariants with four resources. All became healthy, and all REPLs were opened from the dashboard.
Variant
Observed result
Passwordless Redis, TLS disabled
PING returned PONG through port 6379
Redis with developer-certificate TLS
PING returned PONG through internal secondary port 6380
MongoDB with TLS and a custom certificate directory
Authenticated as admin; REPL query succeeded
MongoDB single-member replica set
Prompt showed [direct: primary]; db.hello().setName returned mongo-replica
MongoDB's custom certificate directory was /usr/local/share/aspire-repl-ca. The fixture explicitly opted into the existing experimental certificate and replica-set APIs.
Evidence:pr-testing-variants-browser.log, pr-testing-variants-resources.json, and four ReplVariants-*.png screenshots.
Created ReplLifecycle with PostgreSQL. Opened its REPL, closed the tab through the dashboard close button, and confirmed the tab disappeared. Opened a new REPL and successfully executed a query returning reopened-postgres.
Issue found: Closing the tab did not terminate the remote psql process or its database connection. After opening and closing two sessions, no terminal tabs remained, but docker top showed two psql processes and two corresponding idle local PostgreSQL connections:
The same behavior was reproduced after replacing the container: closing the later live REPL again left a remote psql process and idle database connection behind. A screenshot and DOM snapshot confirmed there were zero docked terminals.
Impact: Repeated open/close cycles accumulate client processes and database connections until the container is stopped. Tab removal alone is not sufficient cleanup for these container-exec sessions.
Recommendation: Investigate and fix remote exec-process lifetime on terminal disposal, then add a regression that verifies the in-container client and database connection disappear after closing the tab. The observed failure is in the new end-to-end REPL workflow; this testing pass did not isolate whether the correction belongs in the command helper, shared terminal lifetime handling, or container-runtime handling.
Stopped and started PostgreSQL through the PR CLI and waited for it to become healthy. The container ID changed from 5ef829c8fd8d... to a84aa0c265ea.... A newly opened dashboard REPL authenticated against the replacement and returned restarted-postgres.
Stopped PostgreSQL and confirmed its resource state was Exited. Opened its dashboard action menu and verified the REPL Fluent menu item's disabled property was true.
Expected outcome: The stopped resource must not offer an actionable REPL command.
Changed the temporary database's password inside an authenticated REPL using \password, leaving the AppHost's parameter unchanged. Opened another REPL through the dashboard.
The new session visibly reported:
FATAL: password authentication failed for user "postgres"
The terminal then reported ended: true and readOnly: true; it did not appear to be a usable authenticated session.
Expected outcome: A visible authentication failure and an ended session, not silent success.
In publish mode, the fixture registered all six integrations and asserted that each had zero ResourceCommandAnnotation entries named repl. The process exited successfully and logged:
Browser automation was corrected to use synchronous waitForFunction predicates. In this installed browser automation stack, an asynchronous predicate returned immediately even when it resolved to false; those preliminary attempts were not counted as successful tests.
The initial shared-canvas run had competing browser connections/input. The AppHost was restarted at a fresh isolated dashboard URL, and the successful default-resource run used only the dedicated automation browser.
The browser harness waits for the resource page title, a newly created terminal, and actual prompt/output text before proceeding. It reads the Fluent component's actual disabled property rather than assuming an aria-disabled attribute.
Default Chrome was unavailable; the installed Microsoft Edge browser was used instead.
Podman, Windows, Linux hosts, and the legacy SQL Server tools path were not tested in this artifact-based run.
No production source or repository files were changed during this testing pass.
Summary
Scenario
Result
All six default docked REPLs
Passed
PostgreSQL 5433 / MySQL 3307
Passed
Passwordless Redis and TLS/replica-set variants
Passed
Dock tab closure and reopening
Failed remote-process cleanup; reopening passed
Container replacement
Passed
Stopped-resource REPL disabled
Passed
Stale-password failure surfaced
Passed
Publish-mode REPL exclusion
Passed
Overall Result
ISSUES FOUND: One reproducible lifecycle cleanup problem. The authenticated REPLs, custom-port fixes, connection variants, restart behavior, negative states, and publish-mode exclusion otherwise passed the exercised scenarios.
The report, browser output logs, screenshots, publish counts, and pr-testing-repro-apps.tar.gz are retained there. The archive contains the four AppHost source files and the browser scenario scripts, not the downloaded CLI/package cache.
All test AppHosts and the dedicated browser session have been stopped. The lifecycle test containers were confirmed removed, taking the orphaned REPL processes with them. The temporary CLI/package/app workspace has been deleted; the evidence listed above remains available.
Add typed WithRepl exports and trusted-dashboard guidance for all six integrations. Keep direct runtime exec behavior and isolate readiness and terminal test timeout budgets.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b4c5fc2e-7805-44de-b46c-7d59e732ccf7
Correct dashboard description for passwordless resource paths
src/Shared/ContainerReplCommand.cs:59
This dashboard description is inaccurate for the supported passwordless Redis, Valkey, and MongoDB resource paths: those REPLs open without authentication. Avoid promising authentication in the shared text.
Status: Verified. The PR head was checked again after testing and remained unchanged.
CI: The run completed successfully, including package and macOS ARM64 CLI artifact jobs.
The isolated dogfood install used the installer linked in the PR comment. Its reported executable location was install/dogfood/pr-20231/bin/aspire; that exact executable was used throughout. The install completed successfully. No older artifact or source-build substitution was used.
Six hosting integrations: PostgreSQL, Redis, Valkey, MongoDB, MySQL, and SQL Server; typed WithRepl() APIs, client arguments, authentication, and TLS handling.
The six integration project files and READMEs.
playground/Terminals/Terminals.AppHost/: explicit opt-in examples and references.
Six integration REPL test classes and their project references.
tests/Shared/ContainerReplCommandTestBase.cs: opt-in/run-mode coverage and independent readiness/interaction timeout budgets.
Hosting and test changes are present. There are no CLI, dashboard implementation, template, client-component, VS Code extension, or CI-infrastructure changes. Browser tests exercise the new integration commands through the existing dashboard UI.
Executed scenarios
1. C# explicit opt-in and authenticated docked clients
Coverage: Happy path and default-off boundary. Result: Passed.
Created ReplOptIn with aspire new aspire-empty using the verified PR template/hive. Added all six integrations with .WithRepl() and six corresponding resources without opt-in. The default-off resources used explicit startup to avoid launching unnecessary duplicate containers.
The AppHost asserts the actual model contains exactly one repl command per opted-in resource and none on each default-off resource. The dashboard action menus independently confirmed all six default-off resources have no REPL command.
Opened every opted-in client through Actions > REPL, verified its terminal appeared in the bottom dock, executed an authenticated query, and exited using the client's normal quit command. Repeated the full matrix to verify reopening.
Integration
Query
Observed result
Normal exit
PostgreSQL
SELECT current_user, current_setting('port');
postgres, 5432
\q
Redis
PING
PONG
quit
Valkey
PING
PONG
quit
MongoDB
Read authenticated user via connectionStatus
admin-authenticated
exit
MySQL
SELECT CURRENT_USER(), @@port;
Root account, 3306
exit
SQL Server
SELECT 'repl-' + SUSER_SNAME(); followed by GO
repl-sa
EXIT
All 12 query/normal-exit cycles passed. Terminal diagnostic snapshots confirmed ended sessions after normal exit.
Evidence:optin-browser.log, optin-resources.json, six ReplOptIn-*.png screenshots.
2. TypeScript explicit opt-in and runtime execution
Created a separate ReplTypeScript app using aspire new aspire-ts-empty. Added all six integrations using aspire add, explicitly specifying the PR package version and hive. The SDK and all six package entries were verified at the tested version.
Ran actual .withRepl() calls for all six types, rather than only inspecting generated declarations. Added six default-off resources, checked their dashboard menus have no REPL command, then performed the same two rounds of authenticated queries and normal exits as the C# fixture.
All six default-off checks and all 12 authenticated query/normal-exit cycles passed.
Evidence:ts-add-*.log, ts-browser.log, ts-resources.json, six ReplTypeScript-*.png screenshots, archived AppHost configuration.
3. Customized container target ports
Coverage: Boundary/regression. Result: Passed.
Created ReplPorts with PostgreSQL configured to listen on port 5433 and MySQL on port 3307, including matching target endpoint ports. Enabled .WithRepl() on both.
Dashboard-launched clients authenticated successfully and reported the actual server ports as 5433 and 3307. Both clients also reopened and exited normally. Four query/exit cycles passed.
PING returned PONG through the internal plaintext loopback endpoint at port 6380
MongoDB with TLS and custom certificate directory
Client authenticated as admin using /usr/local/share/aspire-repl-ca
MongoDB single-member replica set
Direct primary connection returned the expected replica-set name
All four clients were exercised twice and exited normally: eight query/exit cycles passed.
Evidence:variants-browser.log, variants-resources.json, four ReplVariants-*.png screenshots.
5. Stopped-resource command state
Coverage: Unhappy path. Result: Passed.
Created ReplLifecycle, started PostgreSQL, then stopped it using aspire resource postgres stop. Waited for the down state and opened its dashboard action menu.
Expected and observed: The REPL menu item's actual Fluent disabled property was true; the stopped resource did not offer an actionable REPL.
The lifecycle fixture required password authentication for local PostgreSQL connections. Changed the disposable database's password inside its authenticated REPL using \password, left the AppHost parameter unchanged, quit normally, and opened another REPL.
Expected and observed: The new terminal visibly reported FATAL: password authentication failed for user "postgres". Its diagnostic state was ended: true and readOnly: true, rather than a usable session.
Ran aspire publish --list-steps --non-interactive against the C# fixture. Its model assertions require zero REPL commands on all resources in publish mode, including the six explicitly opted-in resources.
The command succeeded. A dedicated evidence file recorded zero REPL commands on each of the 12 resources.
This checks publish-mode command registration, not an actual deployment.
Evidence:publish.log, publish-counts.log.
Summary
Scenario
Status
Current-head artifact identity
Passed
C# opt-in, six default-off checks, 12 query/exit cycles
Passed
TypeScript opt-in, six default-off checks, 12 query/exit cycles
Passed
Custom PostgreSQL/MySQL ports, four query/exit cycles
Passed
Redis/MongoDB variants, eight query/exit cycles
Passed
Stopped REPL command disabled
Passed
Replacement-container connection
Passed
Stale credentials visibly fail
Passed
Publish-mode command exclusion
Passed
Harness notes and limits
Initial browser attempts required corrections for the dock overlapping resource rows, action-menu dismissal, and rapid repeat commands during the dashboard's existing one-second command re-enable delay. The successful runs used a larger viewport, explicit menu dismissal, terminal-state polling, and two rounds through each client matrix. Preliminary failed automation attempts were not counted as passing scenarios.
The stopped resource's dashboard label did not match an initial selector that assumed the raw Exited state. The final check selected the resource by name and verified the actual menu-item disabled state.
Client process survival after closing a tab without quitting is an accepted limitation. It was not treated as a failure, and no cleanup workaround was introduced.
Podman, Windows/Linux hosts, and the legacy SQL Server client path were not exercised.
The 135 focused source tests had already passed after the timeout change; this report describes the subsequent published-artifact validation.
No production source was changed during artifact testing.
Overall result
PR VERIFIED for the tested macOS/Docker scenarios at 392e1d1877.
Evidence includes 21 screenshots, browser terminal snapshots, CLI/model logs, and repro-apps.tar.gz containing the five fixture AppHosts/configuration. Test AppHosts and the dedicated browser were stopped. Only the pre-existing cache-qubrcadt container remained running after testing.
Remove stale Aspire.Hosting.Terminals imports from REPL integrations and shared helpers; terminal types now resolve through Aspire.Hosting.ApplicationModel.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b4c5fc2e-7805-44de-b46c-7d59e732ccf7
Regarding the security concern in the latest Copilot review: a threat model for this feature is underway. This does not indicate that threat modeling or security review is complete.
The reason will be displayed to describe this comment to others. Learn more.
Reviewed the shared REPL command, all six integrations, terminal lifecycle, and regression coverage at 7369267. Focused tests and real-path PostgreSQL/Redis terminal interactions passed. No blocking issues found.
…egrations
Adds documentation for the opt-in WithRepl() extension method that
adds a REPL dashboard command for PostgreSQL, MySQL, MongoDB, SQL
Server, Redis, and Valkey hosting integrations (microsoft/aspire#20231).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Documented the new opt-in WithRepl() dashboard REPL command (source PR #20231) across all six affected hosting integrations: PostgreSQL, MySQL, MongoDB, SQL Server, Redis, and Valkey.
Triggered signals and evidence:
integration_readme_changed — evidence in src/Aspire.Hosting.{MongoDB,MySql,PostgreSQL,Redis,SqlServer,Valkey}/README.md, each adding an "Interactive REPL"/"REPL" section describing WithRepl().
pr_body_has_user_facing_section — PR body's "### User-facing usage" section shows the WithRepl()/withRepl() C# and TypeScript API calls for all six integrations.
Docs changes: Added a new "Add [Resource] with a REPL command" section to each *-host.mdx page (postgres-host.mdx, mysql-host.mdx, mongodb-host.mdx, sql-server-host.mdx, redis-host.mdx, valkey-host.mdx), each with synced C#/TypeScript AppHost tabs, disabled-by-default/run-mode-only behavior, exit/quit-before-closing guidance, and a :::caution callout on trusted-user access matching the PR's security considerations section.
…ations (#20419)
Backport of #20231 to release/13.6
/cc @mitchdenny
## Customer Impact
Adds opt-in dashboard REPL access for PostgreSQL, Redis, Valkey,
MongoDB, MySQL, and SQL Server, using bundled clients and configured
credentials where applicable. Developers can query local resources
without installing clients or copying credentials. Existing applications
are unchanged unless they enable `WithRepl()`.
## Testing
On the source PR, all 135 focused REPL tests passed. Published-artifact
testing covered C# and TypeScript opt-in behavior, all six clients,
custom ports, TLS/replica sets, normal exit/reopen, restart recovery,
authentication failure, and publish-mode exclusion. Source PR CI passed.
## Risk
Low. The functionality is explicitly opt-in and run-mode-only, leaving
existing applications unchanged. It uses the existing terminal
infrastructure without changing shared terminal lifecycle behavior.
## Regression?
No — this is an additive feature, not a regression fix.
---------
Co-authored-by: Mitch Denny <midenn@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b4c5fc2e-7805-44de-b46c-7d59e732ccf7
Copilot-Session: 25d3f000-f5c9-4806-bcf6-86475c51c89c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Make it possible to query local databases and caches directly from the Aspire dashboard without installing clients or copying credentials into a separate terminal.
Adds an explicitly opt-in REPL resource command for PostgreSQL, Redis, Valkey, MongoDB, MySQL, and SQL Server. Each integration exposes a typed
WithRepl()extension. The command opens the bundled client (psql,redis-cli,valkey-cli,mongosh,mysql, orsqlcmd) in the dashboard terminal dock, already authenticated to the running container. Sessions remain available after the command returns.Shared internal source resolves the current container ID, respects Docker/Podman runtime selection, and disables the command until the container is running and its ID is available. Commands are run-mode-only and are not registered unless explicitly enabled. Adds all six resources to the terminal playground and documents the experience in each integration README. No shared public REPL interface or terminal lifecycle API is introduced.
User-facing usage
Enable the command only for resources whose authenticated client access is appropriate for everyone who can access the dashboard:
The same opt-in is available to TypeScript AppHosts:
Run the AppHost and select REPL on a running resource. PostgreSQL starts in
postgres; SQL Server starts inmaster. MongoDB supports direct replica-member connections and uses the configured CA bundle without disabling TLS validation. SQL Server supports current and legacy bundledsqlcmdlocations. PostgreSQL and MySQL respect customized container target ports.Quit the client before closing its terminal tab. Closing the tab alone may leave the client running inside the container; stopping the container ends remaining clients.
Validation
GObatches.withRepl()exports.392e1d1877passed on macOS ARM64/Docker using five freshly generated AppHosts: C# and TypeScript default-off/opt-in behavior, all six authenticated dashboard clients, normal exit/reopen, custom ports, Redis/MongoDB variants, stopped-command disabling, container replacement, stale-credential failure, and publish-mode exclusion. Captured 21 screenshots and CLI/browser logs.Security considerations
REPL commands are disabled by default. Enabling one grants dashboard users access to a privileged, authenticated database/cache client, potentially including server-side operating-system commands. Only enable this for trusted dashboard users; consider tunnels, Codespaces, and VS Code remoting when deciding who can access it. SQL Server uses the
saaccount.Passwords are forwarded through environment variables rather than command-line arguments. MongoDB retains certificate validation; SQL Server trusts the local server certificate for its in-container loopback connection. Redis uses its existing non-TLS loopback port when TLS is enabled. Review should consider credential exposure through process environments, shell/client launch handling, and access to authenticated terminal sessions. No formal threat model or security review has been completed.
Checklist
<remarks />and<code />elements on your triple slash comments?