Skip to content

fix(cli): persist sandbox authentication and sessions - #29671

Open
BLVCK-MAMBA-6 wants to merge 2 commits into
google-gemini:mainfrom
BLVCK-MAMBA-6:fix/29461-sandbox-persistence
Open

BLVCK-MAMBA-6 wants to merge 2 commits into
google-gemini:mainfrom
BLVCK-MAMBA-6:fix/29461-sandbox-persistence

Conversation

@BLVCK-MAMBA-6

Copy link
Copy Markdown

Summary

Persist authentication, folder-trust, and session state across sandbox container invocations.

This fixes the repeated authentication prompts, lost sessions, and folder-trust restart loop reported in #29461 while keeping the rest of the host Gemini configuration isolated from the sandbox.

Details

  • Stores sandbox-owned persistent state in ~/.gemini/sandbox.
  • Restores approved state into the isolated settings directory before starting the container.
  • Saves approved state before removing the temporary settings directory.
  • Uses an explicit allowlist for authentication, trust, history, and session files.
  • Persists only the selected authentication fields from settings.json; hooks, commands, and other host settings remain excluded.
  • Protects the persistent directory and authentication settings with restrictive filesystem permissions.
  • Adds unit coverage for restoration, persistence, allowlisting, authentication-setting filtering, and sandbox lifecycle integration.

Related Issues

Fixes #29461

How to Validate

Run the focused unit tests:

npm test -w @google/gemini-cli -- \
  src/utils/sandboxUtils.test.ts \
  src/utils/sandbox.test.ts

Expected result: all 97 tests pass.

Run ESLint against the changed files:

npx eslint --no-cache --max-warnings 0 \
  packages/cli/src/utils/sandbox.ts \
  packages/cli/src/utils/sandbox.test.ts \
  packages/cli/src/utils/sandboxUtils.ts \
  packages/cli/src/utils/sandboxUtils.test.ts

For a Docker integration test:

GEMINI_SANDBOX=docker npm run build:sandbox
GEMINI_SANDBOX=docker npm start -- --sandbox
  1. Authenticate and trust the working directory.
  2. Start a conversation and exit the CLI.
  3. Launch the sandbox again.
  4. Confirm authentication and folder trust are not requested again.
  5. Run gemini --resume or gemini --list-sessions and confirm the previous session is available.

The local Docker smoke test confirmed that credentials and folder trust were restored without entering the restart loop. A complete live-session interaction was blocked by an unrelated unsupported-nightly-client response, while session persistence paths are covered by the unit tests.

The repository-wide lint command was terminated by the local environment with exit code 143; focused ESLint on all changed files passed.

Pre-Merge Checklist

  • Updated relevant documentation and README (not needed; internal behavior only)
  • Added/updated tests
  • Noted breaking changes (none)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@BLVCK-MAMBA-6
BLVCK-MAMBA-6 requested a review from a team as a code owner October 7, 2026 15:54
@google-cla

google-cla Bot commented Oct 7, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@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 introduces persistent state management for the Gemini CLI sandbox environment. By enabling the retention of authentication, folder-trust, and session data, it resolves issues related to repeated prompts and lost sessions while maintaining strict security boundaries between the host environment and the isolated sandbox container.

Highlights

  • State Persistence: Implemented a mechanism to persist sandbox authentication, folder-trust, and session state across container invocations by storing them in a dedicated directory (~/.gemini/sandbox).
  • Security and Isolation: Ensured host Gemini configuration remains isolated by using an explicit allowlist for persisted files and applying restrictive filesystem permissions to the new sandbox state directory.
  • Lifecycle Integration: Integrated state restoration and persistence into the sandbox lifecycle, ensuring settings are correctly loaded before container startup and saved upon cleanup.
  • Testing: Added comprehensive unit tests to verify the restoration, persistence, allowlisting, and authentication-setting filtering logic.
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. ↩

@github-actions github-actions Bot added the size/l A large sized PR label Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

📊 PR Size: size/L

  • Lines changed: 402
  • Additions: +393
  • Deletions: -9
  • Files changed: 4

@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 sandbox state persistence and restoration between sandbox invocations, ensuring that sandbox-created state (such as credentials, history, and trusted folders) is safely preserved while remaining isolated from host credentials. The review feedback highlights an issue where fs.chmodSync could throw permission errors on non-POSIX filesystems and abort state persistence, suggesting wrapping it in a try-catch block. Additionally, the feedback points out a style guide violation in the unit tests where process.env is modified directly, recommending the use of vi.stubEnv to prevent test leakage.

Comment on lines +457 to +465
try {
fs.mkdirSync(sandboxStateDir, { recursive: true, mode: 0o700 });
fs.chmodSync(sandboxStateDir, 0o700);
} catch (err) {
debugLogger.warn(
`Failed to prepare persistent sandbox state directory: ${err instanceof Error ? err.message : String(err)}`,
);
return;
}

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.

high

On non-POSIX filesystems (such as Windows or certain shared mounts), fs.chmodSync can throw permission errors (e.g., EPERM). Aborting the entire persistSandboxState function on chmodSync failure will prevent state persistence entirely in these environments. Instead, wrap fs.chmodSync in its own try-catch block to silently ignore permission errors, similar to how it is handled in sandbox.ts.

  try {
    fs.mkdirSync(sandboxStateDir, { recursive: true, mode: 0o700 });
    try {
      fs.chmodSync(sandboxStateDir, 0o700);
    } catch {
      // Silently ignore permission errors on non-POSIX filesystems
    }
  } catch (err) {
    debugLogger.warn(
      `Failed to prepare persistent sandbox state directory: ${err instanceof Error ? err.message : String(err)}`,
    );
    return;
  }

Comment on lines +116 to +117
delete process.env['PATH'];
delete process.env['PYTHONPATH'];

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.

high

According to the repository style guide (Testing Conventions, lines 84-90), modifying process.env directly should be avoided to prevent test leakage. Instead, use vi.stubEnv('NAME', '') to unset environment variables.

Suggested change
delete process.env['PATH'];
delete process.env['PYTHONPATH'];
vi.stubEnv('PATH', '');
vi.stubEnv('PYTHONPATH', '');
References
  1. Testing Conventions (lines 84-90) state that when testing code that depends on environment variables, we should use vi.stubEnv('NAME', 'value') in beforeEach and vi.unstubAllEnvs() in afterEach, and avoid modifying process.env directly to prevent test leakage. (link)

Comment on lines +761 to +762
delete process.env['PATH'];
delete process.env['PYTHONPATH'];

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.

high

According to the repository style guide (Testing Conventions, lines 84-90), modifying process.env directly should be avoided to prevent test leakage. Instead, use vi.stubEnv('NAME', '') to unset environment variables.

Suggested change
delete process.env['PATH'];
delete process.env['PYTHONPATH'];
vi.stubEnv('PATH', '');
vi.stubEnv('PYTHONPATH', '');
References
  1. Testing Conventions (lines 84-90) state that when testing code that depends on environment variables, we should use vi.stubEnv('NAME', 'value') in beforeEach and vi.unstubAllEnvs() in afterEach, and avoid modifying process.env directly to prevent test leakage. (link)

@gemini-cli gemini-cli Bot added priority/p1 Important and should be addressed in the near term. area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt labels Oct 7, 2026

This branch has not been deployed

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

Labels

area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt priority/p1 Important and should be addressed in the near term. size/l A large sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sandboxed Gemini CLI loses login and session information since v0.60.0

1 participant