API-ключ Codex — не просто строка. Он определяет, от чьего имени тарифицируются запросы, к каким моделям есть доступ и насколько велик ущерб при утечке. Частые 401 связаны не с недействительным ключом, а с несовпадением имени переменной, переписанным заголовком, неверным уровнем конфигурации или старыми учётными данными в локальном кэше.
Статья описывает типы ключей, создание, переменные окружения и файл конфигурации, profiles, ротацию, минимальные права, CI и диагностику 401 — в порядке, который можно повторить напрямую. Команды и параметры сверяйте с текущей версией Codex и документацией используемого шлюза.
Примечание: OpenAI, Codex и ChatGPT — товарные знаки или зарегистрированные товарные знаки OpenAI. Статья носит технический характер и не подразумевает аффилированности с OpenAI. Права ключей, доступные интерфейсы и тарификация определяются официальной документацией платформ и страницами сайта.
1. Сначала разделите три типа ключей и два хранилища
Учётные данные Codex легко перепутать; разделите их по назначению:
| Название | Типичное использование | Где хранится | Замечания |
|---|---|---|---|
| OpenAI Platform API Key | Вход через codex login --with-api-key |
auth.json или системное хранилище |
Тарификация по стандартным ставкам API |
CODEX_API_KEY |
codex exec, SDK и другие разовые запуски |
Только окружение текущего процесса | Не пишется на диск, подходит для CI |
| Ключ пользовательского provider | Через env_key указывает на переменную |
Окружение оболочки или сервис секретов | Часто используется в командном шлюзе, удобен для лимитов |
Первое хранилище — «учётные данные входа», им управляет cli_auth_credentials_store: file пишет auth.json в CODEX_HOME, keyring использует системное хранилище, auto сначала пробует хранилище и откатывается к файлу, ephemeral держит данные только в памяти процесса. Второе хранилище — «ключ provider», задаваемый именем переменной в env_key; Codex читает её при каждом запросе. Важно: env_key — это только имя переменной, а не сама переменная.
CODEX_HOME по умолчанию ~/.codex, его можно перенести в контролируемый каталог. OPENAI_API_KEY — источник, который читает команда входа; CODEX_API_KEY — разовые учётные данные неинтерактивного запуска. Названия похожи, назначение разное.
2. Создание ключа: пять шагов
- Откройте ZSQH AI Gateway или используемую платформу, зарегистрируйтесь и войдите в консоль.
- Перейдите на страницу «API-ключи» и создайте ключ; в названии укажите среду и назначение, например
codex-work-mac. - Задайте лимит и срок действия. Тестовому ключу сначала дайте небольшой лимит и скорректируйте после реального расхода.
- Если платформа поддерживает белый список моделей или область проекта, отметьте только те модели, которые нужны Codex.
- Скопируйте ключ целиком и сразу сохраните в менеджере паролей или сервисе секретов. Большинство консолей показывают его только один раз.
Ключ часто начинается с sk-, но префикс не доказывает подлинность и ничего не говорит о правах. При копировании проверьте пробелы по краям, переводы строки и лишние кавычки — это частая причина 401. После создания проверьте минимальным запросом и только потом раздавайте команде.
3. Как сочетаются переменные окружения и config.toml
Рекомендуемый подход: в конфигурации только имя переменной, реальный ключ — в окружении или инструменте управления секретами. Пример ~/.codex/config.toml:
# ~/.codex/config.toml
model = "your-model-id"
model_provider = "zsqh"
[model_providers.zsqh]
name = "ZSQH AI Gateway"
base_url = "https://ai.zhongshangqihang.com/v1"
wire_api = "responses"
env_key = "ZSQH_API_KEY"
env_key_instructions = "Создайте ключ в консоли шлюза и экспортируйте его как переменную окружения"
Затем экспортируйте ключ в той же оболочке, из которой запускается Codex:
export ZSQH_API_KEY="sk-ваш-ключ"
В macOS и Linux эту строку можно положить в приватный файл вроде ~/.zshrc.local, а основной файл конфигурации оставить со ссылкой на переменную. В Windows PowerShell используйте $env:ZSQH_API_KEY="sk-ваш-ключ". Процессы, запущенные из Dock, IDE или настольного приложения, могут не видеть переменные из конфигурации оболочки; в этом случае задавайте их в стартовом скрипте или системных переменных.
Если шлюз требует пользовательский заголовок, вместо env_key можно использовать env_http_headers = { "X-API-Key" = "ZSQH_API_KEY" } и настроить локальный каталог моделей. Если ключ динамически выдаётся Vault, KMS или похожим инструментом, токен можно получать через command в [model_providers.zsqh.auth], но не одновременно с env_key. Поле experimental_bearer_token позволяет вписать ключ напрямую, но официально не рекомендуется; в командной среде его лучше избегать.
Можно также использовать вход: printenv OPENAI_API_KEY | codex login --with-api-key — учётные данные попадут в auth.json или хранилище; очистка выполняется через codex logout. Для командного шлюза предпочтительнее env_key: лимиты, права на модели и отзыв управляются централизованно на стороне шлюза.
4. Несколько конфигураций и profiles
Рекомендуется как минимум три набора учётных данных: личный повседневный, проектный и автоматизированный. У них разные лимиты, права и циклы ротации; смешивание затрудняет и учёт расхода, и диагностику.
В новых версиях Codex profile вынесен в отдельный файл. В основной конфигурации определите два provider с разными переменными:
# ~/.codex/config.toml
model = "your-model-id"
model_provider = "zsqh_work"
[model_providers.zsqh_work]
base_url = "https://ai.zhongshangqihang.com/v1"
wire_api = "responses"
env_key = "ZSQH_WORK_KEY"
[model_providers.zsqh_test]
base_url = "https://ai.zhongshangqihang.com/v1"
wire_api = "responses"
env_key = "ZSQH_TEST_KEY"
Затем создайте ~/.codex/test.config.toml, где укажите только переопределяемые ключи верхнего уровня:
model = "your-test-model-id"
model_provider = "zsqh_test"
Переключение выполняется командой codex --profile test. Учтите: начиная с версии 0.134.0 старые таблицы [profiles.xxx] и запись profile = "..." верхнего уровня больше не читаются; в файле profile не нужно снова вкладывать [profiles.xxx] — используйте ключи верхнего уровня. Старые версии могут принимать прежний синтаксис; перед обновлением смотрите примечания к версии.
.codex/config.toml в доверенном проекте подходит только для несекретных соглашений; model_provider, model_providers и profile из него игнорируются, и ключ туда тоже писать и коммитить нельзя.
5. Ротация ключей: когда и как
Цель ротации — не формальность, а сокращение окна действия после утечки. Поводом служат уход сотрудника, потеря устройства, подозрение на утечку, требование поставщика и фиксированный цикл, например каждые 90 дней.
- Создайте в консоли новый ключ с датой в названии, например
codex-prod-2026-10. - Сначала запишите новый ключ в инструмент управления секретами или переменную окружения, старый пока сохраните.
- Проверьте оба ключа через
codex execи минимальный запрос: модель, лимит и права должны работать. - Посмотрите журнал расхода старого ключа и убедитесь, что забытых скриптов или сотрудников не осталось.
- Отключите старый ключ и наблюдайте долю ошибок и неудачные запросы ещё один-два дня.
- Зафиксируйте время ротации, ответственного и область влияния для передачи и аудита.
Не выполняйте ротацию в пик нагрузки. Параллельная работа двух ключей безопаснее схемы «удалить и создать». Если используется только вход, после ротации выполните codex logout и войдите заново, чтобы в auth.json не остались старые данные. auth.json нужно защищать как пароль и не синхронизировать с публичными облачными дисками или репозиториями.
6. Минимальные права и защита от утечек
- Один ключ на человека, при необходимости дополнительно по средам; для CI отдельный ключ с отдельным лимитом.
- Задайте ключу срок действия, бюджет и лимит параллельности; открывайте только нужные модели.
- Если платформа поддерживает белый список IP, ограничьте офисной сетью или выходом runner; если нет — полагайтесь на лимиты и оповещения.
- В корпоративной среде можно принудительно задать
forced_login_method = "api"или"chatgpt", чтобы сотрудники не смешивали учётные данные. - На личной машине предпочтителен
cli_auth_credentials_store = "keyring"; на общей машине или в CI —ephemeral, чтобы меньше писалось на диск. .gitignoreдолжен покрывать.env,.env.*,auth.json,*.pemи подобные файлы; перед коммитом проверяйте шаблонsk-через secret scanning или pre-commit hook.- Не вписывайте ключ по умолчанию в код, не отлаживайте через
echo $ZSQH_API_KEY, маскируйте заголовокAuthorizationв журналах.
При подтверждённой утечке порядок такой: сначала отключите или удалите ключ, затем создайте новый, после чего проверьте журнал расхода и историю репозитория. Удалить файл недостаточно — старый ключ мог уже быть скопирован в другое место.
7. CI и неинтерактивное использование
Принцип CI: «ключ не попадает в код, образ и журналы».
- Для разового запуска используйте
CODEX_API_KEY=<key> codex exec --json "...", подставляя значение только перед командой, а не на уровне переменных задания. - В GitHub Actions предпочтителен официальный Action Codex; не вставляйте ключ прямо в шаг shell.
- В CI используйте отдельный ключ с низким лимитом и узкими правами, доступный только на защищённых ветках или в доверенных workflow.
- Используйте
--ephemeral, чтобы файлы сессии не писались на диск; вне Git-репозитория при необходимости добавьте--skip-git-repo-check. - Не используйте управляемые учётные данные ChatGPT в публичных репозиториях и на недоверенных runner.
8. Диагностика 401: порядок проверки
401 означает ошибку аутентификации, но не обязательно неверный ключ. Проверяйте по порядку:
- Выполните
codex login statusи определите фактически действующий способ входа. - Убедитесь, что имя переменной в
env_keyнаписано без ошибок и переменная непустая в текущем процессе; проверяйте длину, не печатая значение целиком. - Определите, из какого окружения запущен Codex. Встроенный терминал IDE, Docker, systemd и launchd могут не наследовать переменные оболочки.
- Заново скопируйте ключ из консоли, исключив пробелы, переводы строки и кавычки.
- Если используются учётные данные входа, выполните
codex logoutи войдите снова, чтобы исключить остатки вauth.json. - Проверьте, не конфликтует ли
forced_login_methodс текущим типом учётных данных; при несовпадении Codex может завершиться или отклонить запрос. - Проверьте, не истёк ли ключ, не отключён ли он, есть ли баланс и права на модель.
- Убедитесь, что Base URL и путь
/v1верны, а прокси не удаляет и не переписываетAuthorization; при необходимости сверьтесь с журналом шлюза.
Частые ошибки:
| Симптом | Частая причина | Что делать |
|---|---|---|
| 401 — ошибка аутентификации | Переменная не экспортирована, имя не совпадает, учётные данные истекли | Сверить env_key; переоткрыть терминал; войти заново |
| 403 Forbidden | Нет прав на модель, ограничение IP, заморожен лимит | Проверить права и белый список в консоли |
| 404 Not Found | Лишний или пропущенный /v1, неверный путь |
Сверить адрес и доступные интерфейсы по частям |
| 429 Too Many Requests | Превышена параллельность или лимит | Снизить параллельность, проверить лимит ключа |
| model not found | Неверный идентификатор модели | Скопировать точный идентификатор со страницы цен |
Частые вопросы
API-ключ Codex и подписка ChatGPT — это одно и то же?
Нет. Подписка ChatGPT относится к веб- и клиентским продуктам; Codex может входить через аккаунт или работать по API Key с оплатой по факту. Лимиты, счета и объём прав различаются, поэтому в команде их нужно учитывать раздельно.
Как связаны env_key и OPENAI_API_KEY?
env_key — параметр конфигурации, значением которого является имя переменной окружения; OPENAI_API_KEY — одно из распространённых имён и источник для codex login --with-api-key. Можно указать env_key = "OPENAI_API_KEY", но лучше дать шлюзу отдельное имя, чтобы не смешивать с учётными данными входа.
Можно ли вписать ключ прямо в config.toml?
Не рекомендуется. Открытый ключ легко утекает вместе с резервной копией конфигурации, скриншотом или репозиторием. Используйте env_key со ссылкой на переменную или [model_providers.xxx.auth] с внешней командой получения токена.
Нужно ли останавливать сервис при ротации ключа?
Нет. Создайте и проверьте новый ключ, переключите конфигурацию, затем отключите старый — параллельная работа двух ключей позволяет избежать обрыва запросов.
Почему codex login status в порядке, а запросы всё равно дают 401?
Статус входа показывает лишь наличие локальных учётных данных и не подтверждает работоспособность ключа пользовательского provider. Проверьте переменную env_key, Base URL, баланс шлюза и права на модель; если запрос идёт через прокси, проверьте, не переписываются ли заголовки.
Что дальше
Если ключа ещё нет, создайте тестовый ключ с небольшим лимитом через страницу регистрации и настройте его по порядку из статьи. Модели, лимиты и способ тарификации смотрите на странице «Модели и цены»; цены меняются вслед за версиями моделей и политикой upstream, ориентируйтесь на актуальную информацию страницы.
Читайте также:
