Skip to content

feat(security): redact secrets from execution output and audit (#690) - #746

Merged
kunaldhongade merged 1 commit into
mainfrom
feature/690-secret-redaction
Aug 6, 2026
Merged

feat(security): redact secrets from execution output and audit (#690)#746
kunaldhongade merged 1 commit into
mainfrom
feature/690-secret-redaction

Conversation

@kunaldhongade

@kunaldhongade kunaldhongade commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds redactSecretsFromText and applies it to configured-command results plus capability audit reason/command fields.
  • Updates the threat model for secret-handling controls and residual heuristic limits.

Test plan

  • tsc -p tsconfig.base.json --noEmit
  • vitest run packages/execution/test
  • CI green

Refs #690 (does not close; remaining: sandbox isolation evaluation, session-scoped approval expiry, broader adversarial UAT corpus).

…udit

Scrub Bearer tokens, API keys, and common secret patterns from command stdout/stderr/errors and capability audit events before they are returned or persisted. Refs #690.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation type: test Test coverage, fixtures, or verification improvements area: docs README, community files, or documentation area: execution Safe command and behavior probe execution labels Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

CodeDecay PR Check

Lead catch: No direct high-signal catch found

CodeDecay did not find a strong direct regression or weak-test signal in this run.

Risk: Low · Merge 28/100 · Decay 19/100 · Security 0/100

This score is conservative pending stronger direct evidence. Treat structural-only signals as review guidance, not proof of a regression.

Full CodeDecay report

CodeDecay Report

Overall risk: Low

Score Value
Merge risk 28/100
Decay risk 19/100
Security risk 0/100
Findings Count
High 3
Medium 3
Low 9

Changed Files

  • docs/security/threat-model.md modified (+5/-1)
  • packages/execution/src/capability/audit.ts modified (+3/-2)
  • packages/execution/src/capability/index.ts modified (+1/-0)
  • packages/execution/src/capability/redact.ts added (+29/-0)
  • packages/execution/src/command.ts modified (+10/-9)
  • packages/execution/src/index.ts modified (+2/-0)
  • packages/execution/src/sanitize-result.ts added (+28/-0)
  • packages/execution/test/capability-policy.test.ts modified (+46/-0)

Likely Impacted Areas

  • Low Documentation (docs): docs/security/threat-model.md
  • Low Source code (source): packages/execution/src/capability/audit.ts, packages/execution/src/capability/index.ts, packages/execution/src/capability/redact.ts, packages/execution/src/command.ts, packages/execution/src/index.ts, packages/execution/src/sanitize-result.ts
  • Low Tests (test): packages/execution/test/capability-policy.test.ts

Normalized Impact Graph

Graph artifact: .codedecay/local/impact-graph.json (4380 node(s), 8902 edge(s))

  • Confidence: Direct: 8902, inferred: 0, heuristic: 0
  • codedecay-js-babel-symbols via @babel/parser (available, adapter 1.0.0)
    • Limitation: Call expressions are not connected to target symbols in this adapter version.
    • Limitation: Only JavaScript and TypeScript files parsed by @babel/parser are represented.
    • Limitation: Static import resolution does not resolve runtime dependency injection or dynamic imports.
  • codedecay-python-lezer via @lezer/python (available, adapter 1.0.0)
    • Limitation: Dynamic imports, dependency injection, decorators without literal routes, and framework route registries are not resolved.
    • Limitation: Python impact evidence uses the @lezer/python grammar and conservative module-to-file resolution.
    • Limitation: Static test imports do not prove execution or assertion quality.
  • Graph limitation: A static test import does not prove the symbol executed or that assertions cover its behavior.

Symbol Impact Evidence

Graph artifact: .codedecay/local/symbol-impact-graph.json (931 file(s), 5531 edge(s))

  • packages/execution/src/capability/audit.ts#appendCapabilityAuditEvent -> packages/execution/src/capability/index.ts, packages/execution/src/command.ts, packages/execution/src/index.ts, packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/capability/index.ts#redactSecretsFromText -> packages/execution/src/index.ts, packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/capability/index.ts#redactSecretsFromUnknown -> packages/execution/src/index.ts
  • packages/execution/src/capability/redact.ts#redactSecretsFromText -> packages/execution/src/capability/audit.ts, packages/execution/src/capability/index.ts, packages/execution/src/index.ts, packages/execution/src/sanitize-result.ts, packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/capability/redact.ts#redactSecretsFromUnknown -> packages/execution/src/capability/index.ts, packages/execution/src/index.ts, packages/execution/src/sanitize-result.ts
  • packages/execution/src/command.ts#runConfiguredCommand -> packages/adapters/src/command-adapter.ts, packages/cli/src/product/generated-tests/runner.ts, packages/cli/src/product/generated-tests/runner/retry.ts, packages/cli/src/product/runtime/service.ts, packages/execution/src/index.ts, packages/execution/test/capability-policy.test.ts, packages/execution/test/execution.test.ts, packages/harness/src/loop/agent.ts, packages/tool-adapters/src/agent-process/run.ts, packages/tool-adapters/src/pact/harness.ts, packages/tool-adapters/src/playwright/harness.ts, packages/tool-adapters/src/schemathesis/harness.ts, packages/tool-adapters/src/semgrep/run.ts, packages/tool-adapters/src/stryker/run.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts, packages/execution/test/execution.test.ts
  • packages/execution/src/index.ts#appendCapabilityAuditEvent -> packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/index.ts#authorizeCapability -> packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/index.ts#checkPathWithinAllowedRoots -> packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/index.ts#createDefaultCapabilityPolicy -> packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/index.ts#detectShellSubstitution -> packages/cli/src/product/runtime/service.ts, packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • packages/execution/src/index.ts#fetchWithoutExternalRedirect -> packages/cli/src/product/runtime/health.ts, packages/execution/test/capability-policy.test.ts
    • Likely tests: packages/execution/test/capability-policy.test.ts
  • ...and 4 more symbol impact(s)

Language And Parser Coverage

  • Source files classified: 7
  • Fully supported parser files: 7
  • Limited files: 0
  • Unsupported files: 0

Merge Risk Breakdown

  • Score: 28/100
  • Raw score before dampeners: 37/100
  • Adjusted score before severity cap: 28/100
  • Highest contributing severity: Low
  • Evidence mode: heuristic-only

Top contributors:

  • +4 Docs area changed (heuristic): docs/security/threat-model.md touches a docs area and should be reviewed for regression impact.
  • +4 Source area changed (heuristic): packages/execution/src/capability/audit.ts touches a source area and should be reviewed for regression impact.
  • +4 Source area changed (heuristic): packages/execution/src/capability/index.ts touches a source area and should be reviewed for regression impact.
  • +4 Source area changed (heuristic): packages/execution/src/capability/redact.ts touches a source area and should be reviewed for regression impact.
  • +4 Source area changed (heuristic): packages/execution/src/command.ts touches a source area and should be reviewed for regression impact.

Dampeners:

  • -9 Heuristic-only dampener: Merge risk stays conservative until direct evidence exists.

Notes:

  • Heuristic-only merge risk is capped at 54/100 until direct evidence exists.
  • Untrusted memory context is visible but contributes 0 score until trusted evidence corroborates it.

Decay Risk Breakdown

  • Score: 19/100
  • Raw score before dampeners: 25/100
  • Adjusted score before severity cap: 19/100
  • Highest contributing severity: Medium
  • Evidence mode: heuristic-only

Top contributors:

  • +10 High complexity in changed function (heuristic): runConfiguredCommand has estimated cyclomatic complexity 18.
  • +10 Large changed function (heuristic): runConfiguredCommand spans 178 lines, which increases review and regression risk.
  • +3 File spread (structural): Change breadth spans 8 file(s).
  • +2 Change size (structural): Changed lines amplify review cost across 8 file(s).

Dampeners:

  • -6 Heuristic-only dampener: Decay stays conservative until direct evidence exists.

Notes:

  • Heuristic-only decay is capped at 54/100 until direct evidence exists.

Security Risk Breakdown

  • Score: 0/100
  • Raw score before dampeners: 0/100
  • Adjusted score before severity cap: 0/100

Security Matcher Coverage

  • Changed source files scanned: 6
  • Security candidates found: 0
  • Skipped files: 0

Test Evidence

  • Mode: heuristic-only
  • Sources: none
  • Changed source coverage:
  • packages/execution/src/capability/audit.ts: not measured (no measurable changed lines)
  • packages/execution/src/capability/index.ts: not measured (no measurable changed lines)
  • packages/execution/src/capability/redact.ts: not measured (no measurable changed lines)
  • packages/execution/src/command.ts: not measured (no measurable changed lines)
  • packages/execution/src/index.ts: not measured (no measurable changed lines)
  • packages/execution/src/sanitize-result.ts: not measured (no measurable changed lines)
  • Notes:
  • No runtime coverage artifact was found. Test audit remains heuristic-only.

Changed Path Test Proof

Status Count
Runtime-proven 0
Static-only 13
Weakened by mocks 0
Unproven 3
  • Static-only packages/execution/src/capability/audit.ts#appendCapabilityAuditEvent (static-reference, deterministic)
    • Evidence: Referenced by packages/execution/test/capability-policy.test.ts, but no runtime coverage artifact proves changed lines executed.
    • Static references: packages/execution/test/capability-policy.test.ts
    • Repair task: Strengthen packages/execution/test/capability-policy.test.ts so it executes packages/execution/src/capability/audit.ts#appendCapabilityAuditEvent with assertions; static import alone is not proof.
  • Static-only packages/execution/src/capability/index.ts#redactSecretsFromText (static-reference, deterministic)
    • Evidence: Referenced by packages/execution/test/capability-policy.test.ts, but no runtime coverage artifact proves changed lines executed.
    • Static references: packages/execution/test/capability-policy.test.ts
    • Repair task: Strengthen packages/execution/test/capability-policy.test.ts so it executes packages/execution/src/capability/index.ts#redactSecretsFromText with assertions; static import alone is not proof.
  • Unproven packages/execution/src/capability/index.ts#redactSecretsFromUnknown (missing-proof, heuristic)
    • Evidence: No runtime coverage or static test reference was found for this changed path.
    • Repair task: Add an integration test that reaches packages/execution/src/capability/index.ts#redactSecretsFromUnknown without mocking the changed boundary.
  • Static-only packages/execution/src/capability/redact.ts#redactSecretsFromText (static-reference, deterministic)
    • Evidence: Referenced by packages/execution/test/capability-policy.test.ts, but no runtime coverage artifact proves changed lines executed.
    • Static references: packages/execution/test/capability-policy.test.ts
    • Repair task: Strengthen packages/execution/test/capability-policy.test.ts so it executes packages/execution/src/capability/redact.ts#redactSecretsFromText with assertions; static import alone is not proof.
  • Unproven packages/execution/src/capability/redact.ts#redactSecretsFromUnknown (missing-proof, heuristic)
    • Evidence: No runtime coverage or static test reference was found for this changed path.
    • Repair task: Add an integration test that reaches packages/execution/src/capability/redact.ts#redactSecretsFromUnknown without mocking the changed boundary.
  • Static-only packages/execution/src/command.ts#runConfiguredCommand (static-reference, deterministic)
    • Evidence: Referenced by packages/execution/test/capability-policy.test.ts, packages/execution/test/execution.test.ts, but no runtime coverage artifact proves changed lines executed.
    • Static references: packages/execution/test/capability-policy.test.ts, packages/execution/test/execution.test.ts
    • Repair task: Strengthen packages/execution/test/capability-policy.test.ts so it executes packages/execution/src/command.ts#runConfiguredCommand with assertions; static import alone is not proof.
  • Static-only packages/execution/src/index.ts#appendCapabilityAuditEvent (static-reference, deterministic)
    • Evidence: Referenced by packages/execution/test/capability-policy.test.ts, but no runtime coverage artifact proves changed lines executed.
    • Static references: packages/execution/test/capability-policy.test.ts
    • Repair task: Strengthen packages/execution/test/capability-policy.test.ts so it executes packages/execution/src/index.ts#appendCapabilityAuditEvent with assertions; static import alone is not proof.
  • Static-only packages/execution/src/index.ts#authorizeCapability (static-reference, deterministic)
    • Evidence: Referenced by packages/execution/test/capability-policy.test.ts, but no runtime coverage artifact proves changed lines executed.
    • Static references: packages/execution/test/capability-policy.test.ts
    • Repair task: Strengthen packages/execution/test/capability-policy.test.ts so it executes packages/execution/src/index.ts#authorizeCapability with assertions; static import alone is not proof.
  • ...and 8 more changed path proof entries

Untrusted Memory Context

  • Project invariant may be impacted (packages/execution/src/capability/audit.ts:4): Untrusted memory context: invariant "No hidden cloud or model call" applies to this change. The OSS CLI must remain useful without telemetry, API keys, hosted services, required LLM calls, or CodeDecayCloud.
  • Project invariant may be impacted (packages/execution/src/capability/audit.ts:4): Untrusted memory context: invariant "Commands are explicit" applies to this change. CodeDecay must not run project commands unless they are configured and safety.allowCommands is true.
  • Project invariant may be impacted (docs/security/threat-model.md:73): Untrusted memory context: invariant "Tool evidence is separate from AI suggestions" applies to this change. Reports must not present agent/model suggestions as verified evidence unless backed by deterministic checks or command output.
  • Project invariant may be impacted (docs/security/threat-model.md:73): Untrusted memory context: invariant "Output must be actionable" applies to this change. Redteam reports and agent bundles should say what behavior to verify, which test proof is weak or missing, and what task a coding agent should perform.
  • Architecture note applies (packages/execution/src/capability/audit.ts:4): Untrusted architecture context: Local-first redteam workflow: codedecay redteam is deterministic and report-only by default. Command execution and LLM/provider use require explicit user configuration.

Medium Risk Findings

  • High complexity in changed function (packages/execution/src/command.ts:13): runConfiguredCommand has estimated cyclomatic complexity 18.
  • Large changed function (packages/execution/src/command.ts:13): runConfiguredCommand spans 178 lines, which increases review and regression risk.

Low Risk Findings

  • Docs area changed (docs/security/threat-model.md:73): docs/security/threat-model.md touches a docs area and should be reviewed for regression impact.
  • Source area changed (packages/execution/src/capability/audit.ts:4): packages/execution/src/capability/audit.ts touches a source area and should be reviewed for regression impact.
  • Source area changed (packages/execution/src/capability/index.ts:5): packages/execution/src/capability/index.ts touches a source area and should be reviewed for regression impact.
  • Source area changed (packages/execution/src/capability/redact.ts:1): packages/execution/src/capability/redact.ts touches a source area and should be reviewed for regression impact.
  • Source area changed (packages/execution/src/command.ts:8): packages/execution/src/command.ts touches a source area and should be reviewed for regression impact.
  • Source area changed (packages/execution/src/index.ts:12): packages/execution/src/index.ts touches a source area and should be reviewed for regression impact.
  • Source area changed (packages/execution/src/sanitize-result.ts:1): packages/execution/src/sanitize-result.ts touches a source area and should be reviewed for regression impact.
  • Test area changed (packages/execution/test/capability-policy.test.ts:7): packages/execution/test/capability-policy.test.ts touches a test area and should be reviewed for regression impact.

Recommended Checks

  • Add an integration test that reaches packages/execution/src/capability/index.ts#redactSecretsFromUnknown without mocking the changed boundary.
  • Add an integration test that reaches packages/execution/src/capability/redact.ts#redactSecretsFromUnknown without mocking the changed boundary.
  • Add an integration test that reaches packages/execution/src/sanitize-result.ts#sanitizeExecutionResult without mocking the changed boundary.
  • Add or run tests covering packages/execution/src/capability/index.ts
  • Add or run tests covering packages/execution/src/capability/redact.ts
  • Add or run tests covering packages/execution/src/index.ts
  • Add or run tests covering packages/execution/src/sanitize-result.ts
  • Flow check (Pull request redteam review): Check weak or missing test proof
  • Flow check (Pull request redteam review): Keep deterministic evidence separate from AI suggestions
  • Flow check (Pull request redteam review): Review edge cases and agent fix tasks
  • Flow check (Pull request redteam review): Run codedecay redteam against the PR diff
  • packages/analyzer-js/test/weak-test-audit.test.ts

Notes

CodeDecay is deterministic and local-first. This report was generated without telemetry, API keys, LLMs, or model calls.


Found by CodeDecay - deterministic, local-first, no telemetry.

@kunaldhongade
kunaldhongade merged commit ba22fd0 into main Aug 6, 2026
10 checks passed
@kunaldhongade
kunaldhongade deleted the feature/690-secret-redaction branch August 6, 2026 12:40
kunaldhongade added a commit that referenced this pull request Aug 6, 2026
…udit (#746)

Scrub Bearer tokens, API keys, and common secret patterns from command stdout/stderr/errors and capability audit events before they are returned or persisted. Refs #690.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs README, community files, or documentation area: execution Safe command and behavior probe execution documentation Improvements or additions to documentation type: test Test coverage, fixtures, or verification improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant