# AI-агенты под управлением подрядчиков: как корректно закрыть production-доступ

Подрядчик может отлично работать с AI-агентом для программирования и всё равно оставить вашу production-среду в худшем состоянии, чем она была до этого. Обычно проблема начинается не со злонамеренного запроса. Она начинается, когда все считают, что кто-то другой отвечает за процесс агента, одобрения и очистку доступа.

Относитесь к агенту, которым управляет подрядчик, как к временному оператору production-системы. Назначьте ему ответственного внутреннего спонсора, понятный идентификатор процесса, узкий набор полномочий и процедуру удаления доступа, которую кто-то уже отработал. Если вы не можете назвать сотрудника, способного остановить агент сегодня, вы не делегировали работу. Вы создали бесхозный процесс.

## Идентификатор подрядчика не может владеть production-агентом

Компания, которой принадлежит production-система, должна владеть полномочиями агента, даже если процесс запускает и контролирует подрядчик. Трудовые отношения подрядчика, личная учётная запись, ноутбук и приглашение в календаре заканчиваются на условиях, которые вы не контролируете напрямую. Production-доступ не может зависеть от чего-либо из этого списка.

Команды часто смешивают два вопроса:

- Кто управляет агентом во время этой работы?
- Кто по-прежнему отвечает за все возможности, которые получил агент?

На первый вопрос может ответить подрядчик. На второй должен ответить внутренний сотрудник. У него должно быть достаточно полномочий, чтобы приостановить работу, изменить её границы, проверить записи и закрыть доступ без ожидания ответа подрядчика.

Я видел, как это происходит в самой обычной ситуации. Подрядчик получает приглашение в репозиторий с исходным кодом и production-токен API, потому что ему нужно разобраться с проблемой. Он запускает агент на своём компьютере, изучает код, обращается к API и готовит исправление. Договор заканчивается, учётную запись подрядчика в репозитории отключают, и всем кажется, что работа завершена. Через несколько недель в автоматическом профиле терминала всё ещё лежит токен. В старом рабочем каталоге агента остаются инструкции по его использованию. Компания удалила человека из одной системы, но не убрала operational-путь к production.

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

Это не бюрократия ради бюрократии. Такой подход предотвращает самый дорогой вид неопределённости: инцидент, во время которого команда не может понять, пришёл ли запрос от одобренного агента, старой настройки подрядчика или злоумышленника, повторно использующего забытый доступ.

## Назначьте одного сотрудника ответственным за делегирование

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

До выдачи production-полномочий спонсор должен ответить на четыре конкретных вопроса. Какую задачу выполняет агент? К какой среде он может обращаться? Какие действия входят в задачу? Когда разрешение прекращается?

Избегайте расплывчатых формулировок вроде «помогать обслуживать сервис» или «помогать с развёртыванием». Такие фразы становятся опасными, когда агент может интерпретировать их через инструменты. Описывайте работу наблюдаемыми действиями: проверить ответы с ошибками от этого сервиса, открыть pull request, выполнить указанную диагностическую команду или отправить запрос на изменение для конкретного endpoint.

Спонсору не нужно весь день сидеть рядом с подрядчиком. Но он должен отвечать за границы. Если подрядчик говорит, что теперь нужны запись в базу данных, новая инфраструктурная роль или доступ к другому сервису, это новое решение о делегировании. Не позволяйте прежнему одобрению незаметно растягиваться под новый запрос.

В публикации NIST Special Publication 800-207 о zero trust есть полезная мысль: системы не должны автоматически доверять субъекту только потому, что он находится в определённой сети или раньше обращался к ресурсу. Применяйте тот же принцип к работе агента. Нахождение подрядчика в вашем чате или VPN, а также прежнее одобрение операции чтения не разрешают другому процессу выполнить запись в production.

Здесь команды часто выбирают неправильное упрощение. Они выдают подрядчику широкий постоянный доступ, потому что повторные одобрения кажутся медленными. Они кажутся медленными, потому что работа была определена недостаточно точно. Сначала исправьте границы работы. Широкий постоянный доступ превращает проблему планирования в проблему реагирования на инцидент.

Дайте спонсору явную замену. Если он уходит, передайте запись о работе новому спонсору и заново одобрите полномочия. Процесс без действующего спонсора должен автоматически потерять доступ или быть сразу отключён вручную. Нет законной причины оставлять production-полномочия у работы подрядчика, которой никто не управляет.

## Происхождение процесса должно входить в каждое одобрение

Одобрение человека отличается от одобрения процесса. Эту разницу часто стирают, и в результате одобрение охватывает больше программ, чем предполагал проверяющий.

Идентификатор человека показывает, кто прошёл аутентификацию. Идентификатор процесса показывает, какой исполняемый файл запросил действие, где он работал и соответствует ли он ожидаемому процессу. Когда AI-агент работает через оболочки, расширения, MCP-серверы, фоновые помощники и скрипты, именно процесс фактически получает доступ к пути учётных данных.

Требуйте подтверждение того, что новый процесс агента является одобренным процессом. В macOS полномочия подписи кода дают проверяющему полезную отправную точку. Они позволяют определить полномочия подписи, предъявленные исполняемым файлом. Но они не доказывают, что production-запрос относится к работе конкретного подрядчика, и не решают, разумно ли запрошенное действие. Используйте подпись как сведения о процессе, а не как безусловное разрешение.

Практическая карточка одобрения должна показывать больше, чем отображаемое имя подрядчика. В ней нужно указать процесс или средство запуска, полномочия подписи кода, если они доступны, текущую работу, целевую среду и запрошенную возможность. Если проверяющий не может отличить известный процесс агента от скопированного скрипта, одобрение слишком слабое.

Так обнаруживается распространённая проблема. Подрядчик запускает одобренный агент для программирования в одном терминале. Позже shell-скрипт или другой процесс агента наследует переменные среды, читает локальный конфигурационный файл и выполняет тот же запрос с теми же учётными данными. Одобрение только человека не показывает, что вызывающие процессы разные. Второй процесс может быть безвредным, но этого никто не установил.

Правильный ответ не в том, чтобы требовать от проверяющих невозможной уверенности. Нужно уменьшить объём, который охватывает одно одобрение. Привязывайте одобрения к сеансу или запуску процесса, ясно идентифицируйте этот запуск и завершайте одобрение, когда запуск заканчивается. Новый процесс должен представиться заново.

Храните локальную запись о команде запуска процесса, рабочем каталоге, времени запуска, спонсоре и ожидаемом условии завершения. Не нужно собирать каждый личный запрос или каждый файл, который читает подрядчик. Нужно достаточно operational-сведений, чтобы ответить на простой вопрос при инциденте: какой одобренный процесс выполнил действие, под чьими полномочиями и оставался ли он в пределах назначенной работы?

## Владелец одобрения должен соответствовать масштабу последствий

Человек, одобряющий действие агента, должен соответствовать возможным последствиям этого действия. Подрядчик может одобрять обычные действия в рамках делегированной узкой задачи. Он не должен незаметно становиться окончательным распорядителем действий, способных изменить production-данные, разрешения, сообщения клиентам или инфраструктуру.

Разделите одобрение на два уровня. Спонсор разрешает категорию работы и её продолжительность. Владелец одобрения действия разрешает конкретную операцию, когда её влияние требует решения человека. В небольшой команде один сотрудник может выполнять обе роли. Всё равно храните их раздельно, потому что позже они отвечают на разные вопросы.

Используйте простую модель ответственности:

- Спонсор отвечает за цель, границы и срок работы.
- Оператор-подрядчик отвечает за качество задачи и запрашивает действия в рамках разрешённых границ.
- Владелец одобрения действия решает, разрешать ли чувствительный вызов.
- Технический хранитель отвечает за путь к учётным данным и процедуру остановки.
- Служба безопасности или эксплуатации проверяет, что отзыв завершён.

Не устраивайте процедуру одобрения для каждого безобидного чтения только ради формального контроля со стороны человека. Проверяющие начнут автоматически подтверждать запросы и пропустят тот, который действительно требует внимания. Добавляйте трение там, где действие меняет состояние, расширяет полномочия, раскрывает ограниченные данные или обращается к новой production-цели.

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

На экране одобрения также должна быть указана цель. Формулировка «Разрешить агенту использовать API» почти ничего не говорит проверяющему. Формулировка «Разрешить этому одобренному процессу отправить POST-запрос к production-endpoint биллинга» превращает запрос в решение, за которое можно отвечать. Проверяющий всё ещё может отклонить его, запросить change request или потребовать использовать staging.

Усталость от одобрений говорит о плохом дизайне, а не о том, что одобрения нужно отменить. Если очередь превращается в шум, ограничьте инструменты, объедините безопасные операции в короткий сеанс или перенесите расследование в непроизводственную среду. Не решайте проблему постоянными production-полномочиями.

## Не помещайте учётные данные в контекст агента

Агент должен запрашивать действие, а не хранить секрет, который его разрешает. Именно это делает отключение доступа после окончания работы выполнимым.

Если агент подрядчика получает API-токен в открытом виде, закрытый SSH-ключ или скопированный секрет в конфигурационном файле, вы уже потеряли контроль над тем, куда может попасть эта учётная информация. Токен может оказаться в истории терминала, памяти агента, журналах, временных файлах, исправлении кода или запросе, отправленном другому сервису. Ротация может очистить саму учётную информацию, но не восстановит сведения о том, куда она попала.

Используйте шлюз действий, который хранит учётные данные на стороне под контролем компании и выполняет одобренные HTTP- или SSH-действия от имени агента. Агент получает результат, а не секрет. Это не превращает опасное действие в безопасное. Зато у команды появляется место для применения одобрения, записи вызова и отзыва полномочий без поиска по файловой системе подрядчика.

Sallyport использует эту модель для HTTP API-вызовов и SSH-команд: секреты остаются в зашифрованном хранилище, а агент запрашивает действия через MCP-подключение, не получая учётные данные. Здесь важна изоляция, а не магия. Взломанный или неосторожный агент всё ещё может запросить опасные действия в пределах выданных ему полномочий, поэтому ответственность и одобрения по-прежнему необходимы.

Относитесь к каждому пути к учётным данным как к отдельному объекту инвентаризации. Записывайте владельца учётных данных, цель, разрешённый тип действия, ссылку на работу и способ отключения. Не ограничивайтесь заметкой «production-токен используется подрядчиком». Такая заметка не сообщает специалисту по инцидентам, где находится токен, был ли он скопирован и какой путь нужно отключить.

SSH требует особого внимания: команды часто считают вход на хост временным только потому, что подрядчик работает временно. Проверьте authorized keys, сертификаты, локальную переадресацию агента, доступ через jump host, профили оболочки, запланированные задания и удалённые копии скриптов развёртывания. Удаление одного открытого ключа не отзывает закрытый ключ, который всё ещё может попасть на другой доверенный узел.

То же правило действует для HTTP-учётных данных. Удалите или отключите путь действия, затем проверьте, что цель отклоняет новый запрос. Не объявляйте работу завершённой только потому, что в интерфейсе управления доступом пользователь отмечен как отключённый. У шлюза действий, сервисной учётной записи, API-учётных данных и сетевого маршрута могут быть разные жизненные циклы.

## Спроектируйте отзыв до выдачи доступа

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

Опишите путь остановки до первого production-действия. Он должен охватывать процесс агента, сеанс одобрения, маршрут учётных данных, доступ к исходному коду и инфраструктуре, запланированные работы и сохранение аудита. Для каждого пункта укажите исполнителя и способ проверки завершения.

Важно различать отключение и отзыв. Отключение прекращает будущее использование конкретной учётной записи или учётных данных. Отзыв завершает действующие отношения полномочий и удаляет пути, которые могут их восстановить. Учётную запись подрядчика можно отключить, пока уже работающий процесс сохраняет активный сеанс. Токен можно отозвать, пока SSH-подключение остаётся открытым. Обработайте оба состояния.

Используйте следующую последовательность, когда работа заканчивается или её нужно немедленно остановить:

1. Заблокируйте новые действия агента на шлюзе учётных данных или в точке авторизации, затем отзовите активные сеансы, связанные с этой работой.
2. Остановите известные локальные и удалённые процессы агента, включая мультиплексоры терминала, launch agents, задания CI и запланированные задачи.
3. Отключите или замените учётные данные компании, назначенные для этой работы, и удалите доступ к репозиториям, облаку, VPN, bastion и системе управления задачами.
4. Проверьте инвентарь работы на наличие скопированных конфигураций, созданных скриптов, ключей развёртывания и временных сервисных учётных записей, затем удалите их.
5. Проверьте отклонение запроса, выполнив безопасную проверку через разрешённый путь, и сохраните записи действий до закрытия работы.

Порядок важен. Если сначала удалить записи или отключить учётную запись подрядчика, можно потерять сведения, необходимые для поиска активных сеансов. Сначала остановите пути действий, сохраните доказательства, а затем очистите доступ.

Не заявляйте об успехе только потому, что у каждого пункта есть ответственный. Проверьте процедуру во время работы. Попросите хранителя отозвать непроизводственный сеанс в присутствии подрядчика. Убедитесь, что агент не может выполнить следующий вызов, подрядчик понимает, что остановлено, а в журнале активности появилась запись об отказе. Первый случай, когда команда обнаружит отсутствующий путь остановки, не должен совпасть с расследованием инцидента или спором по договору.

## Короткая запись о работе выявляет пропущенные решения

Небольшая запись, которую легко проверить, обнаруживает больше реальных проблем, чем длинная политика доступа, которую никто не читает. Храните её вместе с задачей или в управляемом репозитории эксплуатации, а не в личной переписке.

Этот пример намеренно прост. Замените значения-заполнители собственными идентификаторами, но не убирайте поля из-за того, что работа кажется временной.

```yaml
engagement: contractor-search-repair-2025-04
sponsor: employee-ops-owner
technical_custodian: employee-platform-owner
contractor_operator: external-developer
purpose: diagnose production search indexing failures
agent_process:
  approved_launcher: signed-local-agent-process
  allowed_workstation: managed-mac-asset-184
  expires_at: 2025-04-30T17:00:00Z
scope:
  environments: [staging, production-read]
  permitted_actions:
    - GET search-service health endpoint
    - GET indexing queue depth endpoint
  prohibited_actions:
    - production writes
    - credential administration
approval:
  session_owner: employee-ops-owner
  per_call_owner: employee-platform-owner
credential_routes:
  - search-api-read-route
  - bastion-diagnostic-route
revocation_owner: employee-platform-owner
verification_owner: employee-security-owner
```

Запись разделяет понятия, которые часто объединяют под одной меткой. `contractor_operator` не равен `sponsor`. `session_owner` не обязательно равен `per_call_owner`. `revocation_owner` не тот же человек, который решил, что работа нужна. Такое разделение не даёт подрядчику фактически одобрить расширение собственных полномочий и не превращает отсутствующего менеджера в единственного человека, способного остановить доступ.

В поле `permitted_actions` нужно использовать глаголы и цели. Формулировка «только чтение» слишком расплывчата, если у сервиса есть endpoint, запускающий экспорт, раскрывающий персональные данные или потребляющий ресурсы. К `production-read` тоже нужно относиться внимательно. Операция чтения может раскрыть регулируемые данные или operational-сведения, которые упростят атаку.

Устанавливайте срок окончания, даже если у договора нет точной даты завершения. Если работа продолжается, продлевайте срок отдельным решением. Явленное продление заставляет спонсора проверить, нужен ли по-прежнему production-доступ и остаётся ли исходный процесс тем процессом, который используется сейчас.

## Записи аудита должны отвечать на operational-вопросы

Журнал работы агента должен показывать, кто разрешил действие, какой процесс его запросил, какой цели он достиг, завершилось ли действие успешно и когда полномочия были отозваны. Один протокол чата не может надёжно ответить на все эти вопросы.

По возможности храните два представления. Одно следует за запуском или сеансом агента, чтобы расследующий мог увидеть жизненный цикл авторизации и остановить активный запуск. Второе следует за отдельными действиями, чтобы оператор мог проверить конкретный API-вызов или SSH-команду. Связывайте оба представления с одной исходной записью события, а не ведите разные истории вручную.

Защищайте журнал аудита от процесса, который он записывает. Процесс, способный менять собственную историю, может скрыть наиболее важные доказательства. Хранилище только для добавления, ограниченные права записи и криптографическое сцепление помогают решить эту проблему, но у каждого механизма своя задача. Цепочка может показать, что записи были изменены или удалены. Она не скажет, была ли исходная операция хорошей идеей.

Sallyport ведёт журналы сеансов и активности, сформированные из зашифрованного журнала аудита с хеш-сцеплением. Команда `sp audit verify` может проверять цепочку офлайн поверх шифротекста. Это полезно, когда компьютер с хранилищем заблокирован или расследующему не следует читать сами секреты.

Для каждой работы заранее решите, кто и когда проверяет записи. Для чувствительной записи в production может потребоваться проверка до продолжения работы подрядчиком. Для короткой диагностической задачи может быть достаточно проверки при закрытии. Но команда всё равно должна знать, как найти события во время инцидента.

Сохраняйте и отказы. Отклонённое действие может показать, что агент пытался выйти за пределы полномочий, подрядчик неправильно понял задачу или старый процесс продолжает работать после отключения доступа. Если сохранять только успешные вызовы, вы выбрасываете доказательства, которые часто объясняют следующий инцидент.

## Формулировки договора должны соответствовать дизайну доступа

Договор не может отозвать API-токен, но он может устранить неопределённость, из-за которой команды оставляют доступ. Описывайте operational-обязанности так, чтобы они соответствовали реальным средствам контроля.

Укажите, что компании принадлежат учётные данные, регистрации процессов, записи аудита и любые настройки доступа, созданные для этой работы. Укажите, что подрядчик должен использовать одобренные пути под контролем компании для production-действий и не должен копировать учётные данные в локальные файлы, запросы, репозитории или сторонние сервисы. Если работе требуется исключение, требуйте письменного одобрения спонсора до его применения.

Добавьте обязанность вернуть и удалить рабочие материалы, но не полагайтесь на подтверждение как на единственный контроль. Подрядчик может действовать добросовестно и всё равно пропустить файл в истории оболочки, кэшированную переменную среды или резервную копию. Технический отзыв обрабатывает то, что вы можете контролировать. Условия договора охватывают обязанности, остающиеся за пределами ваших систем.

Определите окончание работы в operational-терминах: спонсор закрывает задачу, хранитель отключает пути действий, ответственный за проверку подтверждает тест отказа, а команда сохраняет журнал аудита по обычным правилам хранения. Если подрядчику позже понадобится доступ для поддержки, откройте новую работу вместо восстановления старой.

Избегайте формулировок, по которым подрядчик «отвечает за безопасность», без перечисления решений и средств контроля. Это звучит строго, но не отвечает на сложные вопросы, когда кто-то просит изменить production в шесть вечера. Напишите, кто может одобрить изменение, кто его выполняет и кто может остановить работу.

Первым документом, который нужно подготовить, должна быть не широкая политика об AI. Подготовьте запись о работе для следующего подрядчика, которому понадобится агент рядом с production. Заполните её вместе со спонсором и хранителем. Любое пустое поле напрямую указывает на задачу, которую команда должна выполнить до выдачи доступа.
