Skip to content

chore: add a shared subprocess execution module to private-tools - #1763

Merged
mrgrain merged 4 commits into
mainfrom
iankhou-subprocess-module
Jul 28, 2026
Merged

chore: add a shared subprocess execution module to private-tools#1763
mrgrain merged 4 commits into
mainfrom
iankhou-subprocess-module

Conversation

@iankhou

@iankhou iankhou commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

No functional changes, adds utilities that need to be wired in.

Unifying how the toolchain talks to the shell (split out of #1758 to keep diffs reviewable).

Add utilities to packages/@aws-cdk/private-tools/lib/subprocess/index.ts.

  • run(argv) / runSync(argv) — argv-array spawn, never a shell. Windows .cmd/.bat shims are resolved by cross-spawn (modern Node refuses to spawn batch shims directly, CVE-2024-27980). Shell injection is impossible by construction, so no argument escaping exists at all. Inside of the trust boundary.

  • runUserCommandLine(line) — the only path to a shell. Reserved for command lines the user authored themselves (cdk.json app, --browser), so it's outside of the trust boundary. Deliberately has no argv form, so command lines cannot be assembled from parts.

  • renderForDisplay() (display-only, allowlist-based quoting), SubprocessError with a kind discriminant, stateful UTF-8 decoding across pipe chunks, stdin EPIPE tolerance, line-buffered output, capture/inherit-stderr/inherit stdio modes, and opt-out output collection.

No call sites change in this PR — the migrations (init, synth, docs, npm, ec2-detection, cdk-assets shell) are in the follow-up PR: #1758.

Adds 56 unit tests.

Checklist

  • Unit tests added/updated
  • Integration tests (n/a — no behavior change until consumers migrate)
  • No manual edits to generated files

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

…e-tools

Adds @aws-cdk/private-tools/lib/subprocess, one audited implementation of
child-process execution for the toolchain, with exactly two shapes:

- run(argv) / runSync(argv): argv-array spawn, never a shell. Windows
  .cmd/.bat shims are resolved by cross-spawn (modern Node refuses to
  spawn batch shims directly, CVE-2024-27980). Shell injection is
  impossible by construction, so no argument escaping exists at all.
- runUserCommandLine(line): the only path to a shell, reserved for
  command lines the user authored themselves (cdk.json app command,
  --browser). Deliberately has no argv form.

Also included:
- renderForDisplay(argv): display-only quoting for logs, allowlist-based
- SubprocessError with a kind discriminant (spawn-failed|exited|killed)
- Stateful UTF-8 decoding (multi-byte chars split across pipe chunks),
  stdin EPIPE tolerance, line-buffered output delivery, capture /
  inherit-stderr / inherit stdio modes, opt-out output collection

Consumers are migrated in a follow-up PR.
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
See the Details below.

License Issues

packages/@aws-cdk/private-tools/package.json

PackageVersionLicenseIssue Type
cross-spawn^7.0.6NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
npm/@types/cross-spawn ^6.0.6 UnknownUnknown
npm/cross-spawn ^7.0.6 UnknownUnknown
npm/@types/cross-spawn 6.0.6 🟢 6.5
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 4 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 8Found 24/30 approved changesets -- score normalized to 8
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
License🟢 9license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Pinned-Dependencies🟢 8dependency not pinned by hash detected -- score normalized to 8
Binary-Artifacts🟢 10no binaries found in the repo
Fuzzing⚠️ 0project is not fuzzed

Scanned Files

  • packages/@aws-cdk/private-tools/package.json
  • yarn.lock

@iankhou
iankhou requested a review from Copilot July 27, 2026 18:46

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

Adds a new shared subprocess execution module under @aws-cdk/private-tools intended to unify how the CDK toolchain spawns child processes, with a clear trust model split between argv-based execution (run/runSync, no shell) and user-authored command lines (runUserCommandLine, shell). This PR is foundational (no consumer migrations yet) and focuses on correctness, security boundaries, and test coverage.

Changes:

  • Introduces packages/@aws-cdk/private-tools/lib/subprocess with run(), runSync(), runUserCommandLine(), SubprocessError, and display-only rendering utilities.
  • Adds comprehensive unit tests for piping, timeouts, failure classification, UTF-8 chunk decoding, line buffering, and Windows .cmd shim behavior.
  • Wires in cross-spawn (and types) via projen + package metadata updates.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
yarn.lock Adds cross-spawn and @types/cross-spawn entries to the lockfile.
packages/@aws-cdk/private-tools/tsconfig.json Includes cross-spawn typings due to restricted types list.
packages/@aws-cdk/private-tools/test/subprocess/subprocess.test.ts New unit test suite covering subprocess behaviors and edge cases.
packages/@aws-cdk/private-tools/package.json Adds cross-spawn (runtime) and @types/cross-spawn (dev) dependencies.
packages/@aws-cdk/private-tools/lib/subprocess/index.ts Implements the shared subprocess execution module and error model.
packages/@aws-cdk/private-tools/.projen/tasks.json Updates dependency task filters to include @types/cross-spawn.
packages/@aws-cdk/private-tools/.projen/deps.json Records new runtime/build deps for projen-managed dependency tracking.
.projenrc.ts Adds a subprocess tool definition to the private-tools tool set (deps/devDeps).
Comments suppressed due to low confidence (1)

packages/@aws-cdk/private-tools/lib/subprocess/index.ts:303

  • This comment says DISPLAY_SAFE contains characters that “never need quoting … on any platform”, but Windows intentionally treats % as unsafe (cmd.exe expansion) and forces quoting via a special-case check. Updating the comment would prevent future changes from accidentally reintroducing % as a Windows-safe character based on this docstring.
 * Characters that never need quoting for display, on any platform.
 *
 * Everything else — including every POSIX and cmd.exe metacharacter (`;`, `|`,
 * `&`, `<`, `>`, `(`, `)`, backtick, `*`, `^`, `%`, quotes, whitespace, …) —

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/@aws-cdk/private-tools/lib/subprocess/index.ts
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.

4 participants