Skip to content

runtime: harden external process invocation - #94

Merged
Gregory Joseph (gnjoseph) merged 8 commits into
microsoft:mainfrom
gnjoseph:fix/process-invocation-hardening-main
Aug 26, 2026
Merged

runtime: harden external process invocation#94
Gregory Joseph (gnjoseph) merged 8 commits into
microsoft:mainfrom
gnjoseph:fix/process-invocation-hardening-main

Conversation

@gnjoseph

@gnjoseph Gregory Joseph (gnjoseph) commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • centralize external CLI launches behind a shell-free process abstraction
  • validate Azure subscription and resource-group identifiers before process, app, or container-type side effects
  • preserve Windows CLI shim resolution, timeout, error, and detached-process behavior
  • release as @microsoft/spe-mcp@0.2.0-alpha.3

Validation

  • local npm run ci passed with 915 tests and 7 skips
  • sanitized local happy/failure proof is embedded below

Proof

Sanitized local proof generated from completed Vitest runs. All identifiers and process inputs shown are inert; no tenant data, credentials, or live environment evidence is included.

Shell-free happy path

Arguments remain discrete and both launch APIs force shell: false.

PR 94 shell-free happy path proof

Invalid Azure identifier rejection

A malformed inert Azure identifier is rejected before the Azure CLI process seam.

PR 94 invalid Azure identifier rejection proof

Synchronous spawn error normalization

Pre-launch synchronous throws are normalized to the RunCommandError contract with message, stack, optional code, and initialized stdout/stderr.

PR 94 synchronous spawn error normalization proof

Centralize external CLI launches behind a shell-free process abstraction, validate Azure identifiers at the tool and helper boundaries, and add focused regression coverage.

AB#3116729
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR promotes the external process-invocation hardening work into main by centralizing az/azd/dev-server launches behind a shell-free process abstraction and tightening validation for Azure identifiers before they become CLI arguments.

Changes:

  • Introduces src/proc-exec.ts (runCommand / spawnProcess) to ensure shell-free child process execution (including Windows .cmd/.bat shim resolution via cross-spawn).
  • Adds strict Azure subscription ID + resource-group validation helpers (predicate/require/assert) and applies subscription validation in azure_resource_groups_list.
  • Updates multiple tools/helpers and tests to use the new process seam; bumps package version to 0.2.0-alpha.2 and records the change in the changelog.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/validation.ts Adds allowlist-based Azure subscription/resource-group validation helpers (predicate/require/assert).
src/validation.test.ts Adds regression coverage for the new Azure identifier validation helpers.
src/tools/run-local.ts Switches dev-server spawning to the shared shell-free launcher.
src/tools/run-local.test.ts Updates mocks/assertions to target proc-exec rather than node:child_process.
src/tools/list-azure.ts Centralizes subscriptionId validation via requireAzureSubscriptionId before calling CLI helpers.
src/tools/list-azure.test.ts Adds tests proving invalid/missing subscription IDs are rejected before invoking the CLI helper.
src/tools/deploy-azure.ts Replaces direct execFile usage with runCommand for azd/az invocations.
src/tools/deploy-azure.test.ts Updates mocks to the new launcher seam and adds argv-discreteness regression coverage.
src/proc-exec.ts New shell-free process abstraction built on cross-spawn.
src/proc-exec.test.ts Adds contract tests for shell-free behavior, argv discreteness, error shaping, and timeouts.
src/bootstrap.ts Routes Azure CLI bootstrap calls through runCommand (shell-free).
src/bootstrap.test.ts Updates mocking strategy to proc-exec and asserts shell-free invocation contract.
src/azure-cli.ts Routes Azure CLI helper calls through runCommand and asserts identifier validity at the process seam.
src/azure-cli.proc.test.ts Adds process-boundary contract tests (reject-before-spawn + discrete argv).
package.json Bumps version to 0.2.0-alpha.2 and adds cross-spawn + typings.
package-lock.json Updates lockfile for the version bump and new direct dependency.
CHANGELOG.md Documents the process hardening and validation changes for 0.2.0-alpha.2.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/proc-exec.ts Outdated
grjoseph and others added 2 commits August 20, 2026 18:05
Reserve a new npm version for the main-based ESRP release because 0.2.0-alpha.2 has already been submitted.

AB#3116729
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep server.json synchronized with package.json and enforce the invariant in CI.

AB#3116729
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.

grjoseph and others added 5 commits August 24, 2026 10:38
Keep pre-launch spawn exceptions on the RunCommandError contract while preserving their diagnostics and initializing buffered output.

Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reject malformed explicit standard-billing subscription and resource-group values before Azure CLI, app, or container-type work. Reuse the shared boundary validation in guided and direct container-type flows and add no-side-effect regressions.

Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Validate zero-resource-group elicitation results before the existence probe so whitespace-only and malformed names cannot reach Azure helpers or resource creation. Add helper and end-to-end no-side-effect regressions for both provisioning surfaces.

Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Match Azure's documented Unicode and leading-hyphen naming rules while binding option-like names to the Azure CLI flag without a shell.

Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve project-cwd tool launches from canonical absolute host PATH entries, reject project-local targets, and surface resolution failures without enabling shell mode.

Copilot-Session-Id: 9b07fed7-d2cf-4209-8682-6c3004401c04

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@gnjoseph
Gregory Joseph (gnjoseph) merged commit 844875e into microsoft:main Aug 26, 2026
6 checks passed
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.

3 participants