gemini-cli - ✅(Solved) Fix Sandboxing: Support absolute paths for `SEATBELT_PROFILE` on macOS [3 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
google-gemini/gemini-cli#24991Fetched 2026-04-09 08:16:28
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
labeled ×2issue_type_added ×1

PR fix notes

PR #25013: feature: allow absolute path for macos seatbelt profiles (sandbox)

Description (problem / solution / changelog)

Summary

<!-- Concisely describe what this PR changes and why. Focus on impact and urgency. -->

Enhance macOS Seatbelt configuration flexibility by allowing the SEATBELT_PROFILE environment variable to accept absolute paths. This enables developers to maintain centralized sandbox policies across multiple repositories without duplicating configuration into every project's .gemini folder.

Details

<!-- Add any extra context and design decisions. Keep it brief but complete. -->

Updated the sandbox utility to check if the SEATBELT_PROFILE value is an absolute path.

  • If absolute: Uses the path directly.
  • If relative/name: Continues with existing logic (checking built-in profiles or the project .gemini folder).

This change is non-breaking and preserves all existing workflows.

Related Issues

<!-- Use keywords to auto-close issues (Closes #123, Fixes #456). If this PR is only related to an issue or is a partial fix, simply reference the issue number without a keyword (Related to #123). -->

Closes #24991

How to Validate

GEMINI_SANDBOX=sandbox-exec SEATBELT_PROFILE=$(pwd)/bundle/sandbox-macos-permissive-open.sb node bundle/gemini.js -s

Pre-Merge Checklist

<!-- Check all that apply before requesting review or merging. -->
  • 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
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

Changed files

  • .github/workflows/chained_e2e.yml (modified, +2/-0)
  • .github/workflows/evals-nightly.yml (modified, +15/-5)
  • docs/cli/settings.md (modified, +3/-3)
  • docs/reference/configuration.md (modified, +4/-1)
  • evals/answer-vs-act.eval.ts (modified, +12/-0)
  • evals/app-test-helper.ts (modified, +44/-44)
  • evals/ask_user.eval.ts (modified, +18/-6)
  • evals/automated-tool-use.eval.ts (modified, +4/-0)
  • evals/cli_help_delegation.eval.ts (modified, +2/-0)
  • evals/component-test-helper.ts (added, +136/-0)
  • evals/concurrency-safety.eval.ts (modified, +2/-0)
  • evals/edit-locations-eval.eval.ts (modified, +2/-0)
  • evals/frugalReads.eval.ts (modified, +6/-0)
  • evals/frugalSearch.eval.ts (modified, +2/-12)
  • evals/generalist_agent.eval.ts (modified, +2/-0)
  • evals/generalist_delegation.eval.ts (modified, +8/-0)
  • evals/gitRepo.eval.ts (modified, +4/-0)
  • evals/grep_search_functionality.eval.ts (modified, +12/-0)
  • evals/hierarchical_memory.eval.ts (modified, +7/-2)
  • evals/interactive-hang.eval.ts (modified, +4/-0)
  • evals/model_steering.eval.ts (modified, +4/-2)
  • evals/plan_mode.eval.ts (modified, +12/-0)
  • evals/redundant_casts.eval.ts (modified, +2/-0)
  • evals/sandbox_recovery.eval.ts (modified, +2/-0)
  • evals/save_memory.eval.ts (modified, +28/-2)
  • evals/shell-efficiency.eval.ts (modified, +6/-0)
  • evals/subagents.eval.ts (modified, +12/-0)
  • evals/test-helper.test.ts (modified, +12/-0)
  • evals/test-helper.ts (modified, +94/-54)
  • evals/tool_output_masking.eval.ts (modified, +4/-0)
  • evals/tracker.eval.ts (modified, +4/-0)
  • evals/validation_fidelity.eval.ts (modified, +2/-0)
  • evals/validation_fidelity_pre_existing_errors.eval.ts (modified, +2/-0)
  • evals/vitest.config.ts (modified, +4/-1)
  • package-lock.json (modified, +8/-36)
  • package.json (modified, +2/-2)
  • packages/cli/index.ts (modified, +149/-31)
  • packages/cli/package.json (modified, +1/-1)
  • packages/cli/src/acp/acpClient.ts (modified, +1/-1)
  • packages/cli/src/config/settingsSchema.ts (modified, +2/-1)
  • packages/cli/src/gemini.tsx (modified, +44/-43)
  • packages/cli/src/gemini_cleanup.test.tsx (modified, +3/-0)
  • packages/cli/src/interactiveCli.tsx (modified, +1/-1)
  • packages/cli/src/test-utils/render.tsx (modified, +1/-1)
  • packages/cli/src/ui/AppContainer.tsx (modified, +1/-1)
  • packages/cli/src/ui/__snapshots__/ToolConfirmationFullFrame-Full-Terminal-Tool-Confirmation-Snapshot-renders-tool-confirmation-box-in-the-frame-of-the-entire-terminal.snap.svg (modified, +2/-1)
  • packages/cli/src/ui/__snapshots__/ToolConfirmationFullFrame.test.tsx.snap (modified, +1/-1)
  • packages/cli/src/ui/commands/bugCommand.test.ts (modified, +7/-4)
  • packages/cli/src/ui/commands/bugCommand.ts (modified, +1/-2)
  • packages/cli/src/ui/components/ExitPlanModeDialog.test.tsx (modified, +2/-0)
  • packages/cli/src/ui/components/Footer.test.tsx (modified, +1/-0)
  • packages/cli/src/ui/components/HistoryItemDisplay.test.tsx (modified, +4/-4)
  • packages/cli/src/ui/components/ModelDialog.test.tsx (modified, +1/-0)
  • packages/cli/src/ui/components/SettingsDialog.test.tsx (modified, +1/-1)
  • packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx (modified, +39/-0)
  • packages/cli/src/ui/components/ToolConfirmationQueue.tsx (modified, +2/-2)
  • packages/cli/src/ui/components/__snapshots__/ToolConfirmationQueue-ToolConfirmationQueue-height-allocation-and-layout-should-render-the-full-queue-wrapper-with-borders-and-content-for-large-edit-diffs.snap.svg (modified, +2/-1)
  • packages/cli/src/ui/components/__snapshots__/ToolConfirmationQueue.test.tsx.snap (modified, +3/-3)
  • packages/cli/src/ui/components/messages/DenseToolMessage.test.tsx (modified, +48/-6)
  • packages/cli/src/ui/components/messages/DenseToolMessage.tsx (modified, +18/-53)
  • packages/cli/src/ui/components/messages/ToolGroupMessage.tsx (modified, +0/-11)
  • packages/cli/src/ui/components/messages/__snapshots__/DenseToolMessage.test.tsx.snap (modified, +6/-7)
  • packages/cli/src/ui/components/shared/BaseSettingsDialog.test.tsx (modified, +1/-1)
  • packages/cli/src/ui/contexts/KeypressContext.test.tsx (modified, +85/-1)
  • packages/cli/src/ui/contexts/KeypressContext.tsx (modified, +14/-2)
  • packages/cli/src/ui/contexts/SessionContext.test.tsx (modified, +4/-4)
  • packages/cli/src/ui/contexts/SessionContext.tsx (modified, +5/-5)
  • packages/cli/src/ui/hooks/useGeminiStream.ts (modified, +6/-14)
  • packages/cli/src/ui/hooks/useLogger.test.tsx (modified, +4/-31)
  • packages/cli/src/ui/hooks/useLogger.ts (modified, +6/-15)
  • packages/cli/src/utils/sandbox.test.ts (modified, +33/-0)
  • packages/cli/src/utils/sandbox.ts (modified, +20/-6)
  • packages/cli/src/utils/sessionUtils.test.ts (modified, +19/-25)
  • packages/cli/src/utils/sessionUtils.ts (modified, +6/-15)
  • packages/cli/src/utils/sessions.ts (modified, +2/-2)
  • packages/core/src/agents/subagent-tool.ts (modified, +1/-0)
  • packages/core/src/core/loggingContentGenerator.test.ts (modified, +1/-0)
  • packages/core/src/core/loggingContentGenerator.ts (modified, +3/-0)
  • packages/core/src/index.ts (modified, +1/-1)
  • packages/core/src/sandbox/macos/MacOsSandboxManager.test.ts (modified, +31/-28)
  • packages/core/src/sandbox/macos/MacOsSandboxManager.ts (modified, +10/-12)
  • packages/core/src/sandbox/macos/seatbeltArgsBuilder.test.ts (modified, +41/-103)
  • packages/core/src/sandbox/macos/seatbeltArgsBuilder.ts (modified, +106/-105)
  • packages/core/src/scheduler/policy.test.ts (modified, +23/-14)
  • packages/core/src/scheduler/scheduler.test.ts (modified, +2/-0)
  • packages/core/src/scheduler/scheduler.ts (modified, +1/-0)
  • packages/core/src/scheduler/scheduler_parallel.test.ts (modified, +1/-0)
  • packages/core/src/scheduler/tool-executor.ts (modified, +1/-0)
  • packages/core/src/telemetry/trace.test.ts (modified, +12/-9)
  • packages/core/src/telemetry/trace.ts (modified, +6/-3)
  • packages/core/src/tools/ls.test.ts (modified, +7/-7)
  • packages/core/src/tools/ls.ts (modified, +1/-1)
  • packages/core/src/tools/shell.test.ts (modified, +40/-26)
  • packages/core/src/tools/shell.ts (modified, +7/-3)
  • packages/core/src/utils/session.ts (modified, +0/-2)
  • packages/sdk/src/session.test.ts (modified, +2/-1)
  • schemas/settings.schema.json (modified, +2/-2)

PR #25024: feature: feature: allow absolute path for macos seatbelt profiles (sa…

Description (problem / solution / changelog)

Summary

<!-- Concisely describe what this PR changes and why. Focus on impact and urgency. -->

Enhance macOS Seatbelt configuration flexibility by allowing the SEATBELT_PROFILE environment variable to accept absolute paths. This enables developers to maintain centralized sandbox policies across multiple repositories without duplicating configuration into every project's .gemini folder.

Details

<!-- Add any extra context and design decisions. Keep it brief but complete. -->

Updated the sandbox utility to check if the SEATBELT_PROFILE value is an absolute path.

  • If absolute: Uses the path directly.
  • If relative/name: Continues with existing logic (checking built-in profiles or the project .gemini folder).

This change is non-breaking and preserves all existing workflows.

Related Issues

<!-- Use keywords to auto-close issues (Closes #123, Fixes #456). If this PR is only related to an issue or is a partial fix, simply reference the issue number without a keyword (Related to #123). -->

Closes #24991

How to Validate

GEMINI_SANDBOX=sandbox-exec SEATBELT_PROFILE=$(pwd)/bundle/sandbox-macos-permissive-open.sb node bundle/gemini.js -s

Pre-Merge Checklist

<!-- Check all that apply before requesting review or merging. -->
  • 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
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

Changed files

  • packages/cli/src/utils/sandbox.test.ts (modified, +33/-0)
  • packages/cli/src/utils/sandbox.ts (modified, +4/-2)

PR #25427: feat(sandbox): resolve custom seatbelt profiles from $HOME/.gemini first

Description (problem / solution / changelog)

Summary

Custom (non-builtin) SEATBELT_PROFILE values now resolve from $HOME/.gemini/sandbox-macos-${profile}.sb first, falling back to the existing project-level .gemini/sandbox-macos-${profile}.sb. This lets a user keep one custom profile that works across every workspace, which is what was requested in #24991.

Details

The previous resolution path (in packages/cli/src/utils/sandbox.ts:67-79) did:

  1. Bundled URL for builtin profile names in BUILTIN_SEATBELT_PROFILES
  2. path.join(GEMINI_DIR, 'sandbox-macos-${profile}.sb') for everything else - i.e. only the project's .gemini/

The change keeps step 1 unchanged. For non-builtin profiles, it now checks path.join(homedir(), GEMINI_DIR, fileName) and uses that file when it exists, otherwise falls back to the project-level path. The same FatalSandboxError is thrown if neither location has the file.

This matches the approach proposed in #24991 (comment) by @scidomino:

It would be better to change the code to search the home .gemini folder first before searching the workspace .gemini. That way, you could put a custom profile in one place and have it work with all your workspaces.

@flexponsive (the issue author) confirmed this would solve the problem. Two prior PRs (#25013, #25024) implemented the alternative SEATBELT_PROFILE-as-absolute-path approach and were closed with "we don't want to impl it this way" - so this PR deliberately takes the maintainer-directed path.

homedir and GEMINI_DIR are already imported from @google/gemini-cli-core in this file, mirroring the user-level .gemini lookups elsewhere (e.g. packages/core/src/services/fileKeychain.ts:19, packages/cli/src/config/trustedFolders.ts:30).

Related Issues

Fixes #24991

How to Validate

  1. npm run build --workspace @google/gemini-cli-core && npm run build --workspace @google/gemini-cli-test-utils
  2. npx vitest run packages/cli/src/utils/sandbox.test.ts - 18 tests pass, including two new tests:
    • should resolve custom seatbelt profile from user home directory
    • should fall back to project .gemini directory when user profile is missing
  3. npx prettier --check packages/cli/src/utils/sandbox.ts packages/cli/src/utils/sandbox.test.ts - clean
  4. npx eslint packages/cli/src/utils/sandbox.ts packages/cli/src/utils/sandbox.test.ts - no errors
  5. npm run typecheck --workspace @google/gemini-cli - passes

Manual smoke (macOS):

mkdir -p ~/.gemini
cp /path/to/your/profile.sb ~/.gemini/sandbox-macos-myprofile.sb
SEATBELT_PROFILE=myprofile gemini   # uses ~/.gemini profile

Run from any other workspace and the same profile resolves.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed) - behavior is additive; no doc changes required, but happy to add a note in docs/cli/sandbox.md if you'd prefer.
  • Added/updated tests (if needed)
  • Noted breaking changes (if any) - none; project-local profiles still work, builtin resolution unchanged.
  • Validated on required platforms/methods:
    • MacOS
      • npm run (vitest)
      • npx
      • Docker
      • Podman
      • Seatbelt (the code path under change)
    • Windows (not applicable - macOS-only code path)
    • Linux (not applicable - macOS-only code path)

This contribution was developed with AI assistance (Codex).

Changed files

  • packages/cli/src/utils/sandbox.test.ts (modified, +106/-1)
  • packages/cli/src/utils/sandbox.ts (modified, +10/-2)
RAW_BUFFERClick to expand / collapse

What would you like to be added?

Update the sandbox utility to check if the value of SEATBELT_PROFILE is an absolute path. If it is, the CLI should use that path directly when spawning sandbox-exec.

Why is this needed?

Currently, the SEATBELT_PROFILE environment variable on macOS only supports built-in profiles or custom profile names that correspond to a file named sandbox-macos-<profile>.sb located in the project's .gemini/ directory.

Users cannot currently provide a direct absolute path to a custom seatbelt profile file located elsewhere on their system. This makes it cumbersome to share sandbox configurations between different projects.

Additional context

No response

extent analysis

TL;DR

Update the sandbox utility to parse the SEATBELT_PROFILE environment variable to check if it contains an absolute path, and use that path directly when spawning sandbox-exec.

Guidance

  • Check the current implementation of the sandbox utility to identify where the SEATBELT_PROFILE environment variable is being processed and used to spawn sandbox-exec.
  • Modify the code to check if the value of SEATBELT_PROFILE is an absolute path using a suitable method (e.g., Path.isAbsolute() in Java or os.path.isabs() in Python).
  • If the value is an absolute path, use it directly when spawning sandbox-exec; otherwise, fall back to the current behavior of looking for a custom profile name in the project's .gemini/ directory.
  • Verify the updated functionality by setting SEATBELT_PROFILE to both absolute paths and custom profile names, and checking that the sandbox utility behaves as expected in each case.

Example

import os

# ...

if os.path.isabs(os.environ.get('SEATBELT_PROFILE')):
    # Use the absolute path directly
    profile_path = os.environ['SEATBELT_PROFILE']
else:
    # Fall back to the current behavior
    profile_path = os.path.join('.gemini', f'sandbox-macos-{os.environ["SEATBELT_PROFILE"]}.sb')

# Spawn sandbox-exec with the determined profile path

Notes

This solution assumes that the programming language and libraries used by the sandbox utility provide a way to check if a path is absolute. The example code snippet is in Python, but the actual implementation will depend on the language and libraries used.

Recommendation

Apply workaround: Update the sandbox utility to check for absolute paths in the SEATBELT_PROFILE environment variable, as this will provide the desired functionality without requiring any external changes.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING