
Комментарии 4
а где в этой связке решается вопрос того что оба агента работают от одного юзера и имеют доступ к одним и тем же файлам? то есть если хермес скомпроментирован то он видит все ключи опенклоу, и наоборот. это осознанное архитектурное решение или временное пока не доделали изоляцию?
Юзер не один, их три:
$ id
uid=1001(...) groups=1001,27(sudo),988(docker)
$ id hermes
uid=1002(hermes) groups=1002(hermes),988(docker)
$ ls -ld ~/.openclaw /home/hermes
drwx------ ubuntu ubuntu /home/<я>/.openclaw
drwxr-x--- hermes hermes /home/hermes
Данные OpenClaw принадлежат uid 1000 — системному ubuntu, который был на машине до меня. Hermes на 1002, без sudo. Я на 1001 и ~/.openclaw в собственном домашнем каталоге прочитать не могу.
В сторону Hermes закрыто плотно. У контейнера OpenClaw один ключ, read-only, и в authorized_keys к нему привязано command="…hermes acp",no-pty,no-port-forwarding,no-agent-forwarding,no-user-rc. Скомпрометированный оркестратор получит stdio с процессом и всё. docker.sock из контейнера выкинут.
В обратную сторону вы правы. По правам hermes у OpenClaw не читает ничего, но он в группе docker — иначе не работает его песочница. Группа docker равна root на хосте: docker run -v /:/mnt, и все эти 700 становятся украшением.
Смягчает то, что чужой код исполняет не хост-процесс Hermes, а его контейнер: CapDrop=[ALL], не privileged, сокет внутрь не проброшен. Чтобы дотянуться до группы docker, надо сначала сбежать из песочницы.
Решение осознанное, записано у меня в компромиссы. Закрывается rootless-докером или socket-proxy вместо членства в группе. Пока не сделано — и это первое, что придётся закрыть, когда в allowlist появится второй человек.
а как у вас с логированием? ну типо когда два агента работают одновременно как понять кто из них что сделал и где сломалось?
Лог один, поэтому вопрос почти не возникает. Hermes сам никуда не пишет: он говорит по stdio через ACP, всё выходит на stdout гейтвея. Один поток, один порядок времени.
Настоящие строки, id укоротил:
[agent:nested] session=agent:hermes:acp:edf5ff53-… run=21b8ea1c-… channel=webchat …текст…
[agents/agent-command] [agent] run announce:v1:agent:hermes:acp:f75583cb-… ended with stopReason=stop
[telegram] outbound send ok chatId=… messageId=415
Кто это сделал — зашито в ключ сессии agent:hermes:acp:<uuid>. Префикс [agent:nested] отделяет исполнителя от оркестратора, run=<uuid> не даёт слипнуться двум прогонам. Настраивать ничего не пришлось.
Плохо вот что. Ротации нет: docker inspect показывает {"Type":"json-file","Config":{}}, лимитов ноль, файл растёт до конца диска. Диск на этой машине один раз уже уходил в 100% и уронил бэкапы. Хранилища и поиска тоже нет, это docker compose logs | grep, и лежит всё на той же машине, что и логируемое.
Ещё: в логах сессии разделены, на диске не всегда — всё без явного профиля песочницы пишет в один /workspace. Кто из двух перезаписал файл, уже не спросишь.
И про «где сломалось». Пост-фактум по логу видно до конкретного run и stopReason. В реальном времени как повезёт: делегирование — не переключатель, а поведение модели, Kimi иногда игнорирует streamTo. Результат приходит всегда, промежуточные шаги когда как.
OpenClaw и Hermes на одном VPS: чего стоит связать двух агентов безопасно