Поддержание аутентификации учетной записи Codex в CI/CD (расширенный сценарий)
Используйте встроенный механизм обновления Codex, чтобы auth.json продолжал работать на доверенных исполнителях CI/CD
В этом руководстве показано, как поддерживать аутентификацию Codex под управлением ChatGPT на доверенном исполнителе CI/CD, не обращаясь к конечной точке токенов OAuth самостоятельно.
Для аутентификации автоматизированных процессов следует использовать API key. Следуйте этому руководству, только если вам необходимо запускать рабочий процесс именно от имени своей учетной записи Codex.
Схема работы:
- Один раз создайте
auth.jsonна доверенном компьютере с помощьюcodex login. - Поместите этот файл на исполнитель.
- Запустите Codex обычным способом.
- Позвольте Codex обновить сеанс, когда он устареет.
- Сохраните обновленный
auth.jsonдля следующего запуска.
Это расширенный сценарий для корпоративной и другой доверенной частной автоматизации. Для большинства заданий CI/CD по-прежнему рекомендуется использовать API keys.
Почему это работает
Codex уже умеет обновлять сеанс под управлением ChatGPT.
В текущей версии клиента с открытым исходным кодом:
- Codex загружает локальный кеш аутентификации из
auth.json - если
last_refreshстарше примерно 8 дней, Codex обновляет набор токенов до продолжения запуска - после успешного обновления Codex записывает новые токены и новое значение
last_refreshобратно вauth.json - если запрос получает
401, в Codex также предусмотрен встроенный механизм обновления и повторной попытки
Таким образом, поддерживаемая стратегия CI/CD — не «самостоятельно вызывайте API обновления».
Она заключается в том, чтобы «запустить Codex и сохранить обновленный auth.json».
Когда следует использовать этот подход
Используйте это руководство, только если выполняются все следующие условия:
- вам нужна аутентификация Codex под управлением ChatGPT, а не API key
codex loginневозможно запустить на удаленном исполнителе- исполнитель находится в доверенной частной инфраструктуре
- вы можете сохранять обновленный
auth.jsonмежду запусками - конкретную копию
auth.jsonбудет использовать только один компьютер или один последовательный поток заданий
Это руководство применимо к аутентификации ChatGPT под управлением Codex (auth_mode: "chatgpt").
Оно не применимо к следующим сценариям:
- аутентификация с помощью API key
- интеграции с хостами, использующие внешние токены (
auth_mode: "chatgptAuthTokens") - универсальные клиенты OAuth за пределами Codex
Если ваши учетные данные хранятся в системном хранилище ключей, сначала переключитесь на хранение в файле. См. раздел Хранение учетных данных.
Однократное создание исходного auth.json
На доверенном компьютере, где возможен вход через браузер:
- Настройте Codex для хранения учетных данных в файле:
cli_auth_credentials_store = "file"- Выполните:
codex login- Убедитесь, что файл соответствует аутентификации ChatGPT под управлением Codex:
AUTH_FILE="${CODEX_HOME:-$HOME/.codex}/auth.json"
jq '{
auth_mode,
has_tokens: (.tokens != null),
has_refresh_token: ((.tokens.refresh_token // "") != ""),
last_refresh
}' "$AUTH_FILE"Продолжайте, только если:
auth_modeимеет значение"chatgpt"has_refresh_tokenимеет значениеtrue
Затем поместите содержимое auth.json в диспетчер секретов CI/CD или скопируйте
его на доверенный постоянный исполнитель.
Рекомендуемая схема: GitHub Actions на собственном исполнителе
Самый простой полностью автоматизированный вариант — собственный исполнитель GitHub Actions с
постоянным CODEX_HOME.
Преимущества этой схемы:
- исполнитель может хранить
auth.jsonна диске между заданиями - Codex может обновлять файл на месте
- последующие задания автоматически используют обновленные токены
- исходный секрет необходим только для начальной загрузки или повторного создания исходного файла
Крайне важно создавать исходный auth.json только при его отсутствии. Если
при каждом запуске перезаписывать файл исходным секретом, обновленные токены,
только что записанные Codex, будут потеряны.
Пример запланированного рабочего процесса:
name: Keep Codex auth fresh
on:
schedule:
- cron: "0 9 * * 1"
workflow_dispatch:
jobs:
keep-codex-auth-fresh:
runs-on: self-hosted
steps:
- name: Bootstrap auth.json if needed
shell: bash
env:
CODEX_AUTH_JSON: ${{ secrets.CODEX_AUTH_JSON }}
run: |
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$CODEX_HOME"
chmod 700 "$CODEX_HOME"
if [ ! -f "$CODEX_HOME/auth.json" ]; then
printf '%s' "$CODEX_AUTH_JSON" > "$CODEX_HOME/auth.json"
chmod 600 "$CODEX_HOME/auth.json"
fi
- name: Run Codex
shell: bash
run: |
codex exec --json "Reply with the single word OK." >/dev/nullЧто при этом происходит:
- при первом запуске создается исходный
auth.json - последующие запуски повторно используют тот же файл
- когда кешированный сеанс становится достаточно старым, Codex обновляет его на обычном
шаге
codex exec - обновленный файл остается на диске для следующего запуска рабочего процесса
Обычно достаточно еженедельного расписания, поскольку в текущем клиенте с открытым исходным кодом Codex считает сеанс устаревшим примерно через 8 дней.
Эфемерные исполнители: восстановление, запуск Codex и сохранение обновленного файла
Если вы используете исполнители, размещенные на GitHub, общие исполнители GitLab или любую другую эфемерную среду, файловая система исполнителя исчезает после каждого задания. В такой конфигурации необходим полный цикл:
- восстановить текущий
auth.jsonиз защищенного хранилища - запустить Codex
- записать обновленный
auth.jsonобратно в защищенное хранилище
Общая структура GitHub Actions:
name: Run Codex with managed auth
on:
workflow_dispatch:
jobs:
codex-job:
runs-on: ubuntu-latest
steps:
- name: Restore auth.json
shell: bash
run: |
export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$CODEX_HOME"
chmod 700 "$CODEX_HOME"
# Replace this with your secret manager or secure storage command.
my-secret-cli read codex-auth-json > "$CODEX_HOME/auth.json"
chmod 600 "$CODEX_HOME/auth.json"
- name: Run Codex
shell: bash
run: |
codex exec --json "summarize the failing tests"
- name: Persist refreshed auth.json
if: always()
shell: bash
run: |
# Replace this with your secret manager or secure storage command.
my-secret-cli write codex-auth-json < "$CODEX_HOME/auth.json"Главное требование: на шаге обратной записи должен сохраняться обновленный файл, созданный Codex во время запуска, а не исходный файл.
Отдельная команда обновления не требуется
Сеанс может обновить любой обычный запуск Codex.
Поэтому у вас есть два подходящих варианта:
- позволить существующему заданию Codex в CI/CD обновлять файл естественным образом
- добавить легковесное плановое задание обслуживания, как в приведенном выше примере GitHub Actions, если реальные задания выполняются недостаточно часто
auth.json обновляется при первом запуске Codex после того, как сеанс устареет.
Важные правила эксплуатации
- Используйте один
auth.jsonна исполнитель или на последовательный поток рабочих процессов. - Не используйте один и тот же файл одновременно в нескольких заданиях или на нескольких компьютерах.
- Не перезаписывайте обновленный файл постоянного исполнителя исходным файлом при каждом запуске.
- Не храните
auth.jsonв репозитории, журналах или общедоступном хранилище артефактов. - Если встроенный механизм обновления перестал работать, заново создайте исходный файл на доверенном компьютере.
Что делать, если обновление перестало работать
Этот процесс сокращает объем ручной работы, но не гарантирует, что один и тот же сеанс будет действовать вечно.
Заново создайте для исполнителя свежий auth.json, если:
- Codex начинает возвращать
401, а исполнитель больше не может обновить сеанс - токен обновления был отозван или истек
- другой компьютер или параллельное задание первым выполнили ротацию токена
- цикл обмена с защищенным хранилищем завершился сбоем и был восстановлен старый файл
Для повторного создания исходного файла:
- Выполните
codex loginна доверенном компьютере. - Замените сохраненную в CI/CD копию
auth.json. - Позвольте следующему заданию исполнителя продолжить работу со встроенным механизмом обновления Codex.
Проверка поддержки сеанса исполнителем
Убедитесь, что у исполнителя по-прежнему есть управляемые токены аутентификации и существует last_refresh:
AUTH_FILE="${CODEX_HOME:-$HOME/.codex}/auth.json"
jq '{
auth_mode,
last_refresh,
has_access_token: ((.tokens.access_token // "") != ""),
has_id_token: ((.tokens.id_token // "") != ""),
has_refresh_token: ((.tokens.refresh_token // "") != "")
}' "$AUTH_FILE"Если исполнитель постоянный, один и тот же файл должен сохраняться между запусками. Если исполнитель эфемерный, убедитесь, что на шаге обратной записи сохраняется обновленный файл из последнего задания.
Ссылки на исходный код
Если вы хотите проверить это поведение в клиенте с открытым исходным кодом:
codex-rs/core/src/auth.rsохватывает обнаружение устаревших токенов, автоматическое обновление, восстановление после 401 путем обновления и сохранение обновленных токеновcodex-rs/core/src/auth/storage.rsохватывает хранениеauth.jsonв файле