Перейти к содержимому
ColliePWA

08/Documentation

Безопасность durable agent

Что может и чего не может делать durable agent, правила доверия сокету и токену, что Collie делает с текстом durable agent и что сохраняется в журнале аудита

Экспериментальная. Сетевой протокол, SDK и эта страница могут измениться, либо функциональность может быть удалена в следующем минорном релизе. В Durable agents описано, от чего зависит её сохранение.

Durable agent — это код, который вы запускаете или развёртываете, и Collie считает его вывод ненадёжным текстом. На этой странице описано, к чему durable agent имеет доступ, что защищает его от посторонних, как Collie обрабатывает его текст и что сохраняется в журнале аудита. О Collie в целом рассказано в Безопасность.

Что durable agent может и чего не может делать

Durable agent спрашивает, а сопряжённое устройство решает. Durable agent получает то, что вы отвечаете и отправляете ему, а также запросы из сети. Collie не даёт ему доступа к вашим терминалам.

durable agent можетdurable agent не может
Задать вопрос: «да» или «нет», выбор варианта, строку текста или короткую формуОтветить на собственный вопрос через Collie
Перечислить стартеры и разместить в ленте до четырёх собственных кнопокВводить текст в ваши терминалы или показывать экран
Размещать текст, код и ссылки https:// в перепискеПоказывать чистый HTML, изображение или ссылку, которая не является веб-адресом
Выбирать текст собственного push-уведомления в пределах ограниченийОтправлять push-уведомлений больше, чем разрешено лимитом

На вопрос отвечает только нажатие человека. Маршрут ответа работает для сопряжённого устройства за шлюзом записи, и ничто в мосте не вызывает его для durable agent, хука или вывода модели. На телефоне для «Разрешать всегда» требуется второе нажатие. Durable agent, предлагающий это, обладает разрешением, требующим наибольшей осторожности, поскольку один ответ от вредоносного инструмента пропустит все последующие вызовы без вопросов.

Исполнение одобренного действия контролирует durable agent, а не Collie. Кнопка durable agent выполняется с правами самого durable agent, а Collie лишь передаёт нажатие.

Durable agent не может заспамить ваш экран блокировки. Collie обрабатывает каждый вопрос один раз, определяя его по durable agent и вызову инструмента, и отправляет push-уведомление максимум единожды. Допускается 3 push-уведомления на переписку в минуту, 10 на хост в минуту и 30 на хост в час. Push-уведомление, которое стало бы 31-м, превращается в одно сводное, после чего хост ничего не отправляет в течение часа. Карточка показывается всегда.

Внимание. Тот же пользователь может ответить на вопрос через сокет. Сокет закрыт для других пользователей, но не для процессов вашего собственного пользователя, включая инструмент, запущенный вашим агентом. Проверка потомков — это собственная защита durable agent, и Collie не может знать, выполняет ли её durable agent.

С этой проверкой durable agent отклоняет answer, send, abort, action, rename, close, reopen и starter от самого себя, от любого запущенного им процесса и от вызывающей стороны, которую он не может от них отличить. Отказ возвращается с кодом 403 caller-refused, при этом чтение остаётся доступным. Для проверки требуется Bun на Linux, где SDK считывает вызывающую сторону сокета. В таблице указано, что именно обеспечивается в зависимости от среды выполнения durable agent:

где работает durable agentчто обеспечивает проверка потомков
Bun на LinuxРаботает по умолчанию. SDK считывает вызывающую сторону каждого соединения и отклоняет действие от durable agent, его потомков или неопознанной вызывающей стороны с ошибкой 403 caller-refused
Bun в других средах, например на macOSРаботать не может. openCollie завершается при запуске с ошибкой, если durable agent не передаст callerCheck: "off". С off ответить может любой процесс вашего пользователя
NodeРаботать не может. Durable agent запускается и выводит одну строку предупреждения. Ответить может любой процесс вашего пользователя

Изолируйте инструменты агента в песочнице, у которой нет доступа к сокету, относитесь к карточке как к уведомлению, а не шлюзу, или запускайте durable agent на Bun. callerCheck: "off" — это собственный выбор durable agent работать без проверки.

Транспорт через сокет

Приватный сокет закрыт для всех остальных пользователей, и единственной преградой к нему служит путь.

ls -ld /run/user/1000 /run/user/1000/desk /run/user/1000/desk/app.sock

Сокет не передаёт ни токен, ни заголовок Authorization. Collie подключается только тогда, когда весь путь является приватным, и перед каждым подключением выполняет обход от / вниз с флагом lstat, исключая переход по ссылкам:

компоненттребование Collieчто указано в причине
Каждая часть пути, включая сокетНе символическая ссылка, даже если она указывает на корректное местоsocket-not-private: <path> is a symlink
Собственный каталог сокетаНастоящий каталог, принадлежащий вам, с правами строго 0700the socket's folder <path> has mode 0755, not 0700, либо belongs to user <a>, not to <b>, либо <path> is not a directory
Каждый каталог выше негоНастоящий каталог, в который группа и остальные не могут писать. Каталог со sticky bit, такой как /tmp, допустим на этом уровне, но не как собственный каталог сокета. Его владелец не проверяется, поскольку служба с изолированным /tmp видит каталоги root от имени пользователя 65534<path> has mode 0775, so group or others can write to it
СокетСокет, принадлежащий вам, без прав доступа для группы или остальныхthe path is not a socket, the socket belongs to user <a>, not to <b>, the socket has mode 0666, not 0600
Платформа без идентификаторов пользователейБезопасный отказ: Collie никогда не выполняет подключениеthis platform shows no file owner
WindowsДоступен только транспорт HTTPS: collie durable attach --socket возвращает отказ до выполнения записиa private socket needs Unix user ids; on Windows use --url <https://...> --token-env VAR

Путь, не прошедший проверку, сразу становится недоступным, без отсрочки. collie doctor называет ту же проверку в строке durable-socket и указывает способ исправления. Если по пути ничего нет, возвращается no socket at <path>, что не нарушает конфиденциальность.

Durable-агент, собранный с помощью SDK, создаёт каталог сокета с правами 0700, если тот отсутствует. Он отказывается запускаться в уже существующем каталоге с другими правами. Он устанавливает для сокета права 0600 и удаляет неработающий файл сокета перед началом прослушивания.

Транспорт через сокет предназначен для Linux и macOS. В Windows нет транспорта через сокет, поэтому используйте там транспорт по токену.

Транспорт по токену

URL и токен обеспечивают доступ к durable-агенту на другом хосте, и токен служит единственной защитой.

openssl rand -hex 32
правилозначение
ТокенОт 32 до 4096 байт после обрезки пробелов, печатные символы ASCII без пробелов
URLhttps://, либо http://127.0.0.1:<port>, либо http://localhost:<port> для durable-агента на этой машине. Не более 2048 байт. Без имени пользователя, пароля, параметров запроса или фрагмента
СертификатПроверяется так же, как его проверяет любой клиент. В Collie нет переключателя для пропуска проверки
ПеренаправленияCollie не переходит по перенаправлениям, поэтому токен никогда не попадёт на другой хост

Любой, у кого есть токен, действует от имени вашего телефона. Он может читать все диалоги, отвечать на любые вопросы, отправлять текст, останавливать реплику, переименовывать или закрывать её, а также запускать starter. У подключения по TLS из интернета нет вызывающей стороны для проверки, поэтому проверка дочернего процесса здесь отсутствует. Durable-агент, к которому обращаются таким способом, должен предлагать только Allow и Deny, но никогда always-allow.

Хост видит открытый текст. TLS заканчивается на хосте, поэтому он видит каждый запрос, включая токен в заголовке, а диалоги хранятся в его хранилище.

Collie хранит токен в виде открытого текста в двух местах. sources.json содержит его для записи, и резервная копия или синхронизация каталога конфигурации переносит его. Collie сохраняет этот файл с правами 0600, сужает более широкие права при запуске с записью в логе, а collie doctor показывает красную строку sources, если файл доступен для чтения группе или остальным. Вариант только для durable-агента хранит его в .env или config.toml, и файл, содержащий его, должен иметь права 0600. Collie никогда не выводит токен в печать. collie durable list выводит (token set), collie doctor выводит set, <n> bytes, и ни одна ошибка или строка лога не содержит это значение. attach считывает его из переменной, указанной в --token-env, поэтому его нет в командной строке.

Срок действия токена не ограничен. Чтобы сменить его, передайте durable-агенту новый токен перед перезапуском Collie, иначе телефон сообщит, что durable-агент отклонил его. Durable-агент может принимать второй токен на время смены: пример с припаркованным Cloudflare принимает COLLIE_TOKEN и, пока тот задан, COLLIE_TOKEN_NEXT (ADR 0103). Шаги описаны в Токены.

Это исходящий вызов, который Collie выполняет к настроенному вами URL, и он отклоняется отсутствием вложений. Каждый запрос передаёт Authorization: Bearer <token>, версию протокола, ETag последнего чтения, а для нажатия — тело того, что вы ответили или отправили. Чтение — это GET без тела.

Каждый опрос по https — это запрос, за который ваш хост может взимать плату, и ответ «ничего не изменилось» также учитывается. Если телефон не открыт, опрос в режиме ожидания выполняется каждые 10 с, поэтому Collie отправляет запрос 8 640 раз в день, и каждые 2 с, пока открыт телефон. К durable-агенту, который недоступен или отклоняет токен, обращение происходит не чаще одного раза в 10 с, и эти запросы также тарифицируются. Используйте платный тариф для durable-агента, который Collie опрашивает весь день.

Что Collie делает с текстом durable-агента

Collie очищает каждую строку от durable-агента перед тем, как её прочитает что-либо ещё, и выводит её как текст.

Durable-агент должен отправлять строки в пределах лимитов. Collie не полагается на то, что он это сделал. Каждая строка проходит три шага:

  1. Управляющие символы удаляются. Collie удаляет управляющие символы C0, DEL и C1. Поля из нескольких строк сохраняют перевод строки и табуляцию: текст элемента, вывод и сводка вызова инструмента, а также причина вопроса.
  2. Невидимые символы и символы направления удаляются. Collie удаляет метки направления U+200E, U+200F и U+061C, переопределения и изоляты с U+202A по U+202E и с U+2066 по U+2069, символы нулевой ширины с U+200B по U+200D, соединитель слов U+2060, метку порядка байтов U+FEFF и теговые символы с U+E0000 по U+E007F, способные нести целое невидимое предложение.
  3. Строка обрезается. Collie обрезает строку до её байтового лимита по границе целого символа и завершает её символом ….

Вопрос, чей заголовок или причина изменились при очистке, получает метку «Text shortened» на карточке. Опция или кнопка панели без оставшихся слов отбрасываются, поэтому кнопка никогда не бывает пустой. Поле без слов именуется по своему id.

текстограничение
Заголовок рабочей области, вкладки, диалога или вопроса256 байт
Опция, поле или надпись стартера128 байт
Надпись кнопки панели16 символов
Причина вопроса2048 байт
Вывод вызова инструмента16384 байта
Текст сообщения или ответа65536 байт
Текст элемента markdown или code32768 байт
Текст, отправляемый durable-агентуОт 1 до 32768 байт, отклоняется до отправки
Один ответ durable-агента16 КиБ для hello, 4 МиБ для снимка состояния

Идентификаторы (id) никогда не очищаются и не обрезаются. Id содержит от 1 до 128 байт без управляющих символов, без пробелов и без любого из символов /, ? или #, иначе содержащий его объект отбрасывается.

Collie отображает текст как текст. Элемент markdown показывает заголовки, списки, выделение, фрагменты кода и ссылки; необработанный HTML никогда не отрисовывается: тег выводится как есть, обычными символами. Ссылка внутри элемента markdown открывает только веб-адрес. Элементу link требуется адрес https:// с хостом, без имени пользователя или пароля, без пробелов, управляющих или невидимых символов, длиной не более 2048 символов. В противном случае Collie отбрасывает элемент и записывает по одной строке в лог для каждой беседы. Изображения и файлы не являются элементами.

Что записывается в лог

Collie записывает каждую операцию записи с телефона в durable agent в <state-dir>/audit.log, режим 0600.

Каждая строка содержит имя durable agent в виде session, сопряжённое устройство и событие:

событиекогдачто сохраняет строка
answerКасание ответило на вопросИдентификатор запроса, вопрос и его ревизию, идентификатор варианта либо тип ответа (optionIds, text или values) и результат. Но не введённый вами текст
sendВы отправили или скорректировали текстИдентификатор запроса, указанные в нём реплику или вопрос, steer, результат и текст в виде превью из 120 символов
abortВы остановили репликуИдентификатор запроса, указанные в нём реплику или вопрос, и результат
actionВы нажали кнопку на панелиИдентификатор запроса, идентификатор действия, реплику и результат
starter.startВы нажали стартерИдентификатор стартера, идентификатор запроса и результат
durable.reopenВы снова открыли закрытую беседуИдентификатор беседы
space.renameВы переименовали рабочее пространствоИдентификатор пространства и новое имя

При закрытии и переименовании беседы или вкладки используются обычные события: pane.close, pane.rename и tab.rename. COLLIE_AUDIT_CONTENT=none скрывает все строки в деталях, кроме нескольких именованных полей вроде идентификатора запроса, поэтому превью send удаляется вместе с ними. Лог показывает то, что уже произошло. Он ничего не блокирует.

Collie также сохраняет квитанцию для каждого ответа, отправки, остановки, нажатия кнопки и стартера, без введённого текста. Где Collie хранит данные durable agent указывает, как долго.

Редактировать эту страницу на GitHub

The rest of the documentation