Skip to content

Безопасность, приватность и устойчивость ​

English version: 04-security-resilience.md. Этот файл — русский дубликат; обновляется вместе с 04-security-resilience.md.

Что хранит Binnacle, кто может достучаться до его демона, где лежат его секреты и что продолжает работать, когда какой-то части нет. Как сообщить об уязвимости — в политике безопасности.

Что хранит telemetry ​

Telemetry — это только метаданные. Хранилище держит для каждого вызова или события:

  • harness, сессию и её субагентов, проект, рабочий каталог и ветку;
  • временные метки, provider и модель;
  • счётчики токенов и cache, с их происхождением, и null, где harness их не сообщает;
  • compaction, упоры в лимиты использования и собственные события демона.

Оно никогда не хранит промпты, ответы модели, содержимое исходных файлов, секреты или аргументы инструментов. В экспорте OpenTelemetry, который настраивает binn init, логирование промптов выключено. Диагностика на уровне содержимого, если её когда-нибудь добавят, должна включаться только явно.

Секреты ​

  • Никаких API-ключей в .binnacle/project.yaml: Binnacle никогда не читает секрет из манифеста и не пишет его туда.
  • Ключи живут в окружении, в хранилище секретов операционной системы или в собственной конфигурации upstream-клиента.
  • Никогда намеренно не экспортируйте секрет в Obsidian или Graphify.
  • binn audit пока не ищет закоммиченные секреты. Это добавляет фаза 12 в docs/05-mvp-plan.md: закоммиченный .env и известные шаблоны ключей, с путём и строкой, но никогда со значением.

Учётные данные tracker ​

Binnacle никогда не пишет в tracker (ADR-0013), поэтому просит токены только на чтение: утёкший токен не может изменить репозиторий.

TrackerТокенЕго доступ
GitHubfine-grainedчтение Issues; для CI в snapshot — чтение Actions, Commit statuses и Pull requests
GitLabлюбойread_api
  • Токен задаётся в окружении демона как BINNACLE_GITHUB_TOKEN или BINNACLE_GITLAB_TOKEN либо в ~/.binnacle/credentials.json, по одному на хост. Демон, запущенный автозапуском, таких переменных не получает, поэтому храните его токены в файле. Как — в чек-листе установки.
  • Файл учётных данных, который могут читать другие, отвергается с tracker.credentials_insecure.
  • Токен отправляется только на свой объявленный хост и никогда не появляется в ответе, диагностике, событии или строке лога.
  • GitHub отдаёт check runs только GitHub Apps, поэтому Binnacle читает workflow runs и statuses коммита и никогда — его содержимое.
  • Токены никогда не импортируются из gh или glab: их токены обычно могут писать, и обещание выше было бы нарушено.

CI, прочитанный из Git remote, а не из tracker, идёт на хост, который не объявлял ни один манифест. На github.com или gitlab.com используется токен, хранимый для этого хоста. На любом другом хосте — только запись файла учётных данных для него и никогда токен из окружения, чтобы remote не мог вытянуть токен, предназначенный для другого хоста.

Локальная сеть ​

Демон слушает только 127.0.0.1, если BINNACLE_HOST не задаёт 0.0.0.0, как в контейнере. Loopback — не граница аутентификации: до него может достучаться любая вкладка браузера пользователя. Учётных записей нет, потому что пользователь один; вместо них демон охраняют токен и две проверки заголовков.

ПутьТокенЧто делает
GET /healthнетГоворит, слушает ли демон Binnacle и какой он версии; больше ничего
POST /v1/logsнетПринимает логи OpenTelemetry: экспортёр harness настраивается эндпоинтом и ничем больше. Сохраняет метаданные каждого вызова и счётчики токенов и ни на какой вопрос не отвечает. Принимает вызовы только с loopback этой машины, на каком бы адресе ни слушал демон
POST /v1/metrics, POST /v1/tracesнетОтвечает, но не хранит
POST /ops/<operation>bearerКаждая операция: CLI, binn mcp и dashboard
любой другой GETнетСгенерированные файлы dashboard, в которых нет данных проекта

Каждый путь, в том числе без токена, проверяется дважды:

  • Host должен быть ровно собственным адресом демона, 127.0.0.1:<port>, или значением host:port из BINNACLE_ALLOWED_HOSTS: не localhost:<port> и не другим именем, если его нет в списке.
  • Origin, если он отправлен, должен быть http:// с одним из этих адресов.

Вместе они отражают DNS rebinding. Кроме того, страницы dashboard несут Content-Security-Policy: они ничего не загружают и ни с чем не соединяются, кроме демона, и запускают только те inline-скрипты, что есть в отданном HTML.

binn mcp говорит с harness по MCP через stdio и вызывает демон с токеном, как любой другой клиент.

Токен dashboard ​

  • binn dashboard открывает dashboard с токеном во фрагменте адреса, который никогда не доходит до сервера. Страница переносит его в local storage браузера (ADR-0031).
  • binn dashboard печатает адрес без токена, потому что вывод shell у навыка доходит до provider модели.
  • binn dashboard --print, для человека у терминала, печатает адрес с токеном.

Удалённый или командный доступ — это post-MVP, и для него нужны собственные аутентификация и модель угроз.

Права на файлы ​

Всё, что Binnacle хранит о себе, лежит в домашнем каталоге Binnacle: по умолчанию ~/.binnacle или каталог, который называет BINNACLE_HOME. Каталог создаётся с 0700, а файлы, которые Binnacle там пишет, получают 0600:

  • токен API;
  • runtime-файл демона и его лог;
  • хранилище, чьи служебные файлы SQLite защищает 0700 каталога;
  • реестр проектов;
  • файл настроек.

0600 и 0700 — режимы POSIX. В Windows они не применяются: Node передаёт режим, а файловая система его игнорирует.

  • Там эти файлы защищены ACL профиля пользователя и ничем из того, что делает Binnacle.
  • Всё, что запущено под этой учётной записью Windows, может прочитать токен API.
  • Это та же граница, за которой уже лежат собственные файлы учётных данных harness, но это не защита, которую даёт Binnacle, и эта страница не делает вид, что она есть.

Открытые advisories зависимостей ​

pnpm audit --prod не сообщает ни одного advisory уровня high или critical. pnpm audit всё ещё сообщает перечисленные ниже, все — в инструментах сборки dashboard. Они работают при nuxt generate и никогда не поставляются: dashboard отдаётся как статические файлы (ADR-0031). Каждый оставлен, потому что ни один релиз прямой зависимости его не убирает (2026-10-13).

AdvisoryПакет, черезСерьёзностьПочему оставленВернуться, когда
GHSA-x6jw-m9v5-85vh, GHSA-v5rq-49vh-5v5c, GHSA-g4wm-2vf7-vfgr, GHSA-858h-whjf-mvg5simple-git 3.x и @simple-git/argv-parser, через nuxt → @nuxt/devtools 3critical, highИсправлено в simple-git 4, который не берёт ни один @nuxt/devtools 3; его убирает только devtools 4, всё ещё beta, а Nuxt 4.6 требует devtools 3. Dashboard выключает devtools, и они работают только под nuxt dev.стабильный Nuxt возьмёт @nuxt/devtools 4
GHSA-86w9-cpqp-85rvnode-forge, через nitropack → listhenhighИсправленного релиза нет. listhen — слушатель сервера разработки; nuxt generate не проверяет им ни одной подписи.node-forge выпустит исправление
GHSA-vfj7-8cjw-p6xmbraces, через nitropack → globby → micromatchhighИсправленного релиза нет. Шаблоны, которые он раскрывает, — собственные шаблоны dashboard во время сборки, так что худший случай — неудачная сборка.braces выпустит исправление
GHSA-g7r4-m6w7-qqqresbuild 0.27, через @nuxt/ui → @nuxt/fonts 0.14 → fontlesslowПоследний Nuxt UI всё ещё берёт @nuxt/fonts 0.14. Уязвимость касается сервера разработки esbuild в Windows, который dashboard никогда не запускает, а шрифты Nuxt UI dashboard выключает.Nuxt UI возьмёт @nuxt/fonts 1

Восстановимость ​

Локальное хранилище SQLite — пересобираемая проекция, а не источник истины: знание о проекте остаётся в Git, tracker и документах. Потеря хранилища может стоить истории telemetry, но никогда — решения.

Плавная деградация ​

Когда опциональной части нет, работа продолжается:

НетЧто происходит
GraphifyАгенты используют Serena, исходники и документы
ObsidianКанонические документы не затронуты
BinnacleОбычный workflow агентов и Git продолжается
Адаптера telemetryРабота продолжается; метрики за этот интервал неполны и так и помечены

Apache-2.0