harnsy: справка по безопасности
Для тех, кто решает, можно ли запускать harnsy на корпоративной машине. Это факты из собственного разбора кода harnsy 0.9.0, который сделал разработчик (ревизия исходников e7a7798d, выпуск 0.9.0); это не независимый аудит и не сертификация, и работающую установку не проверяли. В следующих версиях может быть иначе: что изменилось, сказано в заметках о выпуске. Где написано «по умолчанию», настройка это меняет; где написано «нет» или «никогда», разбор не нашёл в коде ничего, что это делает. Разработчик: Павел Бучнев, индивидуальный предприниматель (Грузия), регистрационный номер 345621981. Вопросы: hello@harnsy.dev.
1. Что такое harnsy
harnsy — локальная программа, которая соединяет кодинг-агентов, которыми человек уже пользуется (Claude Code, Codex, OpenCode), чтобы их агенты могли писать друг другу и работать как одна команда. Команды, которые выполняет агент, идут через один из этих инструментов, под его собственными разрешениями, которые harnsy не обходит. Сама harnsy запускает эти инструменты, выполняет git для локальных проверок и, после того как человек включил каждый, скрипты, называемые действиями (раздел 9). Расчёт сделан на рабочую станцию одного человека (см. раздел 13).
2. Что запускается и что устанавливается
- Один локальный процесс,
harnsy serve(узел), под учётной записью самого человека. Без root и без sudo. - Linux: пользовательская служба systemd. macOS: LaunchAgent. Windows: задача планировщика при входе, с минимальными правами.
- Исполняемый файл ставится в
~/.local/bin/harnsy(Windows:%LOCALAPPDATA%\harnsy\bin). - Необязательное приложение в трее только читает локальный адрес дашборда и не открывает порт.
- На Windows harnsy открывает агентов в собственном терминальном хосте; он слушает сокет или канал только для этого пользователя, не TCP.
harnsy uninstallудаляет службу, трей и исполняемый файл и откатывает правки настроек, сделанные установщиком. Папку с данными он оставляет (раздел 8).
3. Изменения в настройках других инструментов
Установщик меняет настройки подключаемых инструментов только после того, как покажет изменение построчно и получит явное «да»; сначала он делает резервную копию файла. Каждое изменение необязательно.
- Claude Code (
~/.claude/settings.json): хук начала сессии (скрипт-справка, который читает только локальный адрес), обёртка строки состояния, хук запроса разрешения на локальный адрес и, если вы согласитесь, набор правил, разрешающий собственные инструменты harnsy. - Codex (
~/.codex/hooks.json): тот же хук начала сессии. Егоconfig.tomlне меняется. - OpenCode: файл настроек не пишется.
- Установщик не регистрирует MCP-сервер, а только печатает команду.
- Изменения, сделанные позже из дашборда (правило разрешения в файле настроек Claude, доверие к папке проекта), удаление не откатывает.
4. Порты и кто может подключиться
| Порт | По умолчанию | Что обслуживает | Кто может подключиться |
|---|---|---|---|
| 7788 | только 127.0.0.1; узел не запустится на адресе не из петли | дашборд, полный API | любой процесс на этой машине |
| 7790 | 127.0.0.1, включён (можно выключить) | API для агентов без админских маршрутов, прокси для модельных запросов Ассистента, прокси ключей | любой процесс на этой машине |
| 7789 | выключен, пока лицензия harnsy Max не разрешит узлы и не выдан токен узла | другие машины кластера человека; каждый запрос требует токен и область | владельцы токена узла |
| доступ снаружи | выключен | дашборд с телефона или из другой сети | устройства, вошедшие по QR-коду и ключу доступа (passkey); без сессии отдаются только страницы входа, публичные ссылки на файлы и статические файлы приложения |
- Локальные порты проверяют, что запрос назван адресом из петли и пришёл с допустимым источником и типом; это не даёт веб-странице в браузере управлять ими.
- Между пользователями на адресе из петли разграничения нет: любая локальная учётная запись, которая может открыть соединение с ним, получает API без токена. harnsy рассчитан на рабочую станцию одного человека; на общем многопользовательском узле до него дотянется каждая локальная учётная запись.
- Порт кластера на сетевом адресе и доступ снаружи включает сам человек, явно. Оба работают через TLS.
5. Исходящие соединения
Без лицензионного ключа harnsy по умолчанию не открывает соединений за пределы машины. Каждое соединение ниже возникает, только когда человек добавил ключ, добавил подключение или запустил возможность. Некоторым ключ не нужен: диктовке, модельным запросам Ассистента и машине, присоединённой к главному узлу (она может пользоваться размещённым релеем по лицензии главного узла).
| Куда | Когда | Что отправляется | Что нужно | Как отключить |
|---|---|---|---|---|
Сервис лицензий (lic.harnsy.dev) | после добавления ключа: активация, затем проверка примерно раз в сутки; при удалении ключа | весь ключ; хеш идентификатора машины (сам идентификатор машину не покидает); случайное одноразовое значение; метка (по умолчанию ОС и четыре символа хеша, не имя хоста; введённую вами метку отправляют как есть); ОС и архитектура; версия harnsy и дата сборки; открытый ключ, если ключ выдаёт места | лицензионный ключ | удалить ключ |
| Сервис лицензий, обмен короткого ключа | когда человек вводит короткий ключ HRSY-… | код, хеш машины, метка, ОС и архитектура, версия | вставить файл лицензии | |
| Сервис лицензий, билет релея и сервис имён | размещённый релей для узлов или размещённый доступ снаружи | ключ, хеш машины, отпечаток ключа релея; подписанное значение проверки DNS | harnsy Max | выключить релей или доступ снаружи |
Размещённый релей (relay.harnsy.app, порт 443) | узлы через релей или размещённый доступ снаружи | только зашифрованные потоки (раздел 10); релей видит сетевой адрес каждого соединения, какой узел и какая лицензия (в журнале — хеши), время и объём данных, но не содержимое | harnsy Max | harnsy cluster relay off; выключить доступ снаружи |
| Let’s Encrypt | размещённый доступ снаружи или свой домен с автоматическими сертификатами | ключ учётной записи, заказ на имя узла, запрос сертификата | не нужен: в размещённом режиме к ним обращаются до проверки лицензии | выключить доступ снаружи; взять свои файлы сертификата |
crt.sh | размещённый доступ снаружи, каждые 6 часов | публичное имя узла (слежение за Certificate Transparency) | не нужен: в размещённом режиме к ним обращаются до проверки лицензии | выключить доступ снаружи |
| Собственный главный узел человека | машина присоединена к кластеру | токен узла, имя узла, сборка, подтверждение лицензии; затем трафик кластера (сообщения, список агентов, файлы, потоки терминалов, которые человек разрешил) | лицензия или одолженное место | выйти из кластера |
| Telegram, Discord | добавлен бот | токен бота; тексты и файлы .md, которые агенты отправляют в чаты человека; голосовые, которые скачиваются для диктовки | подключения | архивировать бота |
Сервис push-уведомлений браузера (fcm.googleapis.com, web.push.apple.com, updates.push.services.mozilla.com, *.notify.windows.com; адрес даёт браузер человека, только эти хосты, https, порт 443) | агент ждёт ответа на вопрос или запрос разрешения (ожидание ввода — только если человек это отметил), на устройстве, где push включён, вне тихих часов этого устройства; а также когда человек нажимает «тест» | зашифрованное сообщение (RFC 8291), которое прочитает только ваш браузер: вид, имя агента, название проекта и команды, внутренний номер ожидания, язык; текста вопроса, команды, пути к файлу, токена в нём нет. Сервис push видит адрес подписки, сетевой адрес узла, который отправляет, время и размер каждого сообщения, но не содержимое; на телефоне видны имя агента и название проекта или команды, но не вопрос | harnsy Max (мобильный доступ); устройство, в котором ещё выполнен вход | «Настройки › Уведомления»: выключить или удалить устройство; выход из устройства или его отзыв прекращает отправку |
api.openai.com (или адрес, заданный человеком) | диктовка: микрофон в дашборде, голосовые, «проверка» | звук (только в памяти), модель, язык, ключ человека | не нужно | не добавлять подключение для диктовки |
api.anthropic.com, api.openai.com, api.z.ai, open.bigmodel.cn | только когда человек нажимает «проверка» у подключения | токен Claude: один настоящий запрос на один токен; API-ключи: запрос списка моделей | подключения | не нажимать «проверка» |
auth.openai.com | человек начинает «вход в ChatGPT» для подключения Codex | вход по коду устройства | подключения | не пользоваться |
api.github.com (или адрес GitHub Enterprise) | подключение GitHub добавлено или проверяется | токен; запросы только на чтение | подключения | не добавлять |
| Хосты ключей в хранилище ключей | агент обращается к прокси ключей | запрос агента с ключом, подставленным harnsy; частные адреса, адреса петли и облачных метаданных отвергаются | хранилище ключей | удалить ключ |
api.anthropic.com, chatgpt.com, api.openai.com через локальный модельный прокси | только для сессий Ассистента: harnsy пересылает запрос инструмента без изменений | запрос инструмента с его собственным заголовком ключа; ничего не сохраняется | не запускать Ассистента | |
| Собственный сервер OpenCode | человек добавил его | список моделей, проксируемые запросы | подключения | не добавлять |
| Адрес S3, заданный человеком | хранилище переключено на S3 | вложения | harnsy Max | оставить хранилище по умолчанию — локальный диск |
- Что сервис лицензий хранит вместе с записью о вашем ключе по каждой машине, на которой ключ активирован: хеш машины, метку, ОС и архитектуру, версию harnsy, время первого и последнего обращения, конец срока работы без сети, а также когда и кем машина освобождена; ещё журнал активаций и освобождений и дни, в которые машина проверяла ключ. Дату сборки он не хранит и IP-адрес запроса программы в базу не пишет. Журналы его веб-сервера хранят IP-адрес, время и адрес каждого запроса 7 дней, секреты замаскированы. То же сказано в уведомлении о данных заявок на ключ.
- Телеметрия, аналитика и отчёты о сбоях: нет; такого кода в программе нет. Проверка лицензии выше всё же сообщает сервису лицензий, что машина с этой версией работает.
- Обновления: программа никогда не проверяет и не ставит обновления. GitHub за релизами обращаются только скрипты установки, и только когда человек их запускает.
- harnsy не обращается к API моделей ИИ сама. Единственные обращения: кнопка «проверка», диктовка и пересылка для Ассистента, описанная выше. Расход и лимиты читаются из локальных файлов.
- Большинство клиентов учитывает настройку
HTTPS_PROXY; модельный прокси и прокси ключей её намеренно игнорируют. - Собственные вызовы
gitу harnsy не выходят в сеть.
6. Чего harnsy не делает
- Нет телеметрии, аналитики и отчётов о сбоях.
- Она никогда сама не проверяет и не устанавливает обновления.
- Она не читает токены входа Claude Code (
~/.claude/.credentials.jsonили системное хранилище ключей). - Она никогда не читает
auth.jsonOpenCode. - Сам идентификатор машины никогда не покидает машину; уходит только его хеш.
- Запрос агента никогда не заставляет harnsy выполнить команду в терминале.
- Ни один секрет не попадает в командную строку: ключи доходят до инструмента через его окружение или файл.
- Агенты не могут ответить на запрос разрешения через API агентов harnsy. Это не защищает от другого процесса того же пользователя.
7. Учётные данные и ключи
- Claude Code: из
~/.claude.jsonharnsy читает только поля аккаунта (идентификатор аккаунта, который хранится как хеш; почту; тариф; название организации) для цифр расхода. - Codex: файл входа читается в память; хранятся только почта, тариф, хеш идентификатора аккаунта и срок действия токена. Токены собственного входа человека в Codex не сохраняются и не отправляются.
- Ключи, которые добавляет человек (токены подписок, API-ключи, токены ботов, токен GitHub, значения хранилища ключей, секрет S3), запечатаны в базе данных шифром AES-256-GCM. Ключ шифрования — отдельный файл
secret.key, доступный только пользователю. - Инструмент получает такой ключ через своё окружение, никогда в командной строке. Одно исключение: подключение Codex записывает расшифрованный файл входа в папку данных, доступный только пользователю, потому что Codex читает только файл.
- Хранилище ключей: агент значения не видит. harnsy сама подставляет его в исходящий запрос и убирает из ответа.
- Лицензионный ключ — обычный файл в папке данных, доступный только пользователю.
- Приглашения, токены мест, устройства доступа снаружи, коды сопряжения и ссылки на файлы хранятся только как хеши SHA-256; ключи доступа (passkey) — только как открытые ключи.
- Токены присоединения к кластеру хранятся открытым текстом в базе данных и в файле кластера на присоединяемой машине (доступном только пользователю).
8. Данные на диске
- Всё лежит в
~/.harnsy(или в папке изHARNSY_HOME), создаётся доступным только пользователю (на Windows — со списком доступа только для пользователя, если папку создала harnsy). harnsy.db(SQLite): сообщения между агентами целиком, события, рабочие задачи, команды и роли, цифры расхода, журнал действий в терминалах, подключения и хранилище ключей (запечатаны), журналы использования ключей и доступа снаружи.- Уведомления на телефон: по каждому устройству
harnsy.dbхранит адрес браузера (endpoint) и ключи, короткую пометку о браузере и системе, язык и настройки; отправленное хранится 7 дней; ключ подписи push узла — файл, доступный только пользователю. Когда вы удаляете устройство или выключаете push, отправка прекращается, но адрес и ключи остаются в базе с пометкой «удалено». - Файлы и вложения хранятся как есть, до 100 МБ на файл и 5 ГБ всего. Файлы, брошенные на терминал, хранятся 7 дней.
- Экраны терминалов не сохраняются. Они живут в памяти; журнал записывает действие (кто, какая панель, результат), а не текст на экране.
- В покое зашифрованы только запечатанные секреты. Всё остальное лежит как есть и защищено правами на файлы.
- Сроки хранения: сообщения, события, рабочие задачи и история расхода лежат, пока человек их не удалит. 30 дней: журнал действий в терминалах, отправленные и неудавшиеся сообщения в чатах, журнал действий агентов (настраивается). 90 дней: журнал хранилища ключей и журнал доступа снаружи. 7 дней: корзина файлов и загрузки в терминал.
- Чтобы удалить всё: выполните
harnsy uninstall, затем вручную удалите~/.harnsy(а также~/.local/share/harnsy/backups, на macOS —~/Library/Logs/harnsy). Одной команды, стирающей данные, нет.
9. Что агенты могут делать через harnsy
- Агенты через локальный API и MCP отправляют сообщения, видят других агентов, ведут команды и рабочие задачи, открывают новых агентов, читают и пишут общие файлы узла (только
exchange/иdocs/). - Сообщение доходит до инструмента как обычный ход пользователя по его собственному каналу, а не нажатиями клавиш.
- Агентам не отдаются: управление кластером и удалёнными участниками, смена лицензии, админка подключений и хранилища ключей, доступ снаружи, подключение к терминалу, ввод в него и загрузка, ответы на запросы разрешения.
- Терминалы: агент никогда не запускает команду в панели через harnsy. Ввод, подключение, загрузка и открытие оболочки — только для человека. Читать экран панели может агент, который её открыл, и его лид. Это относится к панелям, которые открыла harnsy.
- Запросы разрешения Claude Code показываются в дашборде; собственный диалог инструмента в терминале остаётся живым, побеждает первый ответ. Из чата (Telegram) ответ по умолчанию выключен, возможен только в личном чате владельца и только «один раз» или «отказать».
- Что исполняет сама harnsy: кодинг-агенты в панелях терминала,
git(только локально),codex queueи «действия» — скрипты, которые запускаются только после того, как человек включил каждый из них (закреплены по SHA-256), и которые агент может запустить, только если человек разрешил. - Доверие Codex к проекту передаётся по умолчанию; доверие Claude Code к папке по умолчанию выключено.
10. Между машинами, релей и доступ снаружи
- Несколько машин (harnsy Max): связь между узлами по умолчанию идёт через TLS, когда порт кластера на сетевом адресе. Главный узел создаёт свой ключ, а присоединяемая машина закрепляет его отпечаток, полученный внутри токена присоединения, так что ничему не доверяют при первом знакомстве. Порт только для TLS отвечает на открытый текст ошибкой. Токены можно отозвать.
- Установленная служба оставляет адрес кластера по умолчанию
127.0.0.1:7789обычным HTTP на самой машине — для TLS-прокси перед ним. - Размещённый релей для узлов (бета): два слоя TLS; внутренний — закреплённый TLS главного узла от края до края, поэтому релей не может прочитать ни токены, ни сообщения.
- Размещённый доступ снаружи: релей читает только имя TLS-сервера и передаёт зашифрованные байты; TLS заканчивается на машине человека. Оговорка: тот, кто управляет DNS размещённого имени узла (имени под
n.harnsy.app), мог бы получить на него сертификат. В размещённом режиме это мы: мы держим эту DNS-зону и релей. harnsy следит за Certificate Transparency каждые 6 часов и сообщает о сертификате, который не запрашивала. Это обнаруживает такой сертификат, но не предотвращает его. - Вход снаружи: QR-код, созданный в локальном дашборде (действует 5 минут, один раз), затем ключ доступа (passkey); каждая запись требует проверки ключом доступа не старше 15 минут; устройство выходит из системы после 7 дней простоя (не позднее чем через 30 дней); cookie с флагами
SecureиHttpOnly. Полное управление по умолчанию выключено и само заканчивается через 2 часа. - Размещённый релей работает у Hetzner Online GmbH в Фалькенштайне, Германия. Его журнал хранится 14 дней: по каждому подключению узла — время, хеш идентификатора узла, хеш идентификатора лицензии и адрес источника, обрезанный до /24; по каждому переданному потоку — время, хеш идентификатора узла, адрес источника, обрезанный до /24, байты туда и обратно, длительность и чем закончилось. Содержимого, URL, имён и почты в нём нет. Пока узел подключён, релей держит идентификатор его лицензии в памяти, чтобы применять лимиты и блокировки. Неудавшееся TLS-рукопожатие записывается с полным адресом источника и портом, тоже 14 дней. Собственные журналы администрирования сервера (входы по SSH и заблокированные пакеты, с полными адресами) хранятся 30 дней. Для межсетевого экрана: релей —
relay.harnsy.app, порт 443; сервис лицензий —lic.harnsy.dev.
11. Обновления и целостность сборки
- Обновления ручные: человек запускает установщик заново или заменяет исполняемый файл.
- Каждый релиз публикует на GitHub архивы по системам и файл
SHA256SUMS; установщик сверяет архив с ним. - Исполняемый файл
harnsyнесёт подпись Ed25519 и проверяет себя при запуске. Неудачная проверка его не останавливает: он работает как бесплатная редакция, а ответ про лицензию в дашборде показывает пометку о целостности.SHA256SUMSи исполняемый файл трея не подписаны. - Сборки идут с
-trimpathи без кода на C (CGO_ENABLED=0). Воспроизводимость сборок не заявляется. - Проверяющий может выполнить:
sha256sum -c SHA256SUMS --ignore-missing;go version -m harnsy(версия Go, теги, ревизия); после запускаcurl -s http://127.0.0.1:7788/api/licence, где поле целостности пусто, а дата сборки задана. - Без сети: лицензионный ключ проверяется на машине; harnsy Max продолжает работать без сети до даты, которую сервис лицензий назвал при последней проверке: через 30 дней после неё, а для платной лицензии с закончившимся сроком — через год (подарочный ключ года не получает).
12. Исходный код и лицензия
Исходный код закрыт («все права защищены»); сборки опубликованы на GitHub (harnesy/app). Условия лицензии — в LICENSE и в EULA.
13. Ограничения, которые стоит знать до решения
- Общий многопользовательский узел: каждая локальная учётная запись достаёт до локального API (раздел 4).
- Токены присоединения к кластеру лежат на диске открытым текстом (раздел 7).
- В покое зашифрованы только запечатанные секреты; всё остальное держится на правах доступа к файлам.
- Оговорка про сертификат размещённого доступа снаружи (раздел 10).
- Без лицензионного ключа размещённый доступ снаружи всё равно обращается к Let’s Encrypt и crt.sh.
- В Windows часть файлов с ключами опирается на список доступа папки данных, который harnsy задаёт, только когда сама создаёт эту папку.
- Настройка
strict_localне отказывает локальному вызывающему, который не прислал токен. - Устройство телефона, которое удалили, оставляет в базе свой адрес и ключи с пометкой «удалено» (раздел 8).
SHA256SUMSи исполняемый файл трея не подписаны; сборки не воспроизводимы.- Изменённый исполняемый файл не отвергается: он работает как бесплатная редакция.
harnsy uninstallоставляет папку данных и позднейшие правки настроек Claude, сделанные из дашборда.- harnsy — не песочница: что может агент, решает инструмент, в котором он запущен.
Сообщить об уязвимости: hello@harnsy.dev.
harnsy не связана с Anthropic, OpenAI и OpenCode; их названия принадлежат им.
Контакт: hello@harnsy.dev