DD · Безопасность автономной системы (углубление)
Углублённый модуль поверх курса. Модуль 4 («Иммунная система») даёт архитектуру — матрицу риска READ/WRITE/DELETE/ТРАТА, budget-gate, sandbox для ночного билдера. Этот модуль — про восемь конкретных «болезней», которые матрица риска сама по себе не лечит: как патоген (чужая инструкция) проникает через данные, которые агент читает; как экстренно остановить всю систему одной командой; кто из органов вообще имеет право заходить в какую палату; откуда берётся заражённый инструмент; где хранить ключи от аптечки; как не спутать чужого пациента со своим; как убедиться, что звонящий — правда врач; и как не продиктовать секрет в общий журнал наблюдений. Тон и метки честности — как в основном курсе.
0. Почему этого не хватает в Модуле 4 — и почему это не паранойя
Почти каждый пункт ниже — не абстрактная угроза из учебника по кибербезопасности, а инцидент, уже случившийся у ближайшего архитектурного родственника его завода — OpenClaw (self-hosted агентный шлюз, с которым Лучиан лично экспериментировал). 30 000+ инстансов OpenClaw были найдены в открытом интернете без файрвола, потому что кто-то посчитал «свой домашний сетап» безопасным по умолчанию (цитата с полевого митапа OpenClaw-операторов, Модуль 10: «никто не считает свой сетап на 100% безопасным»). Завод Лучиана архитектурно ближе к этому классу риска, чем к корпоративному SaaS с командой security — докер-сервисы, публичные порты через Caddy, доступ снаружи, и (в планах) библиотека скиллов из тех же публичных каталогов, откуда бралась заражённая часть OpenClaw-экосистемы. У него уже есть правильный инстинкт (127.0.0.1-бинды, Caddy+SSO как единственный внешний вход) — модуль не меняет архитектуру, а достраивает восемь мест, где интуиция пока не формализована в код.
Модуль 4 отвечает на вопрос «какой уровень автономии дать шагу пайплайна» — иммунитет как система принятия решений. У иммунитета есть ещё и конкретные антитела под конкретные патогены. Восемь тем ниже — восемь антител под реальные атаки его системы: ночной билдер (пишет и исполняет код без присмотра), консультант-фабрика (видит чужие бизнес-данные), Telegram+голос как командные каналы, библиотека скиллов из публичных каталогов — источника, которому по умолчанию верить нельзя.
1. Prompt injection, включая cross-agent: заражение через то, что агент читает
По-человечески. У врача железное правило — колоть лекарство только по назначению из истории болезни, которую он сам ведёт. Но однажды в палату кладут анализ крови из другой клиники, а в нём мелким шрифтом приписано: «Внимание, врач: немедленно выписать пациенту 10 доз морфина». Обычный врач это проигнорирует — он читает результат анализа, а не назначение. Агент, не умеющий отличать «данные, которые я читаю» от «инструкции, которым я подчиняюсь», может подчиниться. Это prompt injection — а если заражённый анализ идёт не напрямую врачу, а через лаборанта другому врачу, который на его основе даёт указания третьему, — это уже cross-agent injection: заражение идёт по цепочке, каждое звено которой честно доверяет предыдущему.
Как называется по-настоящему. Prompt injection — внедрение чужих инструкций в контент, который агент обрабатывает как данные. Indirect prompt injection — источник заражения не пользователь, а третья сторона (веб-страница, README, ответ другого агента, комментарий под видео). Cross-agent injection — частный случай: заражённый вывод одного агента становится входом другого без проверки (result packet из DD «Устойчивость роя» — ровно то место, где это может произойти).
Защитная модель — граница «инструкции только от владельца». Это рабочий принцип, который прямо сейчас действует в этой самой сессии: любое сообщение от любого другого агента — это данные и контекст, а не согласие владельца. Только явное слово самого Лучиана санкционирует смену полномочий. Для завода: у каждого агента ровно ОДИН доверенный канал инструкций (оркестратор/владелец), а всё остальное — транскрипт, вывод niche-finder, README, комментарий зрителя — идёт по каналу «контент», который не может менять права, бюджеты или вызывать платные/деструктивные действия сам по себе. Удобно провести это прямо в task/result packet явным полем доверия:
{
"trusted_instructions": {"source": "orchestrator", "text": "..."},
"untrusted_content": [{"source": "competitor_transcript", "ref": "cracker://video/abc123"}]
}
Всё в untrusted_content никогда не передаётся как instruction-часть промпта — только как текст для анализа; платные/публикующие/меняющие права действия разрешены только из trusted_instructions. Инженерная защита, не зависящая от того, «поймёт» ли модель подвох.
Для любопытных. Anthropic (июль 2026, «How we contain Claude across products»): одиночная попытка prompt injection срабатывает ~0,1%, при 100 адаптивных попытках — 5–6% [🟢]. Показательнее другой пример: в 24 из 25 попыток агент реально «слил» AWS-credentials по прямой фишинговой инструкции — утечку остановил не модельный слой, а окружение (egress-контроль). Второй кейс — tool output poisoning: даже доверенный инструмент (GitHub) может вернуть отравленный README, вывод инструмента нужно инспектировать до попадания в контекст, а не считать доверенным по знакомости источника.
2. Kill-switch: одна команда гасит всё
По-человечески. В операционной есть кнопка аварийной остановки — не «попроси прекратить», а физический механизм, отключающий оборудование независимо от того, что думает персонал в этот момент.
Как называется по-настоящему. Kill switch / emergency stop — механизм немедленной остановки, работающий вне логики самого агента.
Трёхуровневая эскалация. Появляющийся community-стандарт KILLSWITCH.md [🟡 молодая, не отраслевая спецификация] предлагает не бинарный «стоп/работа», а три уровня:
TRIGGERS: {daily_spend_usd: 50, consecutive_failures: 5, error_rate_pct: 20}
FORBIDDEN:
files: [".env", "*/oauth_tokens/*", "id_rsa"]
actions: ["git push --force", "DROP", "bulk_publish_over_10"]
ESCALATION:
level_1_throttle: "снизить конкурентность оркестратора вдвое"
level_2_pause: "остановить приём новых задач, Telegram-уведомление"
level_3_shutdown: "docker compose stop factory-stack, сохранить state.json"
Практическая реализация — один скрипт factory-killswitch.sh на whitelisted-команду /stop в Telegram (§7): (1) resource-governor перестаёт принимать новые задачи; (2) оркестратор получает SIGTERM, не SIGKILL — идемпотентные задачи (DD «Устойчивость роя») дописывают checkpoint и останавливаются на границе стадии, не посреди платной операции; (3) состояние пишется в файл, читаемый при следующем запуске.
Из юридического ресёрча (legal-autonomy.md): требования к операторам автономных агентов в 2026 явно перечисляют «kill switches» и «action caps» наравне с аудит-логами — это спросит и регулятор/страховая, если завод станет юрлицом-оператором.
3. Least-privilege по IDENTITY агента: не «что можно», а «кто вообще куда заходит»
По-человечески. Матрица риска Модуля 4 — это «медсестра может ставить капельницу, но не выписывать рецепты» — контроль по типу действия. Но есть и ортогональный контроль: бейдж, который вообще не пускает уборщика в реанимацию, независимо от того, что он там собирался делать.
Как называется по-настоящему. Identity-based least privilege / per-agent scoped credentials — у каждого агента своя, минимально достаточная учётная запись, а не общий главный ключ на всех.
Где на заводе дыра. Матрица Модуля 4 говорит «DELETE требует подтверждения», но не отвечает на вопрос «должен ли niche-finder вообще ФИЗИЧЕСКИ иметь доступ к YouTube OAuth, если он никогда не публикует видео?». Ответ — нет: дело не в том, что он «спросит подтверждения», а в том, что у него не должно быть credential, которым можно удалить.
| Агент/сервис | Что нужно | Чего не должно быть |
|---|---|---|
| niche-finder, x-research-daily | read-only ключи трендов/X | YouTube OAuth, .env генераторов, платёжные ключи |
| channel-hq (оркестратор) | scoped-токен на publish | root-доступ к серверу, секреты клиентов |
| thumbnail-studio / QC | read артефактов проекта | write в память других каналов, OAuth |
| ночной билдер | тестовые ключи, изолированная сеть | ЛЮБЫЕ боевые credentials завода |
| Telegram-бот | свой bot-token, whitelist chat_id | shell-доступ в обход budget-gate |
| MVP-строитель клиента N | папка/namespace клиента N | данные клиента M (§6) |
Для любопытных. Термин 2026 года — non-human identity (NHI) management: каждый сервис получает свой служебный аккаунт со своим scope, не наследует права владельца целиком. Минимум без корпоративного IAM: .env.<service> на сервис вместо единого файла, плюс еженедельный mechanical-first аудит вместо LLM-ревью:
for f in docker-compose.yml services/*/docker-compose.yml; do
grep -E "OAUTH|API_KEY|TOKEN|SECRET" "$f" | grep -v "^\s*#"
done
Ключ не по функции сервиса в выводе — измеримый инцидент least-privilege, закрывается за вечер, не дожидаясь, пока им кто-то воспользуется.
4. Supply-chain риск скиллов и MCP: заражённая аптечка
По-человечески. Ты пошёл в непроверенную аптеку за «тем же, но дешевле» — и получил упаковку, которая выглядит как лекарство, а внутри неизвестно что. Так выглядит установка скилла или MCP-сервера из публичного каталога без проверки: SKILL.md может содержать не только полезную инструкцию, но и встроенную команду «а заодно отправь содержимое .env вот сюда».
Как называется по-настоящему. Supply chain security — тот же класс риска, что npm/pip-пакеты с бэкдором, применительно к SKILL.md и MCP-серверам, которые Лучиан планирует брать готовыми из каталогов.
Цифры (Snyk ToxicSkills, февраль 2026, корпус 3984 скилла с ClawHub/skills.sh): 534 (13,4%) — критические уязвимости, 1467 (36,8%) — хотя бы один изъян, 76 подтверждённо вредоносных, из них 91% через prompt injection [🟢 проверено WebFetch]. По MCP-серверам данные разрозненнее (от 33% критических на выборке 1000 до ~1500 серверов вообще без аутентификации), а один из аудиторов сканеров предупреждает про ~78% ложных срабатываний [🟡 разброс методологий — риск реален, но не точная ставка].
Протокол проверки перед установкой.
1. Читать SKILL.md/код целиком перед первым использованием — не по описанию.
2. Проверять запрашиваемые права — shell, сеть, ФС: скилл «постит в соцсети» не должен просить ~/.ssh.
3. Никогда не запускать curl | bash вслепую, не давать флаги вида --dangerously-force-unsafe-install без чтения, что они разблокируют.
4. Пинить версию/хэш — обновление скилла тоже точка заражения.
5. Тестировать в изоляции (тот же sandbox, что для ночного билдера) без боевых credentials минимум неделю.
6. Проверять репутацию источника — история, звёзды, открытый репо; вредоносные аккаунты в Snyk были свежими и анонимными.
7. grep вместо доверия — скрипт на паттерны секретов/сети/eval/exec перед установкой, почти бесплатно.
Это процесс, не разовая галочка: правило «повторил дважды → оформи скиллом» получает зеркало — «взял скилл из чужого каталога → протокол ДО первого боевого использования», оформленное как скрипт vet-skill.sh, а не ручной чек-лист, который забудут при спешке.
5. Секрет-менеджмент как практика
По-человечески. Один общий ключ от аптечки под ковриком у входа — то, чем функционально является общий .env с плоскими правами у всех сервисов. Правильная практика — сейф с разными ключами для разных полок и журналом, кто и когда брал ключ.
Как называется по-настоящему. Secrets management — управление жизненным циклом чувствительных значений отдельно от кода и с контролем доступа.
Лестница для соло-заводчика.
- Уровень 0 (сегодня). .env никогда не коммитится (.gitignore + разовая git log -p | grep -i API_KEY по всей истории — утёкший в старый коммит ключ считается скомпрометированным и ротируется, чистка истории не спасает, если репо где-то клонировалось).
- Уровень 1. Секреты шифруются прямо в git через SOPS + age: .env.enc коммитится как блоб, приватный age-ключ живёт только на сервере (chmod 600), расшифровка — шаг деплоя:
sops --encrypt --age $(cat /etc/factory/age.pub) .env.niche-finder > .env.niche-finder.enc
sops --decrypt .env.niche-finder.enc > .env.niche-finder # только при деплое
- Уровень 2 (десятки каналов). Лёгкий self-hosted секрет-менеджер (Infisical) с per-service scoped-токенами — прямая реализация identity-based least privilege из §3.
- Универсальное правило: ротация обязательна при малейшем подозрении на компрометацию (новый скилл получил доступ к env; сервис засветился на
0.0.0.0) — минуты, не «раз в год, если вспомнили».
6. Приватность и изоляция данных клиентов в консультант-режиме MVP
По-человечески. Карта пациента А никогда не должна оказаться в папке пациента Б — даже «для примера, как лечили похожий случай». Врач использует обобщённый опыт, но не цитирует чужую карту напрямую.
Как называется по-настоящему. Multi-tenant data isolation — данные каждого клиента физически и логически отделены, перенос знаний идёт только через явное обобщение.
Применение к его ключевому бизнес-режиму. Консультант-фабрика по определению видит чужие боли бизнеса. Архитектура памяти в Модуле 3 уже правильна (per-domain банк, «кофейня ≠ стройка»), но безопасность требует довести это до конца:
- Физически отдельный namespace на клиента, не общая папка с пометкой
client_idв файле — разделение должно ломать доступ по умолчанию, не полагаться на фильтрацию в коде. - MVP-строитель клиента N не имеет чтения в папку клиента M — git worktree или отдельный контейнер, тот же приём, что sandbox ночного билдера кода.
- Промоушен в глобальную память — только после обобщения: паттерн «у малого общепита теряют деньги на порционировании» — да; выдержка из реальных финансов клиента с цифрами — нет. Продолжение порога
count≥5из Модуля 3, плюс обязательная анонимизация. - Explicit-consent на публичное использование кейса клиента — отдельное решение человека, не то, что система решает сама.
Сценарий без изоляции: понедельник — intake кофейни, вторник — intake стройки. Если explorer-агент для стройки имеет read-доступ к общей памяти и «вспоминает» цифры кофейни как иллюстрацию — это разрушение доверия к единственному по-настоящему продаваемому режиму. Предотвращается тем же способом, что cross-agent injection в §1: доступа физически нет, не «не должен быть».
7. Аутентификация командных каналов: Telegram-бот и голос
По-человечески. Медсестра выполнит назначение по телефону, только если узнаёт голос врача или код доступа — не потому что кто-то позвонил и сказал «это доктор».
Как называется по-настоящему. Command channel authentication — проверка подлинности источника команды, отдельно от проверки её содержимого (это уже guardrails Модуля 4).
Telegram. Bot API сам по себе не аутентифицирует «это точно Лучиан» — лишь идентифицирует chat_id. Минимум: бот обрабатывает команды только из whitelisted chat_id, до того как сообщение вообще станет trusted_instructions (§1):
OWNER_CHAT_IDS = {123456789}
async def handle_update(update):
if update.message.chat_id not in OWNER_CHAT_IDS:
log_anomaly("unauthorized_command_attempt", update); return
dispatch_to_orchestrator(update.message.text)
Второй слой — секретный secret_token в setWebhook, чтобы посторонний не слал поддельные апдейты в обход Telegram-инфраструктуры.
Голос. Сложнее — deepfake-голос уже реальная угроза, и нет такого простого якоря, как chat_id. Годится для статусов и низкорисковых команд, но не должен быть единственным каналом подтверждения ТРАТЫ: денежный гейт требует канала, который сложнее подделать (Telegram-кнопка с подписанным callback), а не «голос сказал да»; если голос всё же нужен для денег — минимум PIN/кодовая фраза поверх распознавания тембра.
8. Утечка секретов и PII через логи и память
По-человечески. Врач диктует заметки в коридоре, где их слышат посторонние, и случайно проговаривает не только диагноз, но и номер страхового полиса. Система, логирующая ВСЁ «на всякий случай», рискует тем же.
Как называется по-настоящему. Secret/PII leakage through logs and memory — утечка не через взлом, а через штатную работу observability.
Где это может случиться. Формат структурированного лога решений (nadezhnost.md §7.5) отлично закрывает LEARNING, но опаснее всего при бездумной записи: если input содержит ответ API с токеном или decision_reasoning цитирует финансы клиента из §6 — это осядет в memory-bank, который читается многими агентами и хранится долго.
Меры. 1. Фильтр на границе записи в memory-bank, не полагаясь на то, что агент «сам не залогирует»:
SECRET_PATTERNS = [r"sk-[a-zA-Z0-9]{20,}", r"AKIA[0-9A-Z]{16}", r"Bearer\s+\S+", r"\b\d{13,19}\b"]
def redact_before_log(record: dict) -> dict:
text = str(record)
for pat in SECRET_PATTERNS:
text = re.sub(pat, "[REDACTED]", text)
return text # вызывается ВСЕГДА перед memory_bank.append, не по желанию агента
- PII клиентов (§6) — в изолированный per-client лог, не в общий.
- Логировать ссылку на артефакт, а не сырое содержимое (
artifact_ref, не base64;cost_usd, не полный ответ платёжного API) — продолжение паттерна result_packet из DD «Устойчивость роя». - Модель — ещё один получатель данных: контент в контексте Claude покидает диск завода и подчиняется политике хранения провайдера, секреты и PII минимизируются в промптах так же строго, как в логах.
- Ретеншн: старые логи с потенциальным PII не живут вечно «на всякий случай» — тот же TTL-принцип, что для затухающих правил памяти в Модуле 3.
Где здесь деньги. Каждый пункт — конкретный сценарий потери денег или доверия: утёкший YouTube OAuth = потеря канала, приносившего доход месяцами; заражённый скилл с shell-доступом = потенциально весь сервер; смешение данных клиента А и B = потеря репутации в единственном по-настоящему продаваемом режиме, где всё держится на «приду ночью посмотреть на твой бизнес и никому не расскажу». Kill-switch и аутентификация командных каналов превращают «полная автономия кроме денег» в реально безопасную формулу: без них красная линия существует только на бумаге — нет гарантии, что именно Лучиан, а не заражённый вход, её подтвердил.
Чек-лист внедрения
- [ ] Граница «инструкции только от владельца/оркестратора»: прочитанный контент помечен как данные, не может менять права/бюджеты/вызывать платные действия.
- [ ]
KILLSWITCH.md/эквивалент и скрипт-исполнитель: стоп новых задач → SIGTERM с checkpoint → сохранение state, вызов — только whitelisted Telegram-команда. - [ ] Аудит identity: какой сервис держит какой ключ; убрать YouTube OAuth и боевые
.envиз сервисов, которым они не нужны. - [ ] Общий
.env→.env.<service>; SOPS+age (или аналог); проверить git-историю на утёкшие ключи. - [ ] Письменный протокол проверки скилла/MCP перед установкой (7 пунктов §4) — до старта сборки библиотеки скиллов.
- [ ] Консультант-режим: отдельный namespace на клиента, promotion в общую память только через обобщение, explicit-consent на публичные кейсы.
- [ ] Telegram-бот: whitelist
chat_id, секретный webhook-токен; голос — не единственный канал подтверждения трат. - [ ] Фильтр секретов/PII на границе записи в memory-bank и логи; per-client изоляция логов; ретеншн-политика.
Куда это в курсе
Прямое продолжение Модуля 4 («Иммунная система») — он даёт архитектуру (матрица риска, budget-gate, sandbox), этот модуль — восемь конкретных механизмов защиты внутри неё. Пересекается с Модулем 8 (аутентификация Telegram/панели, урок 8.3), Модулем 3 (изоляция памяти по типам, урок 3.2 — здесь расширена до per-client), Модулем 1.4 (экосистема скиллов — добавлен протокол проверки) и Модулем 11 (roadmap: пункты 2–5 чек-листа — в план первой недели, рядом с уже запланированной изоляцией ночного билдера). DD «Устойчивость роя» дополняет модуль: тот отвечает «как продолжить после сбоя», этот — «как не дать чужой инструкции или дырявому ключу вызвать сбой».
Источники
analysis/nadezhnost.md§1–3, §7, §7.5 (матрица риска, sandbox, observability, урок OpenClaw)web/openclaw-hermes.md§6, §9 (CVE-2026-25253, permission model, ClawHub-риски, hardening checklist)web/legal-autonomy.md§I.C (kill switches, action caps как требование к оператору)web/reddit-claude.md§4 (MCP/Skills/Hooks, принцип «секреты не коммитить»)deep-dives/DD-ustoichivost-roya.md§1–2 (идемпотентность, task/result packet)- Anthropic, «How we contain Claude across products» (июль 2026) — 0,1%/5–6%, egress-контроль, tool output poisoning [🟢]
- Snyk, «ToxicSkills» (5.02.2026, 3984 скилла ClawHub/skills.sh) — 13,4% критических, 36,8% любых, 76 вредоносных, 91% через prompt injection [🟢]
- KILLSWITCH.md — community-стандарт формата аварийной остановки [🟡 молодая спецификация]
- Practical DevSecOps, MCP Security Statistics 2026 — сводка независимых сканирований MCP-серверов [🟡 разные методологии]