Skip to content

refactor(a2a-server): enforce path trust check prior to environment loading and isolate task environment - #28319

Closed
luisfelipe-alt wants to merge 10 commits into
google-gemini:mainfrom
luisfelipe-alt:bugfix/WT-engineer_519269096
Closed

refactor(a2a-server): enforce path trust check prior to environment loading and isolate task environment#28319
luisfelipe-alt wants to merge 10 commits into
google-gemini:mainfrom
luisfelipe-alt:bugfix/WT-engineer_519269096

Conversation

@luisfelipe-alt

@luisfelipe-alt luisfelipe-alt commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR refactors the initialization lifecycle and environment loading order inside CoderAgentExecutor (a2a-server) to ensure that workspace path trust checks occur prior to loading workspace-level environment variables. Furthermore, it introduces AsyncLocalStorage (envStorage) to isolate process.env modifications on a per-task basis.

By refactoring the startup sequence, environment loading mechanism, and introducing robust task-level environment and process isolation in a2a-server, we ensure that workspace-level environment files (.env and .gemini/.env) are completely ignored unless the workspace is explicitly trusted by the user. This
aligns the a2a-server backend's security model with the existing secure implementation in the CLI frontend.

Details

  1. Startup Sequence Refactoring:
    • Deferred the call to loadEnvironment() in
      packages/a2a-server/src/http/app.ts (createApp) and
      packages/a2a-server/src/agent/executor.ts (getConfig) until after
      workspace trust is evaluated (checkPathTrust / setIsTrusted).
    • This prevents an attacker from placing GEMINI_CLI_TRUST_WORKSPACE=true
      inside a malicious .gemini/.env file to self-validate their own
      untrusted workspace before trust is checked.
  2. Secure Environment Loading:
    • Updated loadEnvironment(isTrusted) in
      packages/a2a-server/src/config/config.ts to accept the trust state.
    • If isTrusted is false, workspace-level environment files (both .env
      and .gemini/.env) are completely ignored. Instead, the loader only loads
      environment variables from the user's trusted home directory (e.g.,
      ~/.gemini/.env or ~/.env). This is a safer and more secure approach
      that completely isolates untrusted workspaces from environment loading.
  3. Task-Isolated Environment Loading (AsyncLocalStorage & Proxy):
    • Introduced envStorage (an AsyncLocalStorage context) and a robust
      Proxy on process.env to completely isolate environment variables per
      task, preventing cross-task credential leakage and race conditions in
      concurrent multi-request server environments.
    • Refactored both getConfig and execute in
      packages/a2a-server/src/agent/executor.ts to execute loadEnvironment
      inside the envStorage.run block, ensuring that environment variables are
      never written to the global process.env.
  4. Robust Symbol Delegation in Proxy:
    • Refactored the envProxy to correctly handle non-string properties
      (Symbols like Symbol.toStringTag or util.inspect.custom) by delegating
      them to the original process.env object, preventing standard Node.js
      utilities (like util.inspect) from breaking and avoiding strict-mode
      TypeErrors.
    • The implementation completely avoids the Reflect namespace to comply
      with the project's linter rules (no-restricted-syntax).
  5. Proxy Deletion Correctness:
    • Introduced a unique deletedKeysSymbol to track explicitly deleted keys
      within the task context, ensuring that subsequent reads and checks
      correctly treat deleted keys as non-existent instead of falling back to
      the global process.env.
  6. Resolved process.chdir Race Condition:
    • Removed process.chdir from setTargetDir in
      packages/a2a-server/src/config/config.ts. Instead of globally mutating
      the process's working directory, we now pass workspaceDir explicitly as
      an argument to loadConfig and other services, completely eliminating the
      race condition where concurrent requests could hijack each other's working
      directory.
  7. Adhered to Testing Style Guide:
    • Updated all vi.stubEnv calls in tests to use an empty string ''
      instead of undefined to unset environment variables, and updated the
      assertions to use toBeFalsy() to match.

Related Issues

Fixes #519269096 (Buganizer: b-519269096) Related to #496967516 (Buganizer:
b-496967516)

How to Validate

Important

Because the previous test failures affected all environments (Linux, macOS,
and Windows) due to platform-independent headless and mock context issues,
validation must be performed across all three platforms to guarantee
complete compatibility and prevent any future pipeline regressions.

  1. Run Unit Tests: Verify that the new comprehensive test suite passes
    successfully on your platform:
    npm test -w @google/gemini-cli-a2a-server
    npm test -w @google/gemini-cli-core
  2. Run Linting: Verify code quality and formatting:
    npm run lint
  3. Run Type Checking: Verify TypeScript compilation:
    npm run typecheck

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
    • Windows
      • npm run
    • Linux
      • npm run
      • npx

@luisfelipe-alt
luisfelipe-alt requested a review from a team as a code owner July 8, 2026 17:38
@github-actions github-actions Bot added the size/m A medium sized PR label Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

📊 PR Size: size/XL

  • Lines changed: 1583
  • Additions: +1107
  • Deletions: -476
  • Files changed: 17

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical security vulnerability that allowed for Remote Code Execution (RCE) by exploiting the environment loading mechanism in untrusted workspaces. By refactoring the startup sequence to ensure workspace trust is established before loading environment files, and by enforcing strict variable whitelisting and sanitization, the server now prevents malicious environment configurations from compromising the system.

Highlights

  • Security Refactoring: Deferred environment loading until after workspace trust is verified to prevent environment poisoning.
  • Environment Sanitization: Implemented strict whitelisting and sanitization for environment variables in untrusted workspaces.
  • Vulnerability Mitigation: Added a comprehensive test suite to verify the fix for the identified RCE vulnerability.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request implements workspace trust checks and environment variable sanitization/whitelisting when loading .env files in packages/a2a-server to mitigate RCE vulnerabilities. The review feedback identifies critical security issues: the dynamic use of process.cwd() allows loading malicious .env files from arbitrary paths, and the server blindly trusts the client-supplied isTrusted flag. To resolve these, the reviewer recommends performing server-side trust verification, passing explicit workspace paths instead of changing the global directory, and completely bypassing workspace-level .env loading for untrusted workspaces, which simplifies the loading logic and requires updating the associated tests.

Comment thread packages/a2a-server/src/config/config.ts Outdated
Comment thread packages/a2a-server/src/agent/executor.ts Outdated
Comment thread packages/a2a-server/src/config/config.ts Outdated
Comment thread packages/a2a-server/src/config/config.ts Outdated
Comment thread packages/a2a-server/src/config/rce_vulnerability.test.ts Outdated

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request implements security mitigations to prevent Remote Code Execution (RCE) in untrusted workspaces by restricting environment variable loading to a whitelist and sanitizing values. However, a critical security vulnerability remains: the server relies on the client-supplied agentSettings.isTrusted parameter to determine workspace trust, which can be easily bypassed by an attacker. The trust check should be performed entirely on the server side.

Comment thread packages/a2a-server/src/agent/executor.ts Outdated
@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label Jul 8, 2026
@luisfelipe-alt
luisfelipe-alt force-pushed the bugfix/WT-engineer_519269096 branch 5 times, most recently from 565449a to 749b6f1 Compare July 8, 2026 21:41
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces workspace trust verification for loading environment variables and settings, ensuring that untrusted workspaces do not load sensitive environment variables. While these changes improve security, critical vulnerabilities remain: workspace-level extensions are still loaded unconditionally, which could allow Remote Code Execution (RCE) in untrusted workspaces. Additionally, the environment loading logic is susceptible to path traversal above the home directory, and the new tests lack hermeticity because os.homedir is not mocked.

Comment thread packages/a2a-server/src/agent/executor.ts Outdated
Comment thread packages/a2a-server/src/http/app.ts Outdated
Comment thread packages/a2a-server/src/config/config.ts Outdated
Comment thread packages/a2a-server/src/config/rce_vulnerability.test.ts
@luisfelipe-alt
luisfelipe-alt force-pushed the bugfix/WT-engineer_519269096 branch 6 times, most recently from b41911e to af80408 Compare July 9, 2026 00:00
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces security mitigations to prevent loading environment variables and extensions from untrusted workspaces. The review feedback highlights a critical security vulnerability where folder trust settings are read from the untrusted workspace itself, potentially allowing a bypass. Additionally, the feedback points out a functional regression in environment variable overriding, an inconsistent function call in app.ts, and style guide violations in the new test file regarding direct process.env mutations instead of using Vitest's stubbing utilities.

Comment thread packages/a2a-server/src/agent/executor.ts
Comment thread packages/a2a-server/src/config/config.ts
Comment thread packages/a2a-server/src/http/app.ts Outdated
Comment thread packages/a2a-server/src/config/rce_vulnerability.test.ts Outdated
Comment thread packages/a2a-server/src/config/rce_vulnerability.test.ts Outdated
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request implements security mitigations against Remote Code Execution (RCE) vulnerabilities (b-519269096) by isolating environment variable and extension loading for untrusted workspaces. It prevents untrusted workspaces from loading workspace-level .env files or extensions, restricts workspace paths to allowed root directories, and passes isolated environment variables to child processes (such as checkers and shell tools) instead of polluting the global process.env. Additionally, external editor spawning is disabled in headless/server mode, and tests have been added to verify these security boundaries. I have no feedback to provide as there are no review comments.

Note: Security Review did not run due to the size of the PR.

@gemini-cli

gemini-cli Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Hi there! Thank you for your interest in contributing to Gemini CLI.

To ensure we maintain high code quality and focus on our prioritized roadmap, we only guarantee review and consideration of pull requests for issues that are explicitly labeled as 'help wanted'.

This PR will be closed in 7 days if it remains without that designation. We encourage you to find and contribute to existing 'help wanted' issues in our backlog! Thank you for your understanding.

@DavidAPierce

Copy link
Copy Markdown
Contributor

Critical Finding: Discarded Task Isolation and Proxy Logic

A comparison between the pull request description and the actual codebase
reveals a major discrepancy. The description claims that the pull request
introduces AsyncLocalStorage (envStorage) and a Proxy on process.env to
completely isolate environment variables per task and prevent cross-task
credential leakages.

However, during inspection of the branch history, it was noted that these
additions were completely removed in merge commit ff194f7e4 ("merge: resolve
conflicts with upstream/main").

Code Discrepancies and Impact

The removal of the task isolation logic would have
consequences for the A2A server.

  • No Concurrent Isolation: The server currently runs without any task-level
    environment or directory isolation. Concurrent requests will share the same
    global process.env and process.cwd(), leading to potential race conditions
    and credential leakage across tasks.
  • Out of Date Description: The pull request summary still discusses
    deletedKeysSymbol, envProxy symbol delegation, and process.chdir
    monkey-patching, none of which exist in the current pull request branch.

Recommended Action

Here are a couple paths forward (I recommend option 1):

  1. Restore Task Isolation: Re-integrate the envStorage and envProxy logic
    originally introduced in commit 8d1178584. Ensure that it is merged with
    main correctly without being discarded.
  2. Revise the Design and Description: If the task isolation approach was
    deliberately abandoned in favor of explicit composition, please
    update the pull request description to reflect this and explain how we
    intend to handle concurrent workspace isolation without it, or propose an alternative solution.

@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request implements workspace isolation and environment variable sandboxing for the agent-to-agent server (a2a-server) to mitigate remote code execution vulnerabilities. It introduces task-specific environment isolation using AsyncLocalStorage and a Proxy on process.env, and updates configuration loading to bypass untrusted workspace .env files. However, the envProxy implementation intercepts non-string properties (such as Symbols) and returns undefined or false, which can break standard Node.js utilities like util.inspect or third-party libraries. It is recommended to delegate non-string properties directly to the original process.env target.

Comment thread packages/a2a-server/src/config/config.ts
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request implements task-level environment and workspace isolation in the a2a-server package using AsyncLocalStorage and a Proxy on process.env, alongside monkey-patching process.cwd and process.chdir. It also disables external editor spawning in headless/server mode and ensures isolated environment variables are propagated to shell execution and content generation. Feedback was provided regarding a security vulnerability where the envProxy lacks a defineProperty trap, which could allow dependencies to bypass the proxy's set trap and pollute the global process.env.

Comment thread packages/a2a-server/src/config/config.ts
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces task-level environment and working directory isolation in the a2a-server package using AsyncLocalStorage and a Proxy on process.env to mitigate potential remote code execution (RCE) vulnerabilities from untrusted workspaces. It also updates core services to propagate these isolated environments and disables external editor spawning in headless mode. However, a critical security issue was identified where the main task execution loop in execute is not wrapped in the isolated environment context, causing it to fall back to the global process environment and working directory.

Note: Security Review did not run due to the size of the PR.

Comment thread packages/a2a-server/src/agent/executor.ts
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces workspace isolation and environment variable sandboxing to mitigate remote code execution (RCE) vulnerabilities. It leverages AsyncLocalStorage and a Proxy on process.env to isolate environment variables per task, restricts .env and extension loading in untrusted workspaces, and disables external editor spawning in headless mode. Feedback on the changes highlights a potential unhandled exception in execute where validateWorkspacePath is called synchronously before entering the isolated environment, which could lead to server crashes; wrapping this setup in a try-catch block and notifying the event bus is recommended.

Comment thread packages/a2a-server/src/agent/executor.ts
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request implements workspace and environment isolation for tasks in the a2a-server package to mitigate remote code execution (RCE) vulnerabilities. It uses AsyncLocalStorage and a Proxy on process.env to isolate environment variables and the working directory per task, restricts .env loading in untrusted workspaces, and updates core packages to pass isolated environment variables. The review feedback identifies two key issues: the monkey-patched process.chdir should throw ENOENT errors matching Node's native format, and a .catch block should be added to runInIsolatedEnv in execute to prevent unhandled promise rejections and client hangs during setup failures.

Note: Security Review did not run due to the size of the PR.

Comment thread packages/a2a-server/src/config/config.ts
Comment thread packages/a2a-server/src/agent/executor.ts
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces robust workspace and environment isolation to mitigate Remote Code Execution (RCE) vulnerabilities in the Agent-to-Agent (A2A) server. It implements task-level environment isolation using AsyncLocalStorage and a Proxy on process.env, and monkey-patches process.cwd and process.chdir to prevent cross-task interference. Untrusted workspaces are restricted from loading workspace-level .env files or extensions, and workspace paths are validated against allowed root directories. Additionally, core services like ShellExecutionService and CheckerRunner have been updated to respect these isolated configurations, and external editor spawning is disabled in headless mode. There are no review comments provided, so I have no feedback to offer.

Note: Security Review did not run due to the size of the PR.

@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

Critical Finding: Discarded Task Isolation and Proxy Logic

A comparison between the pull request description and the actual codebase reveals a major discrepancy. The description claims that the pull request introduces AsyncLocalStorage (envStorage) and a Proxy on process.env to completely isolate environment variables per task and prevent cross-task credential leakages.

However, during inspection of the branch history, it was noted that these additions were completely removed in merge commit ff194f7e4 ("merge: resolve conflicts with upstream/main").

Code Discrepancies and Impact

The removal of the task isolation logic would have consequences for the A2A server.

  • No Concurrent Isolation: The server currently runs without any task-level
    environment or directory isolation. Concurrent requests will share the same
    global process.env and process.cwd(), leading to potential race conditions
    and credential leakage across tasks.
  • Out of Date Description: The pull request summary still discusses
    deletedKeysSymbol, envProxy symbol delegation, and process.chdir
    monkey-patching, none of which exist in the current pull request branch.

Recommended Action

Here are a couple paths forward (I recommend option 1):

  1. Restore Task Isolation: Re-integrate the envStorage and envProxy logic
    originally introduced in commit 8d1178584. Ensure that it is merged with
    main correctly without being discarded.
  2. Revise the Design and Description: If the task isolation approach was
    deliberately abandoned in favor of explicit composition, please
    update the pull request description to reflect this and explain how we
    intend to handle concurrent workspace isolation without it, or propose an alternative solution.

Hi @DavidAPierce , I have updated the code, it's ready to next round of code review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l A large sized PR size/m A medium sized PR size/xl An extra large PR status/pr-nudge-sent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants