Сообщение self signed certificate in certificate chain в Codex почти никогда не означает, что вы сами что-то подписали. Оно говорит о сети: цепочка сертификатов, которую получил процесс, заканчивается корневым сертификатом, которого нет в его хранилище доверенных. На рабочем ноутбуке это обычно корневой сертификат корпоративного прокси, который проверяет HTTPS-трафик и переподписывает его сертификатом компании.
Исправление состоит из двух действий: получить этот корневой сертификат в формате PEM и передать его той настройке, которую читает именно упавший процесс. Для Codex CLI это выглядит так:
export CODEX_CA_CERTIFICATE="$HOME/certs/corp-root-ca.pem"
codex loginЕсли ошибка появилась не в самом Codex, а в настольном приложении, MCP-сервере или в команде, которую Codex запустил в песочнице, эта переменная может не помочь: у каждого из этих процессов свой источник доверия. Отключать проверку сертификатов (NODE_TLS_REJECT_UNAUTHORIZED=0, curl -k) не нужно ни в одном из случаев.
Какой процесс выдал ошибку и какую настройку он читает
Сначала найдите, где именно вы увидели текст ошибки: от этого зависит, какая настройка её уберёт.
| Где появилась ошибка | Какой процесс не доверяет цепочке | Что настроить |
|---|---|---|
codex login, запросы и WebSocket в Codex CLI | Собственный клиент Codex | CODEX_CA_CERTIFICATE, если её нет — SSL_CERT_FILE |
MCP-сервер, подключённый по url | HTTP-клиент MCP внутри Codex | Те же CODEX_CA_CERTIFICATE / SSL_CERT_FILE |
MCP-сервер, запущенный через command (npx, node) | Отдельный процесс Node | NODE_EXTRA_CA_CERTS в окружении этого сервера |
Remote Control в настольном приложении, в журнале SELF_SIGNED_CERT_IN_CHAIN | Node-слой приложения | По сообщению пользователя на macOS — запуск с NODE_USE_SYSTEM_CA=1 |
curl: (60) SSL certificate problem: self signed certificate in certificate chain в команде, которую выполнил Codex | curl внутри песочницы | Явный файл: CURL_CA_BUNDLE или --cacert |
npm install и другие Node-инструменты, запущенные Codex | Процесс Node внутри песочницы | NODE_EXTRA_CA_CERTS, переданная через политику окружения |

Первые две строки опираются на документацию и код Codex, третья и шестая — на документацию Node.js. Четвёртая и пятая описаны только в открытых обращениях пользователей в репозитории openai/codex, сопровождающие их не подтверждали; подробности — в соответствующих разделах ниже.
Что означает self signed certificate in certificate chain
Это ошибка проверки цепочки с кодом 19 в OpenSSL: сервер предъявил цепочку, которая упирается в самоподписанный корневой сертификат, а клиент этого корневого сертификата не знает. Самоподписан любой корневой сертификат, в том числе публичных удостоверяющих центров; разница в том, что публичные заранее лежат в хранилище доверенных, а корпоративный — нет.
В корпоративной сети причина чаще всего одна: прокси или агент безопасности выполняет инспекцию HTTPS. Он принимает соединение с chatgpt.com или api.openai.com, проверяет содержимое и отдаёт вашему компьютеру тот же ответ, но с сертификатом, выпущенным корневым CA организации. Браузер при этом работает, потому что ИТ-служба добавила корневой сертификат в системное хранилище. Процесс, который системное хранилище не читает, видит незнакомый корневой сертификат и прерывает соединение.
Реже встречаются другие причины: антивирус с проверкой HTTPS, собственный шлюз или MCP-сервер с сертификатом частного CA, нестандартный базовый URL. Похожее сообщение self-signed certificate без слов про цепочку (код 18) — другой случай: самоподписан сам сертификат сервера, а не корень цепочки.
Кто переподписал соединение: проверка через openssl s_client
Прежде чем что-либо менять, посмотрите, чья подпись стоит в конце цепочки. Подставьте хост из текста ошибки или журнала; если его нет, начните с chatgpt.com:
openssl s_client -connect chatgpt.com:443 -showcerts </dev/nullВ выводе найдите блок Certificate chain. Каждая запись состоит из строки s: (кому выдан сертификат) и i: (кем выдан). Смотрите на i: последней записи:
- название вашей компании или продукта безопасности — инспекция HTTPS подтверждена, нужен корневой сертификат именно этого издателя;
- публичный удостоверяющий центр — трафик к этому хосту не переподписывается, причину ищите в другом хосте из ошибки или в самом процессе;
- незнакомое название, которое не относится ни к компании, ни к известным вам средствам защиты, — не добавляйте его в доверенные, покажите вывод ИТ-службе.
Если выход в интернет возможен только через явный прокси, добавьте к команде -proxy хост:порт. Описание параметров — в документации OpenSSL по s_client.
Как получить корневой сертификат в формате PEM
Самый надёжный источник — ИТ-служба: попросите корневой сертификат корпоративного прокси файлом PEM. Если он уже установлен в системе, его можно выгрузить самостоятельно:
- macOS: «Связка ключей» → связка «Система» → найдите сертификат с именем из строки
i:→ «Файл» → «Экспортировать объекты», формат.pem; - Windows:
certmgr.msc→ «Доверенные корневые центры сертификации» → «Сертификаты» → «Экспорт», формат «X.509 в кодировке Base-64».
Файл PEM — текстовый, начинается со строки -----BEGIN CERTIFICATE-----. Убедитесь, что в нём тот самый издатель:
openssl x509 -in "$HOME/certs/corp-root-ca.pem" -noout -subject -issuer -enddateУ корневого сертификата subject и issuer совпадают, и это имя должно совпасть с i: последней записи из предыдущего шага.
Codex CLI: CODEX_CA_CERTIFICATE и SSL_CERT_FILE
Клиенту Codex достаточно пути к PEM-файлу в переменной окружения. В документации по аутентификации сказано: если сеть использует корпоративный TLS-прокси или частный корневой CA, задайте CODEX_CA_CERTIFICATE до входа; когда она не задана, Codex использует SSL_CERT_FILE.
macOS и Linux:
export CODEX_CA_CERTIFICATE="$HOME/certs/corp-root-ca.pem"
codex loginWindows PowerShell:
$env:CODEX_CA_CERTIFICATE = "C:\certs\corp-root-ca.pem"
codex loginЧтобы настройка сохранялась между сеансами, добавьте строку export в ~/.zshrc или ~/.bashrc, а в Windows задайте переменную среды пользователя.
Что стоит знать о поведении этой настройки (по описанию изменения #14239 в репозитории Codex, принятого 13 марта 2026 года):
- она действует не только на вход: её учитывают исходящие HTTPS-запросы и защищённые WebSocket-соединения, включая облачные задачи и HTTP-клиент MCP;
- порядок такой:
CODEX_CA_CERTIFICATE, затемSSL_CERT_FILE, затем системные корневые сертификаты; - ваш файл добавляется к системным корневым, а не заменяет их, поэтому в нём достаточно одного корпоративного корня;
- если файл не читается или повреждён, Codex выводит ошибку с именем переменной и путём — по ней видно, что настройка подхвачена.
Проверка результата: codex login завершается без ошибки, после чего короткий запрос в новом сеансе получает ответ. Если вместо этого вы видите сообщение о загрузке CA с путём к файлу, исправьте путь или формат файла.
Два случая, когда переменная не срабатывает:
- Старая сборка CLI. Сборки до этого изменения доверяли только системным корневым сертификатам; у пользователя версии 0.58.0 та же причина давала при входе сообщение
Token exchange failed: error sending request for url (https://auth.openai.com/oauth/token )— без слов про сертификат (обращение #6849). Обновите Codex и повторите. Остальные причины этого сообщения разобраны в материале про ошибку Token Exchange Failed в Codex и поиск этапа сбоя. - Переменная задана не в том окружении. Она действует только на процесс, который её унаследовал: терминал, открытый до правки
~/.zshrc, или IDE, запущенная из Dock, о ней не знают. Перезапустите терминал; расширение IDE проверьте, запустив редактор из терминала, где переменная уже задана.
Вход по коду устройства (codex login --device-auth) проблему не обходит: он удобен на машинах без браузера, но обращается к тем же серверам по HTTPS и упирается в ту же проверку цепочки.
Настольное приложение: Remote Control и NODE_USE_SYSTEM_CA=1
Для настольного приложения официального описания работы с собственным CA в документации Codex нет, есть сообщение пользователя. В обращении #43489 от 7 сентября 2026 года (приложение 26.901.51231, macOS 26.6.1) описано следующее: в сети с инспекцией HTTPS функция Remote Control не подключается, в журнале остаются SELF_SIGNED_CERT_IN_CHAIN и строка [remote-control-transport] remote_control_websocket.connect_failed_before_open. При этом корневой сертификат компании доверен в системной связке ключей, а curl, OpenSSL и отдельно установленный Node проверяют цепочку успешно.
Автор обращения добился подключения, запустив приложение из терминала с переменной, которая заставляет Node читать системное хранилище:
NODE_USE_SYSTEM_CA=1 /Applications/ChatGPT.app/Contents/MacOS/ChatGPTЭто наблюдение одного пользователя: обращение открыто, ответа сопровождающих в нём нет, и в следующих сборках поведение может измениться. Сама переменная документирована в справке Node.js: NODE_USE_SYSTEM_CA=1 подключает хранилище операционной системы — связку ключей в macOS, хранилище сертификатов Windows, стандартные каталоги OpenSSL в Linux. Там же описана NODE_EXTRA_CA_CERTS: она добавляет сертификаты из PEM-файла к встроенным корневым и читается один раз при старте процесса.
Читает ли Node-слой приложения CODEX_CA_CERTIFICATE и как приложение ведёт себя в Windows и Linux, в открытых источниках не описано. Если запуск с NODE_USE_SYSTEM_CA=1 не помогает, приложите к обращению в поддержку или к тому же issue строку из журнала и вывод openssl s_client. Когда приложение при этом ещё и теряет связь посреди работы, сначала сохраните состояние по инструкции «Codex постоянно переподключается: сохраните задачу и найдите причину».
MCP-серверы: подключение по url и отдельный процесс Node
У MCP-серверов два разных случая, и определяются они тем, как сервер описан в config.toml.
Сервер с ключом url вызывается HTTP-клиентом самого Codex. Этот клиент входит в список компонентов, на которые распространили CODEX_CA_CERTIFICATE и SSL_CERT_FILE, поэтому отдельной настройки не требуется: достаточно шага из предыдущего раздела. Так же решается ситуация, когда сервер развёрнут внутри компании и его сертификат выпущен частным CA: добавьте корень этого CA в тот же PEM-файл.
Сервер с ключом command — отдельный процесс. Если он написан на Node (типичный запуск через npx), то к внешним API он обращается сам и читает собственные настройки доверия. Передайте ему файл через таблицу env сервера, описанную в документации по MCP:
[mcp_servers.docs]
command = "npx"
args = ["-y", "example-mcp-server"]
[mcp_servers.docs.env]
NODE_EXTRA_CA_CERTS = "/Users/you/certs/corp-root-ca.pem"Имя сервера и пакета здесь условные, путь к файлу укажите абсолютный. NODE_EXTRA_CA_CERTS читается при старте, поэтому после правки перезапустите Codex. Если файл повреждён, Node ограничится предупреждением и продолжит работу без него — при повторной ошибке проверьте файл командой openssl x509 из раздела выше. Серверы на других языках читают свои настройки; для них ищите параметр CA в документации конкретного сервера.
curl: (60) и npm в командах, которые запускает Codex
Команды, запущенные Codex, работают в песочнице и в отфильтрованном окружении, поэтому могут падать даже тогда, когда та же команда в обычном терминале проходит.
Первая причина описана в обращении #11182 (9 февраля 2026 года, codex-cli 0.98.0, macOS). По разбору автора, системный curl на macOS для корневых сертификатов, которых нет в /etc/ssl/cert.pem, обращается к службе com.apple.TrustEvaluationAgent, чтобы проверить доверие по связке ключей. Песочница это обращение запрещает (отказ виден при запуске с --log-denials), и curl завершается с curl: (60) SSL certificate problem: self signed certificate in certificate chain. Обращение открыто, решения от сопровождающих в нём нет.
Обойтись без связки ключей можно штатным способом curl — указать файл с сертификатами явно. Обращение этот способ не проверяло, это стандартное поведение curl:
curl --cacert "$HOME/certs/corp-bundle.pem" https://example.internal/healthили через переменную CURL_CA_BUNDLE. В отличие от настройки Codex, curl этим файлом заменяет набор доверенных сертификатов, а не дополняет его. Если часть хостов идёт мимо инспекции, соберите общий файл:
cat /etc/ssl/cert.pem "$HOME/certs/corp-root-ca.pem" > "$HOME/certs/corp-bundle.pem"Вторая причина — переменная не доходит до команды. Какие переменные окружения Codex передаёт запускаемым процессам, определяет shell_environment_policy в config.toml, поэтому export в вашей оболочке ещё не гарантирует, что npm или curl внутри Codex увидят значение. Надёжнее задать значения явно через ключ set этой политики:
[shell_environment_policy]
set = { NODE_EXTRA_CA_CERTS = "/Users/you/certs/corp-root-ca.pem", CURL_CA_BUNDLE = "/Users/you/certs/corp-bundle.pem" }NODE_EXTRA_CA_CERTS закрывает npm и остальные инструменты на Node. Остальные ключи политики и порядок их применения — в разделе о расширенной конфигурации; как устроены границы самой песочницы, разобрано в статье «Песочница Codex и config.toml: границы, подтверждения и сеть».
Проверка: попросите Codex выполнить curl -sS -o /dev/null -w "%{http_code}\n" https://registry.npmjs.org/ — в ответе должен быть код HTTP, а не ошибка 60.
Почему NODE_TLS_REJECT_UNAUTHORIZED=0 не исправляет ошибку
NODE_TLS_REJECT_UNAUTHORIZED=0, npm config set strict-ssl false, curl -k и --insecure не добавляют доверие к корпоративному сертификату — они выключают проверку целиком. Процесс после этого примет любой сертификат от любого узла на пути, а не только от прокси вашей компании. Документация Node.js прямо предупреждает, что значение 0 делает TLS-соединения уязвимыми для атаки «человек посередине».
Для Codex цена выше обычной: по этому соединению идут токены доступа (в ~/.codex/auth.json, который документация советует беречь как пароль), исходный код и результаты команд. Переменная, заданная в профиле оболочки, к тому же действует на все процессы Node, а не только на тот, что упал. Файл с корневым сертификатом решает ту же задачу и оставляет проверку включённой.

Когда остановиться и обратиться в ИТ-службу
Остановитесь и передайте вопрос ИТ-службе, если выполняется любое из условий:
- корневого сертификата нет в системном хранилище и вам его не выдают;
- издатель в выводе
openssl s_clientвам незнаком и не относится к компании; - сертификат передан нужному процессу, проверка файла проходит, а ошибка остаётся или сменилась отказом прокси;
- политика компании запрещает менять настройки доверия на рабочем компьютере.
Обходить корпоративные средства защиты не нужно: у ИТ-службы есть два штатных решения — выдать корневой сертификат (и промежуточные, если они есть) или исключить нужные хосты из инспекции. Чтобы обращение решили с первого раза, приложите к нему:
- точный текст ошибки и место, где она появилась (CLI, приложение, MCP-сервер, команда в песочнице);
- хост из ошибки или журнала;
- строки
s:иi:из выводаopenssl s_clientдля этого хоста; - версию Codex и операционной системы.
Файл ~/.codex/auth.json и переменные с ключами в обращение не вставляйте.
Короткие ответы об ошибке сертификата в Codex
Почему браузер и curl работают, а Codex выдаёт ошибку сертификата?
Потому что они читают разные хранилища. Браузер и системный curl используют хранилище операционной системы, куда ИТ-служба уже добавила корпоративный корень. Клиент Codex получает дополнительный корневой сертификат через CODEX_CA_CERTIFICATE, Node без NODE_USE_SYSTEM_CA=1 опирается на встроенный список, а команда в песочнице macOS может не дотянуться до связки ключей.
Нужно ли переустанавливать Codex или входить заново?
Переустановка доверие к сертификату не меняет. Повторный вход нужен только после того, как переменная задана: выполните codex login в том же терминале. Если Codex при запуске ждёт и завершается по тайм-ауту, а не ошибкой сертификата, смотрите разбор «Codex не загрузил cloud config bundle за 15 секунд: что проверить».
Почему ошибка сертификата появляется в Codex дома, без прокси?
Проверьте издателя той же командой openssl s_client. Вне корпоративной сети цепочку обычно переподписывает антивирус с проверкой HTTPS либо ошибка относится к вашему собственному шлюзу или MCP-серверу с сертификатом частного CA. В первом случае экспортируйте корневой сертификат антивируса, во втором — корень вашего CA, и передайте файл так же, как описано выше.



