Repository navigation
Redact secret parameter values from environment variables sent over the backchannel - #18089
Conversation
…he backchannel aspire describe --format json emitted the plaintext value of secret parameters whenever the parameter was consumed by another resource via WithEnvironment. The parameter resource's own Value property is already redacted (IsSensitive), but the resolved value flowing into dependent resources' environment dictionaries was not. The auxiliary backchannel RPC target now collects the resolved values of secret parameters (peeking at already-resolved values only, never triggering resolution) and redacts matching environment variable values before snapshots leave the AppHost. Fixes microsoft#17616 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 18089Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 18089" |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR adds redaction of secret parameter values from environment variables when resource snapshots are sent through the backchannel RPC, preventing secrets from leaking through clients like aspire describe --format json.
Changes:
- Adds
GetResolvedSecretParameterValues()to collect resolved secret parameter values from the application model. - Modifies environment variable mapping in snapshot building to null out values that match any resolved secret parameter value.
- Adds a test verifying that secret parameter values are redacted while non-secret values remain visible.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs |
Adds value-based redaction of secret parameters in environment variable snapshots |
tests/Aspire.Hosting.Tests/Backchannel/AuxiliaryBackchannelRpcTargetTests.cs |
Adds test for secret parameter value redaction |
Shaurya (@shauryalowkeygotaura) Take a look at the coding agents section in the contributing guide https://github.com/microsoft/aspire/blob/main/docs/contributing.md#coding-agents. The skills defined here https://github.com/microsoft/aspire/tree/main/.agents/skills (I know claude doesn't read the .agents folder). We typically will run the code-review skill and pr-testing skill. Did you verify this change works e2e with a manual test? |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR Testing ReportPR Information
Artifact Version Verification
Changes AnalyzedFiles Changed
Change Categories
What the change doesWhen building Test Scenarios ExecutedA minimal docker-free AppHost was created (an var secret = builder.AddParameter("dbpassword", "s3cr3t-value-xyz", secret: true);
var region = builder.AddParameter("region", "westus2", secret: false);
builder.AddExecutable("worker", "bash", ".", "-c", "sleep 600")
.WithEnvironment("DB_PASSWORD", secret)
.WithEnvironment("REGION", region)
.WithEnvironment("PLAIN_VAR", "plain-value");Scenario 1: Secret redaction happy path (
|
| Scenario | Status | Notes |
|---|---|---|
| 1. Secret redaction happy path (JSON) | ✅ Passed | DB_PASSWORD → null |
| 2. No over-redaction of non-secret values | ✅ Passed | REGION, PLAIN_VAR preserved |
| 3. Human-readable describe | ✅ Passed | Table renders correctly |
| 4. Backchannel method unit/integration tests | ✅ Passed | 2/2 |
Overall Result
✅ PR VERIFIED
The redaction works end-to-end through aspire describe --format json: secret parameter values referenced as environment variables are redacted, while non-secret parameter values and unrelated env vars are preserved (no over-redaction).
Notes / Recommendations
- The dogfood CLI artifact is unavailable because this fork PR's CI is unapproved (
action_required). A maintainer should approve the workflow so standard dogfood artifacts get published for future testing; this run validated the PR source at head instead. - Merge conflict in
AuxiliaryBackchannelRpcTargetTests.cs(a new test landed adjacent to another newly added test onmain) was resolved by keeping both tests; the production change had no conflict.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ing behavior - Compute resolved secret values once per batch in GetResourceSnapshotsAsync, but keep per-event recomputation in the streaming WatchResourceSnapshotsAsync so secrets resolved mid-stream are still redacted (no filter bypass). - Reword GetResolvedSecretParameterValues doc to 'never blocks waiting for interactive parameter resolution' (the else branch reads ValueInternal). - Document the value-based matching limitations on RedactIfSecretValue. - Add tests proving an unresolved secret does not block the snapshot call, that a secret resolved after a watch starts is still redacted, and that a non-secret value coincidentally equal to a secret value is redacted (expected behavior). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bacfc5e
into
microsoft:main
|
Thanks for the contribution Shaurya (@shauryalowkeygotaura) |
Description
Fixes #17616
aspire describe --format json(and other CLI surfaces fed by the auxiliary backchannel, including the MCP resource tools) emitted the plaintext value of aParameterResourcemarkedsecret: truewhenever that parameter was consumed by another resource viaWithEnvironment(name, secretParam). The parameter resource's ownValueproperty is already redacted at the producer (IsSensitive→null), but the resolved value flowing into dependent resources'environmentdictionaries was not.AuxiliaryBackchannelRpcTargetnow collects the resolved values of secret parameters in the application model and redacts (nulls) any environment variable value that matches one of them, before snapshots leave the AppHost. This means every backchannel consumer is covered, not justdescribe.Notes on the approach:
WaitForValueTcs.Task.IsCompletedSuccessfully); it never triggers parameter resolution, so it cannot block on an interaction prompt. If a secret value hasn't been resolved yet, it also cannot have flowed into anyone's environment.nullis consistent with the existing handling of sensitive resource properties andSecretTextcommand arguments.ReferenceExpression) are not caught by exact-value matching. That likely needs provenance tracking onEnvironmentVariableSnapshotand could be a follow-up.Testing
GetResourceSnapshotsAsync_RedactsSecretParameterValuesInEnvironmentVariablestoAuxiliaryBackchannelRpcTargetTests, modeled on the existingGetResourceSnapshotsAsync_MapsSnapshotDatatest: secret parameter value is redacted, a non-secret parameter's value and unrelated values pass through unchanged.Aspire.Hostingbuilds clean locally with the change. I wasn't able to run the fullAspire.Hosting.Testsproject in my environment (unrelated test-asset build issue inTestProject.IntegrationServiceA), so relying on CI for the test run.🤖 Generated with Claude Code