Amiga
Оглавление курса · урок 6 из 14

Модуль 2 · CI/CD · урок 6 из 14

GitHub Action для Codex

Основной код агентства в GitLab, но часть клиентских проектов живёт на GitHub. Там у Codex есть готовая обёртка — openai/codex-action@v1. Она ставит CLI, поднимает прокси для ключа API и запускает codex exec с заданными правами. В уроке — как её подключить, какие входы важны и какие настройки безопасности нельзя оставлять по умолчанию без понимания.

Что делает action

Action решает три задачи, которые в GitLab мы решали руками:

  1. Устанавливает Codex CLI нужной версии.
  2. Запускает прокси Responses API, если передан ключ. Ключ не выставляется переменной окружения для всего job.
  3. Запускает codex exec с вашим промптом и выбранной стратегией безопасности.

Требования: раннер на Linux или macOS (для Windows обязателен safety-strategy: unsafe), ключ в секретах репозитория (например, OPENAI_API_KEY), код уже получен через actions/checkout.

Минимальный workflow: ревью PR

Пример по мотивам документации. Codex читает PR, а отдельный job публикует итог комментарием.

yaml · .github/workflows/codex-review.yml
name: Codex pull request review
on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  codex:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    outputs:
      final_message: ${{ steps.run_codex.outputs.final-message }}
    steps:
      - uses: actions/checkout@v5
        with:
          ref: refs/pull/${{ github.event.pull_request.number }}/merge
          fetch-depth: 0
          persist-credentials: false

      - name: Run Codex
        id: run_codex
        uses: openai/codex-action@v1
        with:
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          prompt-file: .github/codex/prompts/review.md
          codex-version: "0.163.0"
          sandbox: read-only
          output-file: codex-output.md

  post_feedback:
    runs-on: ubuntu-latest
    needs: codex
    if: needs.codex.outputs.final_message != ''
    permissions:
      issues: write
      pull-requests: write
    steps:
      - uses: actions/github-script@v7
        env:
          CODEX_FINAL_MESSAGE: ${{ needs.codex.outputs.final_message }}
        with:
          github-token: ${{ github.token }}
          script: |
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.payload.pull_request.number,
              body: process.env.CODEX_FINAL_MESSAGE,
            });

Главное в этой схеме — разделение прав. Job с Codex может только читать репозиторий (contents: read) и не хранит учётные данные Git (persist-credentials: false). Job, который пишет комментарий, получает права на запись, но не получает ключ OpenAI и не запускает агента.

Входы action

Вход Зачем
prompt / prompt-file Задача: текст прямо в workflow или файл в репозитории. Только одно из двух. Промпты удобно хранить в .github/codex/prompts/
codex-args Дополнительные флаги codex exec: JSON-массив (["--ephemeral"]) или строка в стиле shell. Аргументы, ослабляющие защиту (альтернативный профиль конфигурации, дополнительные каталоги для записи, обход песочницы), action отклоняет
model, effort Модель и уровень рассуждений. Пусто — значения по умолчанию
sandbox read-only, workspace-write, danger-full-access
output-file Записать итоговое сообщение в файл для артефактов
codex-version Закрепить версию CLI. Пусто — последняя опубликованная
codex-home Каталог конфигурации Codex. Считается доверенным: не указывайте каталог из проверяемой ветки
safety-strategy Привилегии самого процесса Codex (ниже)
allow-users, allow-bots, allow-bot-users Кто может запускать action

Выход action — final-message, последнее сообщение Codex.

В актуальном action.yml репозитория openai/codex-action есть входы, которых пока нет на странице документации: permission-profile (профиль прав, например :workspace, вместо устаревающего sandbox), output-schema и output-schema-file для ответа по схеме, working-directory. Перед использованием сверьтесь с action.yml той версии, которую закрепили. Если нужна структура ответа, а нового входа в вашей версии нет, передайте --output-schema через codex-args.

Стратегии безопасности

Вход safety-strategy управляет тем, с какими привилегиями работает процесс Codex на раннере.

  • drop-sudo (по умолчанию) — перед запуском у пользователя отбирается sudo, необратимо для всего job. Это защищает секреты в памяти.
  • unprivileged-user вместе с codex-user — Codex работает от отдельного пользователя. Ему нужны права на чтение и запись рабочей копии.
  • read-only — Codex не меняет файлы и не ходит в сеть, но работает от пользователя по умолчанию, у которого на раннере, скорее всего, есть sudo. Документация прямо предупреждает: одного read-only для защиты секретов недостаточно.
  • unsafe — без ограничений. Обязателен на Windows, недопустим на раннерах, которые делят несколько команд.

Почему это важно. На раннерах GitHub по умолчанию работает sudo без пароля. В документации action разобран пример: даже при доступе только на чтение и без сети пользователь с sudo может достать ключ через файловую систему procfs. Поэтому не трогайте drop-sudo без веской причины.

safety-strategy и sandbox — разные уровни. Первый ограничивает процесс Codex целиком, второй — команды, которые запускает агент. Нужны оба.

Кто может запускать

По умолчанию action запускается только пользователями с правом записи в репозиторий. Расширить список можно через allow-users, разрешить бота github-actions[bot] — через allow-bots, другие доверенные боты перечисляются явно в allow-bot-users (звёздочка там не поддерживается). Делайте это осторожно. Значение allow-users: "*" открывает ваш ключ всему интернету: документация action описывает злоупотребления, когда посторонние заводят issue, чтобы заставить Codex работать на них за ваш счёт.

Недоверенный ввод

Промпт часто собирают из контекста PR: заголовок, описание, коммиты. Всё это — потенциальный канал prompt injection. Документация action перечисляет типичные места:

  • описание PR: инструкции прячут в HTML-комментарий, который не виден в интерфейсе, но виден модели;
  • сообщения отдельных коммитов, которые никто не читает;
  • файлы инструкций из ветки PR — AGENTS.md, AGENTS.override.md: если Codex работает с содержимым PR, эти файлы тоже недоверенные;
  • скриншоты и другие медиа.

Отдельная ловушка — shell-инъекция в самом workflow. GitHub подставляет выражения ${{ ... }} в скрипт до запуска shell. Если вставить так название ветки или заголовок issue, специально составленное значение выполнится как команда. Передавайте такие значения через env и используйте в кавычках:

yaml
- name: Safe shell usage
  env:
    PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
  run: |
    git fetch origin "$PR_BASE_REF"

Ещё три правила из документации

  • Codex — последний шаг job. После агента с широкими правами состояние раннера непредсказуемо: могли остаться процессы, измениться файлы других actions или Git-хуки. Результат передавайте в следующий job через outputs или артефакты.
  • Закрепляйте codex-version. Воспроизводимость важнее свежести.
  • Ротация ключа. Если есть подозрение, что ключ попал в логи или вывод, отзывайте его сразу.

Встроенное ревью без workflow

Для ревью PR на GitHub workflow не обязателен. У Codex есть встроенная интеграция: подключаете репозиторий, включаете Automatic review в настройках ревью или пишете в PR комментарий @codex review. Codex публикует обычное ревью GitHub и отмечает только проблемы приоритетов P0 и P1. Правила ревью берутся из раздела ## Code Review Rules в AGENTS.md. Подробно — в уроке про ревью и в документации.

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

Попробуйте сами

10–15 мин на рабочем месте
  1. В тестовом репозитории на GitHub добавьте секрет OPENAI_API_KEY и workflow из урока. Создайте файл .github/codex/prompts/review.md с тремя-пятью пунктами, на что смотреть в ревью.
  2. Откройте PR и убедитесь, что комментарий появился. Проверьте в логе job, что Codex работал с drop-sudo.
  3. Найдите в своих workflow места, где ${{ github.event... }} подставляется прямо в run:, и перенесите эти значения в env.

Коротко

  • openai/codex-action@v1 ставит CLI, прячет ключ за прокси и запускает codex exec.
  • Job с Codex — только чтение. Публикация результата — отдельный job без ключа.
  • safety-strategy: drop-sudo не отключайте. read-only секреты не защищает.
  • Запускать могут только пользователи с правом записи. allow-users: "*" — открытый ключ.
  • Текст PR, коммиты и AGENTS.md из ветки PR — недоверенный ввод.
Отметка хранится только в вашем браузере
Хотите связаться с владельцем
компании напрямую?
Дмитрий Тарасов
Дмитрий Тарасов
СЕО

НАПИСАТЬ

Написать в MAX