Private /tmp, no display, git over SSH and netlock check fixes
- /tmp: the agent gets its own (<state>/tmp, files older than 7 days are removed on start) — the host's /tmp holds sockets that lead out of the sandbox (tmux, X11, browsers' singleton sockets, other tools). OCSB_TMP=shared keeps the old behaviour. /tmp is mounted before the project and state binds so they stay visible if they live under /tmp - DISPLAY, WAYLAND_DISPLAY, XAUTHORITY are empty in the sandbox and ~/.Xauthority is hidden; browsers must run headless - GIT_SSH_COMMAND uses -F ~/.ssh/config: in the user namespace root-owned system ssh configs look owned by nobody and ssh refuses them - netlock self-test checks that the proxy opens the tunnel, not that a remote site answers; failed self-tests now say so instead of exiting silently - doctor: no false error for opencode outside a project - skill and READMEs: worktrees only for code changes, private /tmp, headless browsers, troubleshooting entries
This commit is contained in:
@@ -124,6 +124,7 @@ files are read, so you can use it in values. Relative paths are relative to the
|
|||||||
| `OCSB_PLUGINS` | skill-compact-resurrect | plugin files from `plugins/` (or absolute paths) |
|
| `OCSB_PLUGINS` | skill-compact-resurrect | plugin files from `plugins/` (or absolute paths) |
|
||||||
| `OCSB_PANEL` | `1` | "Tokens" panel in the web UI |
|
| `OCSB_PANEL` | `1` | "Tokens" panel in the web UI |
|
||||||
| `OCSB_NOTIFICATIONS` | `1` | desktop notifications through a filtered D-Bus proxy |
|
| `OCSB_NOTIFICATIONS` | `1` | desktop notifications through a filtered D-Bus proxy |
|
||||||
|
| `OCSB_TMP` | `private` | `private`: the agent's own `/tmp` in the state directory; `shared`: the host's `/tmp` |
|
||||||
| `OCSB_SANDBOX` | `1` | `0` = filter and netlock only, no bubblewrap |
|
| `OCSB_SANDBOX` | `1` | `0` = filter and netlock only, no bubblewrap |
|
||||||
| `OCSB_WORKTREES_DIR` | `../<project>-worktrees` | where worktrees go |
|
| `OCSB_WORKTREES_DIR` | `../<project>-worktrees` | where worktrees go |
|
||||||
| `OCSB_WT_PREFIX` | — | worktree directory = `<prefix><slug>` |
|
| `OCSB_WT_PREFIX` | — | worktree directory = `<prefix><slug>` |
|
||||||
@@ -226,7 +227,11 @@ browser → :4196 (context panel inside OpenCode) → :4197
|
|||||||
Inside the sandbox:
|
Inside the sandbox:
|
||||||
|
|
||||||
- **Writable:** the project, the worktrees directory, the state directory, `OCSB_RW`,
|
- **Writable:** the project, the worktrees directory, the state directory, `OCSB_RW`,
|
||||||
`OCSB_RW_HOME`, `/tmp`. Everything else is read-only.
|
`OCSB_RW_HOME` and a private `/tmp`. Everything else is read-only.
|
||||||
|
- **Private `/tmp`:** the host's `/tmp` holds sockets that lead out of a sandbox (tmux, X11,
|
||||||
|
browsers' singleton sockets, other tools), so the agent gets its own, stored in
|
||||||
|
`<state>/tmp` (files older than 7 days are removed on start). Look there for its screenshots
|
||||||
|
and logs. Docker mounts of `/tmp` paths would point at the host's `/tmp` — mount project paths.
|
||||||
- **Hidden:** `OCSB_HIDE_HOME`, `OCSB_HIDE`, private keys in `~/.ssh` (`config`, `known_hosts`
|
- **Hidden:** `OCSB_HIDE_HOME`, `OCSB_HIDE`, private keys in `~/.ssh` (`config`, `known_hosts`
|
||||||
and `*.pub` stay visible; the host's ssh-agent signs).
|
and `*.pub` stay visible; the host's ssh-agent signs).
|
||||||
- **Network:** `HTTP(S)_PROXY` point to the filter. `GIT_SSH_COMMAND` sends ssh through it with
|
- **Network:** `HTTP(S)_PROXY` point to the filter. `GIT_SSH_COMMAND` sends ssh through it with
|
||||||
@@ -238,8 +243,9 @@ Inside the sandbox:
|
|||||||
- **Session bus:** replaced by `xdg-dbus-proxy` that talks only to
|
- **Session bus:** replaced by `xdg-dbus-proxy` that talks only to
|
||||||
`org.freedesktop.Notifications`; the real bus would let the agent start processes outside
|
`org.freedesktop.Notifications`; the real bus would let the agent start processes outside
|
||||||
the sandbox with `systemd-run --user`.
|
the sandbox with `systemd-run --user`.
|
||||||
- **Browser:** `xdg-open` is disabled for the agent; the UI is opened by `run` from your
|
- **No display:** `DISPLAY`, `WAYLAND_DISPLAY` and `XAUTHORITY` are empty and the X cookie is
|
||||||
normal session.
|
hidden, so GUI programs cannot reach your desktop; run browsers (Playwright MCP, Chrome)
|
||||||
|
headless. `xdg-open` is disabled; the UI is opened by `run` from your normal session.
|
||||||
- **No silent fallback:** with `OCSB_SANDBOX=1` and no working bubblewrap, `run` refuses to
|
- **No silent fallback:** with `OCSB_SANDBOX=1` and no working bubblewrap, `run` refuses to
|
||||||
start.
|
start.
|
||||||
|
|
||||||
@@ -260,7 +266,7 @@ place, requests to production — not to hold a determined attacker.
|
|||||||
- **Allowed hosts are a channel.** Data can leave through any host the rules allow.
|
- **Allowed hosts are a channel.** Data can leave through any host the rules allow.
|
||||||
- **The project is writable.** Mistakes inside it are real; cc-safety-net blocks the common
|
- **The project is writable.** Mistakes inside it are real; cc-safety-net blocks the common
|
||||||
destructive commands, git keeps history — commit often.
|
destructive commands, git keeps history — commit often.
|
||||||
- `/tmp` is shared with the host.
|
- With `OCSB_TMP=shared` the host's `/tmp` and its sockets are reachable.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
@@ -275,6 +281,8 @@ place, requests to production — not to hold a determined attacker.
|
|||||||
| `bubblewrap cannot create a sandbox` | unprivileged user namespaces are disabled (`kernel.unprivileged_userns_clone`, AppArmor userns restrictions) |
|
| `bubblewrap cannot create a sandbox` | unprivileged user namespaces are disabled (`kernel.unprivileged_userns_clone`, AppArmor userns restrictions) |
|
||||||
| no "Tokens" panel | open port 4196, not 4197; see `<state>/data/opencode/log/context-panel.log` |
|
| no "Tokens" panel | open port 4196, not 4197; see `<state>/data/opencode/log/context-panel.log` |
|
||||||
| no notifications | install `xdg-dbus-proxy` |
|
| no notifications | install `xdg-dbus-proxy` |
|
||||||
|
| browser tools fail (`Missing X server`, `Failed to connect to Wayland display`) | no display in the sandbox: run the browser headless (Playwright MCP: `--headless`) |
|
||||||
|
| can't find a file the agent put in `/tmp` | it is in `~/.local/share/opencode-sandbox/<name>/tmp` |
|
||||||
| `docker build` fails pulling images | the proxy reaches registries through squid: check `egress logs` |
|
| `docker build` fails pulling images | the proxy reaches registries through squid: check `egress logs` |
|
||||||
|
|
||||||
## Uninstall
|
## Uninstall
|
||||||
|
|||||||
+13
-4
@@ -123,6 +123,7 @@ squid.conf.
|
|||||||
| `OCSB_PLUGINS` | skill-compact-resurrect | файлы плагинов из `plugins/` (или абсолютные пути) |
|
| `OCSB_PLUGINS` | skill-compact-resurrect | файлы плагинов из `plugins/` (или абсолютные пути) |
|
||||||
| `OCSB_PANEL` | `1` | панель «Токены» в веб-интерфейсе |
|
| `OCSB_PANEL` | `1` | панель «Токены» в веб-интерфейсе |
|
||||||
| `OCSB_NOTIFICATIONS` | `1` | уведомления через фильтрующий прокси D-Bus |
|
| `OCSB_NOTIFICATIONS` | `1` | уведомления через фильтрующий прокси D-Bus |
|
||||||
|
| `OCSB_TMP` | `private` | `private` — свой `/tmp` агента в каталоге состояния; `shared` — `/tmp` хоста |
|
||||||
| `OCSB_SANDBOX` | `1` | `0` — только фильтр и netlock, без bubblewrap |
|
| `OCSB_SANDBOX` | `1` | `0` — только фильтр и netlock, без bubblewrap |
|
||||||
| `OCSB_WORKTREES_DIR` | `../<проект>-worktrees` | куда класть worktree |
|
| `OCSB_WORKTREES_DIR` | `../<проект>-worktrees` | куда класть worktree |
|
||||||
| `OCSB_WT_PREFIX` | — | каталог дерева = `<префикс><slug>` |
|
| `OCSB_WT_PREFIX` | — | каталог дерева = `<префикс><slug>` |
|
||||||
@@ -225,8 +226,12 @@ opencode-sandbox run
|
|||||||
|
|
||||||
Внутри песочницы:
|
Внутри песочницы:
|
||||||
|
|
||||||
- **На запись:** проект, каталог worktree, каталог состояния, `OCSB_RW`, `OCSB_RW_HOME`,
|
- **На запись:** проект, каталог worktree, каталог состояния, `OCSB_RW`, `OCSB_RW_HOME` и
|
||||||
`/tmp`. Всё остальное — только чтение.
|
собственный `/tmp`. Всё остальное — только чтение.
|
||||||
|
- **Свой `/tmp`:** в `/tmp` хоста лежат сокеты, через которые можно выйти из песочницы
|
||||||
|
(tmux, X11, сокеты браузеров, других программ), поэтому у агента свой `/tmp` — в
|
||||||
|
`<состояние>/tmp` (файлы старше 7 дней удаляются при запуске). Скриншоты и логи агента ищите
|
||||||
|
там. Docker смонтирует путь из `/tmp` из `/tmp` хоста — монтируйте пути проекта.
|
||||||
- **Скрыто:** `OCSB_HIDE_HOME`, `OCSB_HIDE`, приватные ключи в `~/.ssh` (`config`,
|
- **Скрыто:** `OCSB_HIDE_HOME`, `OCSB_HIDE`, приватные ключи в `~/.ssh` (`config`,
|
||||||
`known_hosts` и `*.pub` видны; подписывает ssh-agent хоста).
|
`known_hosts` и `*.pub` видны; подписывает ssh-agent хоста).
|
||||||
- **Сеть:** `HTTP(S)_PROXY` указывают на фильтр. `GIT_SSH_COMMAND` пускает ssh через него
|
- **Сеть:** `HTTP(S)_PROXY` указывают на фильтр. `GIT_SSH_COMMAND` пускает ssh через него
|
||||||
@@ -239,7 +244,9 @@ opencode-sandbox run
|
|||||||
- **Сессионная шина:** заменена на `xdg-dbus-proxy`, который пропускает только
|
- **Сессионная шина:** заменена на `xdg-dbus-proxy`, который пропускает только
|
||||||
`org.freedesktop.Notifications`; настоящая шина позволила бы агенту запускать процессы вне
|
`org.freedesktop.Notifications`; настоящая шина позволила бы агенту запускать процессы вне
|
||||||
песочницы через `systemd-run --user`.
|
песочницы через `systemd-run --user`.
|
||||||
- **Браузер:** `xdg-open` агенту отключён; интерфейс открывает `run` из вашей обычной сессии.
|
- **Нет экрана:** `DISPLAY`, `WAYLAND_DISPLAY` и `XAUTHORITY` пустые, cookie X скрыт — графические
|
||||||
|
программы до вашего рабочего стола не доберутся; браузеры (Playwright MCP, Chrome) — только
|
||||||
|
headless. `xdg-open` отключён; интерфейс открывает `run` из вашей обычной сессии.
|
||||||
- **Без тихого отката:** при `OCSB_SANDBOX=1` и неработающем bubblewrap `run` не запустится.
|
- **Без тихого отката:** при `OCSB_SANDBOX=1` и неработающем bubblewrap `run` не запустится.
|
||||||
|
|
||||||
**Netlock** (`netlock setup`, sudo) создаёт группу `opencode-sandbox`, добавляет в неё вас и
|
**Netlock** (`netlock setup`, sudo) создаёт группу `opencode-sandbox`, добавляет в неё вас и
|
||||||
@@ -260,7 +267,7 @@ opencode-sandbox run
|
|||||||
правила.
|
правила.
|
||||||
- **Проект доступен на запись.** Ошибки внутри него настоящие; cc-safety-net блокирует
|
- **Проект доступен на запись.** Ошибки внутри него настоящие; cc-safety-net блокирует
|
||||||
типичные разрушительные команды, git хранит историю — коммитьте чаще.
|
типичные разрушительные команды, git хранит историю — коммитьте чаще.
|
||||||
- `/tmp` общий с хостом.
|
- С `OCSB_TMP=shared` доступны `/tmp` хоста и его сокеты.
|
||||||
|
|
||||||
## Решение проблем
|
## Решение проблем
|
||||||
|
|
||||||
@@ -275,6 +282,8 @@ opencode-sandbox run
|
|||||||
| `bubblewrap cannot create a sandbox` | отключены непривилегированные user namespaces (`kernel.unprivileged_userns_clone`, ограничения AppArmor) |
|
| `bubblewrap cannot create a sandbox` | отключены непривилегированные user namespaces (`kernel.unprivileged_userns_clone`, ограничения AppArmor) |
|
||||||
| нет панели «Токены» | открывайте порт 4196, а не 4197; журнал — `<состояние>/data/opencode/log/context-panel.log` |
|
| нет панели «Токены» | открывайте порт 4196, а не 4197; журнал — `<состояние>/data/opencode/log/context-panel.log` |
|
||||||
| нет уведомлений | установите `xdg-dbus-proxy` |
|
| нет уведомлений | установите `xdg-dbus-proxy` |
|
||||||
|
| браузерные инструменты падают (`Missing X server`, `Failed to connect to Wayland display`) | в песочнице нет экрана: запускайте браузер headless (Playwright MCP: `--headless`) |
|
||||||
|
| не найти файл, который агент положил в `/tmp` | он в `~/.local/share/opencode-sandbox/<имя>/tmp` |
|
||||||
| `docker build` не скачивает образы | реестры доступны через squid: смотрите `egress logs` |
|
| `docker build` не скачивает образы | реестры доступны через squid: смотрите `egress logs` |
|
||||||
|
|
||||||
## Удаление
|
## Удаление
|
||||||
|
|||||||
+3
-2
@@ -19,7 +19,7 @@ ocsb_info() { echo "→ $*"; }
|
|||||||
|
|
||||||
OCSB_SCALARS=(
|
OCSB_SCALARS=(
|
||||||
OCSB_NAME OCSB_WEB_PORT OCSB_EGRESS_PORT OCSB_NETLOCK_GROUP OCSB_SANDBOX OCSB_PANEL
|
OCSB_NAME OCSB_WEB_PORT OCSB_EGRESS_PORT OCSB_NETLOCK_GROUP OCSB_SANDBOX OCSB_PANEL
|
||||||
OCSB_NOTIFICATIONS OCSB_OPENCODE_BIN OCSB_ENV_FILE OCSB_KUBECONFIG OCSB_PASSWORD_FILE
|
OCSB_NOTIFICATIONS OCSB_TMP OCSB_OPENCODE_BIN OCSB_ENV_FILE OCSB_KUBECONFIG OCSB_PASSWORD_FILE
|
||||||
OCSB_WORKTREES_DIR OCSB_WT_PREFIX OCSB_WT_BASE OCSB_WT_SLUG_REGEX OCSB_DOCKER_GW
|
OCSB_WORKTREES_DIR OCSB_WT_PREFIX OCSB_WT_BASE OCSB_WT_SLUG_REGEX OCSB_DOCKER_GW
|
||||||
OCSB_STATE_DIR OCSB_OPENCODE_CONFIG OCSB_EGRESS_BASE
|
OCSB_STATE_DIR OCSB_OPENCODE_CONFIG OCSB_EGRESS_BASE
|
||||||
)
|
)
|
||||||
@@ -33,6 +33,7 @@ ocsb_defaults() {
|
|||||||
OCSB_SANDBOX=1 # bubblewrap; 0 = egress filter and netlock only
|
OCSB_SANDBOX=1 # bubblewrap; 0 = egress filter and netlock only
|
||||||
OCSB_PANEL=1 # "Tokens" panel in the web UI (plugins/context-panel)
|
OCSB_PANEL=1 # "Tokens" panel in the web UI (plugins/context-panel)
|
||||||
OCSB_NOTIFICATIONS=1 # desktop notifications through a filtered D-Bus proxy
|
OCSB_NOTIFICATIONS=1 # desktop notifications through a filtered D-Bus proxy
|
||||||
|
OCSB_TMP=private # private: own /tmp in the state dir; shared: the host's /tmp
|
||||||
OCSB_OPENCODE_BIN="" # default: `opencode` from PATH
|
OCSB_OPENCODE_BIN="" # default: `opencode` from PATH
|
||||||
OCSB_ENV_FILE="" # KEY=VALUE file with tokens, exported to OpenCode
|
OCSB_ENV_FILE="" # KEY=VALUE file with tokens, exported to OpenCode
|
||||||
OCSB_KUBECONFIG="" # kubeconfig for the agent (~/.kube/config stays hidden)
|
OCSB_KUBECONFIG="" # kubeconfig for the agent (~/.kube/config stays hidden)
|
||||||
@@ -53,7 +54,7 @@ ocsb_defaults() {
|
|||||||
OCSB_HIDE_HOME=(.gnupg .aws .azure .config/gcloud .kube/config .docker/config.json .netrc
|
OCSB_HIDE_HOME=(.gnupg .aws .azure .config/gcloud .kube/config .docker/config.json .netrc
|
||||||
.git-credentials .config/gh/hosts.yml .password-store .local/share/keyrings .mozilla
|
.git-credentials .config/gh/hosts.yml .password-store .local/share/keyrings .mozilla
|
||||||
.config/google-chrome .config/chromium .config/BraveSoftware .claude .codex
|
.config/google-chrome .config/chromium .config/BraveSoftware .claude .codex
|
||||||
.config/opencode .local/share/opencode)
|
.config/opencode .local/share/opencode .Xauthority)
|
||||||
OCSB_SKILLS=(opencode-sandbox) # skills mounted for the agent (names of skill directories)
|
OCSB_SKILLS=(opencode-sandbox) # skills mounted for the agent (names of skill directories)
|
||||||
OCSB_SKILL_DIRS=() # extra directories to look for skills in
|
OCSB_SKILL_DIRS=() # extra directories to look for skills in
|
||||||
OCSB_PLUGINS=(skill-compact-resurrect/skill-compact-resurrect.v2.ts) # files in plugins/
|
OCSB_PLUGINS=(skill-compact-resurrect/skill-compact-resurrect.v2.ts) # files in plugins/
|
||||||
|
|||||||
+16
-2
@@ -124,11 +124,23 @@ ocsb_bwrap_args() {
|
|||||||
OCSB_BWRAP=(
|
OCSB_BWRAP=(
|
||||||
--die-with-parent --new-session --unshare-pid --unshare-ipc --unshare-uts
|
--die-with-parent --new-session --unshare-pid --unshare-ipc --unshare-uts
|
||||||
--ro-bind / / --dev /dev --proc /proc
|
--ro-bind / / --dev /dev --proc /proc
|
||||||
--bind /tmp /tmp
|
--tmpfs "/run/user/${uid}"
|
||||||
|
)
|
||||||
|
# /tmp: the host's holds sockets that lead out of the sandbox (tmux, X11, browsers,
|
||||||
|
# other agents) — by default the agent gets its own, kept in the state directory.
|
||||||
|
# Mounted before the project and the state, so they stay visible if they live under /tmp
|
||||||
|
if [[ ${OCSB_TMP} == shared ]]; then
|
||||||
|
OCSB_BWRAP+=(--bind /tmp /tmp)
|
||||||
|
else
|
||||||
|
mkdir -p "${OCSB_STATE_DIR}/tmp"
|
||||||
|
chmod 700 "${OCSB_STATE_DIR}/tmp"
|
||||||
|
find "${OCSB_STATE_DIR}/tmp" -mindepth 1 -mtime +7 -delete 2>/dev/null || true
|
||||||
|
OCSB_BWRAP+=(--bind "${OCSB_STATE_DIR}/tmp" /tmp)
|
||||||
|
fi
|
||||||
|
OCSB_BWRAP+=(
|
||||||
--bind "${OCSB_PROJECT_DIR}" "${OCSB_PROJECT_DIR}"
|
--bind "${OCSB_PROJECT_DIR}" "${OCSB_PROJECT_DIR}"
|
||||||
--bind "${OCSB_WORKTREES_DIR}" "${OCSB_WORKTREES_DIR}"
|
--bind "${OCSB_WORKTREES_DIR}" "${OCSB_WORKTREES_DIR}"
|
||||||
--bind "${OCSB_STATE_DIR}" "${OCSB_STATE_DIR}"
|
--bind "${OCSB_STATE_DIR}" "${OCSB_STATE_DIR}"
|
||||||
--tmpfs "/run/user/${uid}"
|
|
||||||
)
|
)
|
||||||
for p in "${OCSB_RW[@]}"; do
|
for p in "${OCSB_RW[@]}"; do
|
||||||
p=$(ocsb_abs "${p}")
|
p=$(ocsb_abs "${p}")
|
||||||
@@ -243,6 +255,8 @@ ocsb_run() {
|
|||||||
# No permission prompts in the sandbox: permission rules from all configs form one
|
# No permission prompts in the sandbox: permission rules from all configs form one
|
||||||
# list, the last match wins, and OPENCODE_CONFIG_CONTENT is the last document.
|
# list, the last match wins, and OPENCODE_CONFIG_CONTENT is the last document.
|
||||||
# Denies are repeated after "*" so they still win.
|
# Denies are repeated after "*" so they still win.
|
||||||
|
# No display: GUI programs fail fast; browsers must run headless
|
||||||
|
env+=("DISPLAY=" "WAYLAND_DISPLAY=" "XAUTHORITY=")
|
||||||
env+=('OPENCODE_CONFIG_CONTENT={"permission":{"bash":{"*":"allow","systemd-run *":"deny","sudo *":"deny"},"external_directory":{"*":"allow"}}}')
|
env+=('OPENCODE_CONFIG_CONTENT={"permission":{"bash":{"*":"allow","systemd-run *":"deny","sudo *":"deny"},"external_directory":{"*":"allow"}}}')
|
||||||
echo " sandbox: writable ${OCSB_PROJECT_DIR}, ${OCSB_WORKTREES_DIR}${OCSB_RW[*]:+, ${OCSB_RW[*]}}; the rest of the system is read-only"
|
echo " sandbox: writable ${OCSB_PROJECT_DIR}, ${OCSB_WORKTREES_DIR}${OCSB_RW[*]:+, ${OCSB_RW[*]}}; the rest of the system is read-only"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ sandbox is on.
|
|||||||
|---|---|
|
|---|---|
|
||||||
| The project, its worktrees directory, paths from `OCSB_RW` in `.opencode-sandbox/sandbox.conf` | read-write, real disk |
|
| The project, its worktrees directory, paths from `OCSB_RW` in `.opencode-sandbox/sandbox.conf` | read-write, real disk |
|
||||||
| Toolchain caches in `~` (`.cache`, `.npm`, `.asdf`, `.bundle`, `.gem`, …) | read-write |
|
| Toolchain caches in `~` (`.cache`, `.npm`, `.asdf`, `.bundle`, `.gem`, …) | read-write |
|
||||||
| `/tmp` | read-write, shared with the host |
|
| `/tmp` | read-write, **private** to the sandbox (on the host it is `<state>/tmp`; files older than 7 days are cleaned) |
|
||||||
| Everything else | read-only |
|
| Everything else | read-only |
|
||||||
| Private SSH keys, `~/.gnupg`, cloud CLI credentials, `~/.kube/config`, browser profiles, other agents' configs, `OCSB_HIDE` paths | hidden (empty) |
|
| Private SSH keys, `~/.gnupg`, cloud CLI credentials, `~/.kube/config`, browser profiles, other agents' configs, `OCSB_HIDE` paths | hidden (empty) |
|
||||||
|
|
||||||
@@ -39,6 +39,7 @@ sandbox is on.
|
|||||||
## Things you cannot do
|
## Things you cannot do
|
||||||
|
|
||||||
- Open a browser (`xdg-open` is disabled): print the link for the user.
|
- Open a browser (`xdg-open` is disabled): print the link for the user.
|
||||||
|
- Run GUI programs: there is no display. Browsers (Playwright, Chrome) must run headless.
|
||||||
- `sudo`, `systemd-run`: denied.
|
- `sudo`, `systemd-run`: denied.
|
||||||
- Start processes outside the sandbox through the session bus: only desktop notifications
|
- Start processes outside the sandbox through the session bus: only desktop notifications
|
||||||
are reachable.
|
are reachable.
|
||||||
@@ -46,7 +47,8 @@ sandbox is on.
|
|||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
The Docker socket is available, so Docker can see the whole host. Mount only paths inside
|
The Docker socket is available, so Docker can see the whole host. Mount only paths inside
|
||||||
the project or its worktrees; never mount `/`, `~` or system directories.
|
the project or its worktrees; never mount `/`, `~` or system directories. Do not mount `/tmp`
|
||||||
|
paths: the Docker daemon sees the host's `/tmp`, not your private one.
|
||||||
|
|
||||||
## Worktrees
|
## Worktrees
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user