Перейти к основному содержанию Перейти к навигации Перейти к нижнему колонтитулу

Безопасность и ограничения AI-агентов

Как CLI Rediacc предотвращает утечку секретов, перезапись учётных данных и повышение привилегий AI-ассистентами кодирования: шлюзы знаний, редактирование, переопределения с проверкой цепочки предков и журнал аудита с хэш-связыванием.

Когда Claude Code, Cursor, Gemini CLI, Copilot CLI или любой другой AI-ассистент кодирования управляет rdc, CLI обращается с ним иначе, чем с человеком за клавиатурой. На этой странице объясняется, что агент может делать, что не может, и как защитные ограничения удерживаются даже тогда, когда агент пытается их обойти.

Краткий справочник: что агенты могут и не могут делать

ОперацияПоведение агента по умолчаниюКак разблокировать для конкретного случая
rdc config show (с редактированием)✅ allowed
rdc config field get --pointer <pointer> (заглушка или дайджест)✅ allowed
rdc config field get --pointer <pointer> --digest✅ allowed
rdc config field set --pointer <pointer> (публичное поле)✅ allowed
rdc config field set --pointer <pointer> (чувствительное поле, с корректным --current)✅ allowed
rdc config edit --dump (редактированный JSONC)✅ allowed
rdc config audit {log, tail, verify}✅ allowed
rdc config field set --pointer <pointer> (чувствительное поле, без --current)🔴 refusedУказать --current "<старое значение>"
rdc config field get --pointer <pointer> --reveal🔴 refusedИспользовать --digest вместо этого
rdc config show --reveal🔴 refusedИспользовать простой rdc config show
rdc config edit (интерактивный редактор)🔴 refusedЧеловек устанавливает REDIACC_ALLOW_CONFIG_EDIT=* перед запуском агента
rdc config edit --apply <file>🔴 refusedТо же переопределение
rdc config field rotate --pointer <pointer>🔴 refusedТо же переопределение; использует интерактивное подтверждение
rdc term connect -m <machine> (прямой SSH на машину)🔴 refusedСначала сделать форк репозитория и подключиться к форку

Всё, в чём агенту отказывается, записывается в журнал аудита с outcome: refused и причиной.

Как агенты обнаруживаются

CLI считает процесс агентом, если выполняется хотя бы одно из условий:

  • Одна из переменных REDIACC_AGENT, CLAUDECODE, GEMINI_CLI, COPILOT_CLI установлена в "1", или CURSOR_TRACE_ID установлена вообще.
  • На Linux: любой родительский процесс в цепочке предков имеет одну из этих переменных в своём окружении (через /proc/<pid>/environ). Даже если агент удалит свои переменные с помощью env -i или скрипта-обёртки, родительская цепочка всё равно сообщит CLI, кто его запустил.

Обнаружение выполняется один раз на процесс и кэшируется. Его нельзя отключить.

Модель шлюза знаний

Чувствительные изменения следуют соглашению passwd(1): чтобы изменить секрет, докажите, что вы его уже знали.

  • Хотите ротировать токен API, хранящийся в /credentials/cfDnsApiToken?
  • CLI спрашивает: «какое текущее значение?»
  • Агент предоставляет открытый текст через --current "$OLD". CLI хэширует $OLD с помощью SHA-256 и сравнивает с дайджестом хранящегося значения. Совпадение → запись выполняется. Несоответствие → отклонено, зафиксировано в аудите.

Модель проста, но закрывает три поверхности атаки:

  1. Скрытая ротация: агент без предварительного доступа к $OLD не может заменить его своим значением.
  2. Утечка через зондирование: ответ с дайджестом никогда не содержит открытый текст; даже скомпрометированный журнал аудита показывает expected abc12345…, got deadbeef…, не базовые значения.
  3. Случайная перезапись конфигурации пользователя: требует намеренного --current каждый раз; нет автоматической перезаписи при set.

Практический пример

# Получить короткий дайджест заглушки редактирования (безопасно для агентов).
$ rdc config field get --pointer /credentials/cfDnsApiToken
{"pointer": "/credentials/cfDnsApiToken", "value": "<redacted:secret>:abc12345"}

# Попытка перезаписи без доказательства: отклонено.
$ rdc config field set --pointer /credentials/cfDnsApiToken --new '"agent-picked-value"'
 Precondition failed: sensitive path requires --current (or --rotate-secret)

# Предоставить текущий открытый текст: разрешено.
$ rdc config field set --pointer /credentials/cfDnsApiToken \
    --current "$OLD_CF_TOKEN" \
    --new   "$NEW_CF_TOKEN"
Set /credentials/cfDnsApiToken

Если у агента никогда не было $OLD_CF_TOKEN, он не может выполнить предусловие, и ротация отклоняется. Пользователь, у которого есть токен, по-прежнему может это сделать через редактор или передав --current из своей оболочки.

Редактирование по умолчанию

Каждая команда rdc, которая читает чувствительное состояние: config show, config field get, config machine list, config edit --dump: возвращает заглушки редактирования для секретных полей, не открытый текст:

"sshKey":       "<redacted:credential>:9f3a2c1b"
"cfDnsApiToken":"<redacted:secret>:abc12345"
"storages.s3-prod.vaultContent": "<redacted:secret>:1f2e3d4c"

8-символьный шестнадцатеричный суффикс заглушки: это первые 8 символов sha256(canonicalize(value)): достаточно для различения двух разных значений с первого взгляда, недостаточно для обратного вычисления. Агент может использовать заглушку для отслеживания изменения значения, не видя его никогда.

--reveal снимает редактирование для людей на интерактивном TTY. Агентам отказывается независимо от состояния TTY. Каждое разрешение записывает запись аудита reveal_granted; каждый отказ записывает запись refused с прикреплёнными сигналами агента субъекта.

Переопределение REDIACC_ALLOW_CONFIG_EDIT

Некоторые операции: интерактивный редактор, --apply, field rotate: существуют для людей и не имеют безопасного пути для агентов. Если вы активно хотите, чтобы агент выполнил одну из них, вы устанавливаете:

export REDIACC_ALLOW_CONFIG_EDIT='*'          # полный обход
# или
export REDIACC_ALLOW_CONFIG_EDIT='/credentials/ssh/privateKey,/infra/cfDnsZoneId'
# (глобы области через запятую: подстановочные символы * допустимы на сегмент)

…и агент это наследует.

Важная деталь: переопределение должно появляться в процессе выше агента в цепочке предков. Если агент установит его в своём собственном окружении (или в порождённой им подоболочке), CLI откажет и сообщит об этом:

Interactive editor is blocked in agent environments (REDIACC_ALLOW_CONFIG_EDIT was set but ancestry verification failed: the override must be set by your shell, not by an agent).

Эффект: агент не может обойти ограничение, запустив export REDIACC_ALLOW_CONFIG_EDIT='*' в середине сессии. Только родительский процесс (вы, в своём терминале, перед запуском агента) может открыть эту дверь.

Журнал аудита

Каждое изменение, каждый отказ, каждое разрешение --reveal записывает строку JSONL в ~/.config/rediacc/audit.log.jsonl (режим 0600, ротация при 10 МБ). Каждая строка связана хэшем: поле prevHash равно sha256("<предыдущая строка>"). Изменение любой строки разрывает цепочку во всех последующих строках.

{"ts":"2026-04-21T10:02:47.831Z","actor":{"kind":"agent","agentSignals":["CLAUDECODE"]},"command":"config field set","paths":["/credentials/cfDnsApiToken"],"outcome":"ok","configId":"...","configVersion":48,"prevHash":"sha256:9f3a..."}
{"ts":"2026-04-21T10:02:51.114Z","actor":{"kind":"agent","agentSignals":["CLAUDECODE"]},"command":"config edit","paths":[],"outcome":"refused","reason":"agent without REDIACC_ALLOW_CONFIG_EDIT=*","prevHash":"sha256:abc1..."}
{"ts":"2026-04-21T10:03:05.220Z","actor":{"kind":"human"},"command":"config show --reveal","paths":[],"outcome":"reveal_granted","configId":"...","configVersion":48,"prevHash":"sha256:deac..."}

Просмотр

# Список последних записей
rdc config audit log --since 24h

# Фильтр по глобу указателя
rdc config audit log --path '/credentials/*'

# Только записи от агентов
rdc config audit log --actor agent

# Потоковая трансляция новых записей в реальном времени (Ctrl+C для остановки)
rdc config audit tail

# Проверка целостности хэш-цепочки
rdc config audit verify
# → "Chain integrity verified across 247 entries."
#   ИЛИ
# → "Chain broken at line 103: file has been tampered with or corrupted."

Что никогда не появляется в журнале аудита

  • Открытый текст секретных значений
  • Парольные фразы, токены, SSH-ключи
  • Старые/новые значения при несоответствии предусловия --current (только 8-символьный префикс дайджеста)

Журнал можно безопасно передать проверяющему безопасности или прикрепить к отчёту об ошибке.

Ограничения поведенческой модели

Ограничения агента являются поведенческими, а не криптографическими. Решительный или специально настроенный агент, работающий с тем же UID, что и файл конфигурации, всегда может выполнить cat ~/.config/rediacc/rediacc.json и прочитать открытый текст, поскольку файл доступен для чтения процессом.

Для настоящего криптографического контроля используйте зашифрованное хранилище конфигурации: секреты хранятся на стороне сервера, каждое чувствительное поле несёт HMAC-обязательство на уровне поля, а воркер аккаунта отклоняет записи, чьё предусловие --current не совпадает по хэшу с хранящимися данными. Сервер никогда не видит открытый текст: нулевое знание: но шлюз применяется принудительно.

Путь локального файла: «лёгкий путь безопасен». Путь удалённого хранилища: «трудный путь тоже труден».

Быстрые рецепты

Разрешить агенту ротацию одного облачного токена

# Под вашей учётной записью, перед запуском агента:
export REDIACC_ALLOW_CONFIG_EDIT='/credentials/cfDnsApiToken'
claude-code              # или cursor, gemini и т. д.

Теперь агент может выполнить config field rotate /credentials/cfDnsApiToken --new …, но по-прежнему не может редактировать /credentials/ssh/privateKey или открыть интерактивный редактор.

Разрешить агенту широкую сессию редактирования конфигурации

export REDIACC_ALLOW_CONFIG_EDIT='*'
claude-code

Агент может открыть rdc config edit, использовать --reveal и запустить field rotate. Каждое действие по-прежнему записывается в журнал аудита с actor.kind: agent и сигналом CLAUDECODE.

Узнать, какие поля агент может трогать

rdc config field list --sensitive --output json

Возвращает каждый шаблон указателя, его тип (secret / credential / pii / identifier) и входит ли он в HMAC-конверт на стороне сервера.

Смотрите также