google-gemini / google-gemini/gemini-cli

security(sandbox): macOS Seatbelt container-runtime isolation misses Podman API sockets (~/.local/share/containers/podman.sock, ~/.podman)

Open Beginner friendly
#28,999 1 comment 0 reactions 0 assignees View on GitHub
area/security status/need-triage
Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 3h
Merged PRs (30d)
45

Description

### What happened?

The macOS Seatbelt sandbox profiles added/extended in #28935 deny access to container-runtime daemon sockets and binaries to prevent sandbox escape via privileged containers mounting the host filesystem (VirtioFS etc.). The deny lists cover Docker Desktop, Colima, OrbStack, and Rancher Desktop (`~/.docker/run`, `~/.colima`, `~/.orbstack/run`, `~/.rd`), and they also deny the **Podman CLI binaries** — but they do **not** deny Podman's API socket paths.

Podman is a first-class sandbox backend in this repo (`packages/cli/src/config/sandboxConfig.ts` auto-detects it, and `packages/cli/src/utils/sandbox.ts` explicitly supports rootless podman on macOS), so a host with Podman installed is an expected configuration.

On macOS, rootless Podman exposes its REST API socket at a user-writable path, by default:

- `$XDG_DATA_HOME/containers/podman.sock` → typically `$HOME/.local/share/containers/podman.sock`
- legacy/alternative locations such as `$HOME/.podman/podman.sock`

None of these appear in any `(deny file-read* file-write* ...)` list in `BUILTIN_SEATBELT_PROFILE_CONTENTS`. Because all four built-in profiles include blanket `(allow file-read*)` (and `permissive-*` even allow broad network-outbound), a process running inside the Seatbelt sandbox can connect directly to the Podman API socket and issue requests equivalent to what the Docker-socket denial was designed to prevent — e.g. creating a privileged container that bind-mounts the host filesystem — bypassing the sandbox boundary that #28935 established for every other container runtime.

Repro sketch (macOS host with `podman machine start` running, gemini-cli sandboxed via `sandbox-exec`):

```bash
# inside a tool-spawned shell within the sandbox:
curl --unix-socket "$HOME/.local/share/containers/podman.sock" \
-X POST http://d/v4.0.0/containers/create \
-d '{"image":"alpine","HostConfig":{"Privileged":true,"Binds":["/:/host"]}}'
```

This succeeds under the current built-in profiles, while the analogous request against `/var/run/docker.sock` is denied.

### What did you expect to happen?

The container-runtime isolation added in #28935 should cover Podman symmetrically:

1. Add Podman socket paths to the file-deny rules in all built-in profiles, e.g.
- `(subpath (string-append (param "HOME_DIR") "/.local/share/containers"))`
- `(subpath (string-append (param "HOME_DIR") "/.podman"))`
- and consider honoring `XDG_DATA_HOME` overrides if the profile templating allows it.
2. Extend the unit tests in `packages/cli/src/utils/sandbox-macos-profiles.test.ts` to assert these denials across all profiles, matching the existing Docker assertions (e.g. the existing `'(literal "/opt/homebrew/bin/podman")'` check).

### Client information

Source-level finding verified against upstream `main` at commit `5411f113c` (v0.57.0-preview.0 era). Affects macOS hosts using the built-in Seatbelt profiles (`permissive-open`, `permissive-proxied`, `restrictive-open`, `restrictive-proxied`, `strict-*`, and their `-closed` aliases).

Platform: macOS (sandbox-exec / Seatbelt). Not applicable to Docker/Podman-container sandbox modes.

### Login information

Not applicable.

### Anything else we need to know?

Sources:

- `packages/cli/src/utils/sandboxBuiltinProfiles.ts` — the `(deny file-read* file-write* ...)` blocks enumerate `/var/run/docker.sock`, `~/.docker/run`, `~/.docker/desktop`, `~/.colima`, `~/.orbstack/run`, `~/.rd`, plus `(deny process-exec ...)` entries that include podman binaries (`/opt/homebrew/bin/podman`, `/usr/local/bin/podman`) — proving Podman was in scope, while its sockets were left out.
- `packages/cli/src/config/sandboxConfig.ts:101-116` — podman auto-detection as a supported sandbox command.
- `packages/cli/src/utils/sandbox.ts:560` — explicit rootless-podman-on-macOS support comment.
- PR #28935 — the isolation change whose stated goal ("prevent sandbox escape via container hypervisor filesystem mounts") this gap undermines.
- Searched existing issues for "podman seatbelt", "sandbox escape podman", "seatbelt docker socket" and open PRs for "podman socket"/"seatbelt" — no duplicates found.

Contributor guide

Open the contributing guide

Research direction

Start in packages/cli/src/utils/sandboxBuiltinProfiles.ts by comparing the existing container-runtime deny blocks, then inspect packages/cli/src/utils/sandbox-macos-profiles.test.ts and the existing Docker assertions. Update the profile coverage for the documented Podman socket locations and verify that the tests assert the denials across all built-in profiles.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, typescript
Domain
cli, operating-systems, security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.