Skip to content

Mask secret-named resolved parameters in results.json - #2

Merged
pepaooo merged 1 commit into
mainfrom
claude/eloquent-babbage-e2j8n7
Nov 3, 2026
Merged

pepaooo merged 1 commit into
mainfrom
claude/eloquent-babbage-e2j8n7

Conversation

@pepaooo

@pepaooo pepaooo commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Problem

results.json recorded each step's and cleanup entry's resolvedParams verbatim. A value under a secret-looking key — e.g. a file.write row { id: E1, password: hunter2-plain } or an ldap.create with userPassword: hunter2-plain — landed in reports/<run-id>/results.json in plain text, while report.html and the workbench's run events already showed ***. The capability matrix documented this as deliberate ("JSON includes resolved parameters without redaction"), but it contradicts the project rule: no secret value in any response, event, log, report or DOM.

Decision

Don't keep it. Mask by key in the JSON too, with the same rule the report uses (Secrets.isSecret).

Changes

  • Secrets.paramsMasked(ScenarioResult | StepResult | CleanupResult) (engine): replaces values under secret-looking keys, at any depth, in steps, cleanup and skipped cleanup entries; everything else is unchanged. This logic moved out of the workbench's RunSessions, which now delegates, so the events and the file share one implementation.
  • JsonResultWriter.write masks every result as it writes the file. This one point covers RunService (idmtest run and workbench runs) and the Maven runners, since all write through RunRecorder. In-memory results are unchanged. secrets.env value masking (****, SecretMask) still applies on top.
  • Docs: capability matrix row "Structured results"; writing-scenarios.md §8 (set: and descriptions) and §9 (Results); guides/scenario-authoring.md; architecture/README.md; the introduction deck. They still state that masking goes by key name only, so secrets in descriptions, messages or values under ordinary keys are written as is.

Tests

  • JsonResultWriterTest: nested rows, headers, LDAP attributes, cleanup and skipped cleanup are masked; the input results are not changed.
  • SecretMaskTest: a value the run's mask doesn't know, under a password key, is written as ***.
  • RunCommandTest: an end-to-end run with ldap.create and userPassword: hunter2-plain keeps the password out of results.json and report.html.

Run locally: engine (649) and wiring (78) suites pass. Runner suite: all touched tests pass. Four unrelated tests (FolderBrowserTest, RecentWorkspacesTest, two in WorkspacesControllerTest) fail only under a POSIX locale because they use non-ASCII folder names; they pass with LANG=C.UTF-8.

Note

Existing results.json files written before this change are not rewritten and still contain plain values.


Generated by Claude Code

results.json recorded each step's and cleanup entry's resolvedParams
verbatim, so a value under a key like `password` or `userPassword`
written in scenario YAML (or bound at run time) reached the file even
though report.html and the workbench's run events showed `***`. That
contradicts the project rule that no secret value appears in any report.

JsonResultWriter now writes every result through Secrets.paramsMasked,
which replaces values under secret-looking keys (Secrets.isSecret), at
any depth, in steps, cleanup and skipped cleanup entries -- the rule the
HTML report already applies. The masking that lived in RunSessions moved
into Secrets so the events and the file share one implementation.

Docs: capability matrix row "Structured results", writing-scenarios §8/§9,
scenario-authoring guide, architecture README and the introduction deck
no longer describe the JSON as unredacted.

Tests: JsonResultWriterTest (nested, cleanup, skipped cleanup; inputs
unchanged), SecretMaskTest (a by-name value the mask does not know),
RunCommandTest (ldap.create with userPassword kept out of results.json
and report.html end to end).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yRxsoDBQHCgAkT7DK8KgA
@pepaooo
pepaooo merged commit f4a8081 into main Nov 3, 2026
1 check passed
@pepaooo
pepaooo deleted the claude/eloquent-babbage-e2j8n7 branch November 3, 2026 05:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants