fix(scripts): check-permissions.py does not flag allow rules for secrets read/delete #57

Closed
opened 2026-08-11 22:51:14 +03:00 by slaid098 · 0 comments
Owner

Контекст

Линтер check-permissions.py проверяет permission-правила в .opencode/opencode.json и агентах: флагает allow для паттернов из DANGEROUS_PATTERNS (деструктивные команды, git clone, ssh-удаления и т.п.). Обнаружено во время работы над PR #55 (issue #54/#56): после ослабления линтера для docker/force-push паттернов проверялось, что линтер продолжается ловить реальные угрозы. Тест показал, что allow для rm .env* и cat .env* НЕ флагаются линтером, хотя это прямая дыра — агент может читать или удалять файлы секретов без ask/deny.

Задача

Расширить DANGEROUS_PATTERNS в .opencode/scripts/check-permissions.py так, чтобы allow для паттернов чтения/удаления секретных файлов флагался как нарушение. Конкретно нужно ловить (неполный список — см. «Граничные случаи» для полного охвата):

  • rm .env* (удаление секретов)
  • cat .env* (чтение секретов через cat)
  • аналоги с git -C * префиксом если применимо

Контракты

  • Линтер остаётся read-only утилитой: python3 .opencode/scripts/check-permissions.py exit 0 если нарушений нет, exit 1 если есть.
  • DANGEROUS_PATTERNS — список кортежей (regex, reason, [scope]); scope опционален ("agent" / "all"), если отсутствует — "all".
  • Новые паттерны попадают в проверку check_rules() автоматически — менять функцию не нужно, только список.
  • Существующие deny для .env*/id_ed25519/id_rsa/*.pem/*secrets* в opencode.json НЕ флагаются (проверяется только action != "allow").

Инварианты

  • Нельзя ломать существующее поведение: 5 паттернов разрешённых в PR #55 (docker rm *, docker system prune*, docker volume rm *, git push --force*, git push -f*) продолжают НЕ флагаться.
  • Линтер продолжает ловить: rm -rf, git clone, ssh * rm/reboot, git clean, sudo, docker rmi, docker network rm, git push --delete*.
  • JSON opencode.json остаётся валидным после правки скрипта (скрипт меняется, конфиг — нет).

Граничные случаи

  • cat .env* vs cat .env.production — glob должен покрывать оба.
  • rm .env* vs rm -f .env vs rm -rf .env — нужно ли ловить все варианты rm секретов, или достаточно rm .env*? Решить при имплементации.
  • head .env* / tail .env* / less .env* / more .env* / grep * .env* — другие способы чтения секретов. Решить, включать ли все или только cat.
  • cp .env* * / mv .env* * — копирование/перемещение секретов.
  • ssh * cat .env* / ssh * rm .env* — секреты на удалённых хостах (уже частично покрывается ssh * rm * для rm, но не для cat).
  • git -C * rm .env* — удаление секретов через git.
  • docker exec * cat .env* / docker exec * rm .env* — секреты в контейнерах (но docker exec * rm * уже deny в конфиге, так что может не быть allow).
  • Паттерны с wildcard в середине: .env* уже покрывает .env, .env.local, .env.production.
  • Решение scope: секреты опасны везде (global + agents), поэтому scope "all" (по умолчанию, без третьего элемента).

Влияние на связанные компоненты

  • CI (ci.yml): линтер запускается в CI; после добавления паттернов, если в конфиге найдётся allow для секретов — CI упадёт. Нужно убедиться, что текущий конфиг НЕ содержит таких allow (предварительная проверка показала, что cat .env* / rm .env* отсутствуют в allow, но это надо перепроверить при имплементации).
  • PR #55: после merge, если этот issue ещё открыт — конфликтов не будет (правки в одном файле, но разные строки).
  • Агенты: если у какого-то агента в frontmatter есть allow для секретов — CI начнёт падать. Нужно проверить всех агентов в .opencode/agents/*.md.

Вне scope

  • Не добавлять флаги для npm install/pip install и т.п. — это уже в DANGEROUS_PATTERNS.
  • Не рефакторить структуру DANGEROUS_PATTERNS (например, не выносить в отдельный конфиг-файл) — только расширить список.
  • Не менять логику check_rules() / parse_agent_bash_rules() / parse_global_bash_rules().
  • Не трогать opencode.json permission-блок.

Критерии приемки

  • python3 .opencode/scripts/check-permissions.py exit 0 на текущем конфиге (после merge PR #55).
  • При добавлении тестового allow правила "cat .env*": "allow" в opencode.json (временно) — линтер флагает его как нарушение.
  • При добавлении тестового allow правила "rm .env*": "allow" — линтер флагает его.
  • Существующие deny правила для .env*/ключей НЕ флагаются.
  • JSON opencode.json остаётся валидным.
  • CI проходит (если в конфиге/агентах нет реальных allow для секретов).
## Контекст Линтер `check-permissions.py` проверяет permission-правила в `.opencode/opencode.json` и агентах: флагает `allow` для паттернов из `DANGEROUS_PATTERNS` (деструктивные команды, git clone, ssh-удаления и т.п.). Обнаружено во время работы над PR #55 (issue #54/#56): после ослабления линтера для docker/force-push паттернов проверялось, что линтер продолжается ловить реальные угрозы. Тест показал, что `allow` для `rm .env*` и `cat .env*` НЕ флагаются линтером, хотя это прямая дыра — агент может читать или удалять файлы секретов без `ask`/`deny`. ## Задача Расширить `DANGEROUS_PATTERNS` в `.opencode/scripts/check-permissions.py` так, чтобы `allow` для паттернов чтения/удаления секретных файлов флагался как нарушение. Конкретно нужно ловить (неполный список — см. «Граничные случаи» для полного охвата): - `rm .env*` (удаление секретов) - `cat .env*` (чтение секретов через cat) - аналоги с `git -C *` префиксом если применимо ## Контракты - Линтер остаётся read-only утилитой: `python3 .opencode/scripts/check-permissions.py` exit 0 если нарушений нет, exit 1 если есть. - `DANGEROUS_PATTERNS` — список кортежей `(regex, reason, [scope])`; `scope` опционален (`"agent"` / `"all"`), если отсутствует — `"all"`. - Новые паттерны попадают в проверку `check_rules()` автоматически — менять функцию не нужно, только список. - Существующие `deny` для `.env*`/`id_ed25519`/`id_rsa`/`*.pem`/`*secrets*` в `opencode.json` НЕ флагаются (проверяется только `action != "allow"`). ## Инварианты - Нельзя ломать существующее поведение: 5 паттернов разрешённых в PR #55 (`docker rm *`, `docker system prune*`, `docker volume rm *`, `git push --force*`, `git push -f*`) продолжают НЕ флагаться. - Линтер продолжает ловить: `rm -rf`, `git clone`, `ssh * rm/reboot`, `git clean`, `sudo`, `docker rmi`, `docker network rm`, `git push --delete*`. - JSON `opencode.json` остаётся валидным после правки скрипта (скрипт меняется, конфиг — нет). ## Граничные случаи - `cat .env*` vs `cat .env.production` — glob должен покрывать оба. - `rm .env*` vs `rm -f .env` vs `rm -rf .env` — нужно ли ловить все варианты `rm` секретов, или достаточно `rm .env*`? Решить при имплементации. - `head .env*` / `tail .env*` / `less .env*` / `more .env*` / `grep * .env*` — другие способы чтения секретов. Решить, включать ли все или только `cat`. - `cp .env* *` / `mv .env* *` — копирование/перемещение секретов. - `ssh * cat .env*` / `ssh * rm .env*` — секреты на удалённых хостах (уже частично покрывается `ssh * rm *` для rm, но не для cat). - `git -C * rm .env*` — удаление секретов через git. - `docker exec * cat .env*` / `docker exec * rm .env*` — секреты в контейнерах (но `docker exec * rm *` уже `deny` в конфиге, так что может не быть `allow`). - Паттерны с wildcard в середине: `.env*` уже покрывает `.env`, `.env.local`, `.env.production`. - Решение scope: секреты опасны везде (global + agents), поэтому scope `"all"` (по умолчанию, без третьего элемента). ## Влияние на связанные компоненты - **CI (`ci.yml`)**: линтер запускается в CI; после добавления паттернов, если в конфиге найдётся `allow` для секретов — CI упадёт. Нужно убедиться, что текущий конфиг НЕ содержит таких `allow` (предварительная проверка показала, что `cat .env*` / `rm .env*` отсутствуют в `allow`, но это надо перепроверить при имплементации). - **PR #55**: после merge, если этот issue ещё открыт — конфликтов не будет (правки в одном файле, но разные строки). - **Агенты**: если у какого-то агента в frontmatter есть `allow` для секретов — CI начнёт падать. Нужно проверить всех агентов в `.opencode/agents/*.md`. ## Вне scope - Не добавлять флаги для `npm install`/`pip install` и т.п. — это уже в `DANGEROUS_PATTERNS`. - Не рефакторить структуру `DANGEROUS_PATTERNS` (например, не выносить в отдельный конфиг-файл) — только расширить список. - Не менять логику `check_rules()` / `parse_agent_bash_rules()` / `parse_global_bash_rules()`. - Не трогать `opencode.json` permission-блок. ## Критерии приемки - `python3 .opencode/scripts/check-permissions.py` exit 0 на текущем конфиге (после merge PR #55). - При добавлении тестового `allow` правила `"cat .env*": "allow"` в `opencode.json` (временно) — линтер флагает его как нарушение. - При добавлении тестового `allow` правила `"rm .env*": "allow"` — линтер флагает его. - Существующие `deny` правила для `.env*`/ключей НЕ флагаются. - JSON `opencode.json` остаётся валидным. - CI проходит (если в конфиге/агентах нет реальных `allow` для секретов).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/opencode-config#57
No description provided.