Когда 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 и сравнивает с дайджестом хранящегося значения. Совпадение → запись выполняется. Несоответствие → отклонено, зафиксировано в аудите.
Модель проста, но закрывает три поверхности атаки:
- Скрытая ротация: агент без предварительного доступа к
$OLDне может заменить его своим значением. - Утечка через зондирование: ответ с дайджестом никогда не содержит открытый текст; даже скомпрометированный журнал аудита показывает
expected abc12345…, got deadbeef…, не базовые значения. - Случайная перезапись конфигурации пользователя: требует намеренного
--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='*' в середине сессии. Только родительский процесс (вы, в своём терминале, перед запуском агента) может открыть эту дверь.
Поддержка платформ: переопределения только для Linux
REDIACC_ALLOW_CONFIG_EDIT и REDIACC_ALLOW_GRAND_REPO оба полагаются на проверку цепочки предков, чтобы доказать, что переопределение установлено вами, а не внедрено агентом. Проверка читает /proc/<pid>/environ для каждого процесса вверх по цепочке. Этот файл устанавливается ядром во время exec и не может быть изменён самим процессом, поэтому окружение родительской оболочки является доказательством, защищённым от подделки.
Этот файл не существует в macOS или Windows. Без возможности проверить легитимность CLI отказывает по умолчанию. Даже если вы корректно установите переопределение в своей оболочке перед запуском агента, переопределение будет отклонено. Сообщение об ошибке точно говорит, что делать:
The REDIACC_ALLOW_GRAND_REPO override is not supported on darwin. This override only works on Linux. On Windows and macOS, agents must use the fork-first workflow. … To use the override, run your agent on Linux (directly, WSL, Docker, or a VM).
На практике у пользователей не на Linux нет эвакуационного люка из подхода «сначала форк». Это сделано намеренно. Агенты проталкиваются через песочницу, обойти которую они не могут, независимо от того, как их попросили. Запускайте своего агента внутри WSL, Linux-контейнера или Linux-VM, если вам нужно переопределение; иначе работайте с форком.
Журнал аудита
Каждое изменение, каждый отказ, каждое разрешение --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 не совпадает по хэшу с хранящимися данными. Сервер никогда не видит открытый текст: нулевое знание: но шлюз применяется принудительно.
Путь локального файла: «лёгкий путь безопасен». Путь удалённого хранилища: «трудный путь тоже труден».
Что Rediacc не изолирует
Защитные ограничения агента на этой странице защищают собственную инфраструктуру Rediacc: файл конфигурации, Docker-демон каждого репозитория, LUKS-зашифрованные данные репозитория, ограниченную SSH-песочницу. Они не защищают внешние сервисы, для которых ваш репозиторий хранит учётные данные.
Форк репозитория это BTRFS reflink тома родителя. Всё, что хранится на диске у родителя, побайтово идентично в форке: код, данные и .env файлы одинаково. Если ваш репозиторий содержит STRIPE_LIVE_KEY, AWS_ACCESS_KEY_ID, токен Railway API или любые другие долгоживущие учётные данные для стороннего сервиса, форк наследует их. Агент, работающий в песочнице форка, может прочитать этот файл, экспортировать значение или использовать его для вызовов стороннего API. У стороннего сервиса нет способа узнать, что вызов пришёл из форка, а не из продакшн.
Это линия разделения ответственности:
| Граница | Владелец |
|---|---|
| Данные репозитория, пространство имён монтирования, область Docker, защитные ограничения агента, журнал аудита | Rediacc |
| Радиус поражения внешних сервисов (Stripe, AWS, Railway, GitHub и т. д.) | Разработчик репозитория |
Три шаблона закрывают разрыв со стороны разработчика:
- Не храните продакшн-учётные данные внешних сервисов в репозитории вообще. Получайте их из внешнего менеджера секретов (HashiCorp Vault, AWS Secrets Manager, 1Password Connect) при запуске контейнера. Контейнеры форка по построению получат учётные данные с областью песочницы, потому что идентифицируют себя по-другому.
- Удаляйте или подменяйте учётные данные во время форка через хук
up()в Rediaccfile.up()форка выполняется с другим GUID репозитория, чем у родителя. Обнаружьте это, затем перепишите.envсо значениями песочницы, подготовьте Stripe sandbox-аккаунт для каждого форка, направьте строки подключения к базе данных на тестовый экземпляр для каждого форка и так далее. См. Сервисы для справки по хукам жизненного цикла. - Ограничьте исходящий сетевой трафик форка с помощью eBPF egress-фильтрации, чтобы форк мог достигать только localhost и явно указанных конечных точек песочницы. Сетевая изоляция Rediacc для каждого репозитория является основой; allowlist для исходящего трафика для каждого форка пока не построен, но путь открыт.
Rediacc обрабатывает инфраструктурную половину безопасности агентов. Половина внешних сервисов живёт в вашем Rediaccfile.
Быстрые рецепты
Разрешить агенту ротацию одного облачного токена
# Под вашей учётной записью, перед запуском агента:
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-конверт на стороне сервера.
Смотрите также
- Обзор интеграции AI-агентов: общий тур
- Настройка Claude Code: шаблон интеграции
- Конверт JSON-вывода: машиночитаемые ответы
- Зашифрованное хранилище конфигурации: криптографическое исполнение на стороне сервера
- Безопасность аккаунта: позиция безопасности оператора