---
title: "在 CI/CD 中維護認證"
description: "基於官方 Codex CI/CD 認證教程，講清 API key 預設路線、ChatGPT-managed auth 高階路線和 auth.json 的安全邊界。"
verifiedAt: "2026-05-06"
---

import { Cards, Card } from 'fumadocs-ui/components/card';

Codex 自動化認證的預設答案是 API key。只有當你確實需要讓 workflow 以你的 Codex account 身份執行時，才使用 ChatGPT-managed auth 的高階方案。

> [!CAUTION]
> `~/.codex/auth.json` 包含 access tokens，按密碼處理。不要 commit、貼工單、發聊天、進日誌、進 artifact，也不要用於 public 或 open-source repository。

<Cards>
  <Card title="CI/CD auth" href="https://developers.openai.com/codex/auth/ci-cd-auth">
    官方高階 `auth.json` 維護方案。
  </Card>
  <Card title="Non-interactive mode" href="/zh-Hant/docs/codex/official/01-products/28-non-interactive">
    大多數 CI 任務直接用 API key 跑 `codex exec`。
  </Card>
  <Card title="GitHub Action" href="/zh-Hant/docs/codex/official/06-team-integration/45-github-action">
    GitHub Actions 場景優先走官方 action 和 secret。
  </Card>
</Cards>

## 兩條路線

```mermaid
flowchart LR
    CI["CI/CD job"] --> API["API key secret"]
    CI --> Auth["ChatGPT-managed auth.json"]
    API --> Default["default route"]
    Auth --> Advanced["trusted private runner only"]
```

API key 路線：把 `CODEX_API_KEY` 或 action 需要的 OpenAI key 放進 CI secret，由 job 注入。它更容易發放、輪換和撤銷，是大多數自動化預設選擇。

ChatGPT-managed auth 路線：先在可信機器上 `codex login` 生成 `auth.json`，把它放到可信 runner，讓 Codex 在執行中使用內建 refresh flow，並把更新後的 `auth.json` 留給下一次 run。

第二條路線的核心不是“自己呼叫 refresh API”。官方推薦的是執行 Codex，讓 Codex 自己重新整理，然後持久化重新整理後的檔案。

## 怎麼選擇

用 API key：

- 普通 CI/CD。
- 公開儲存庫或開源儲存庫。
- GitHub Actions、GitLab CI、Jenkins 等常規自動化。
- 只需要跑 `codex exec` 或 Codex GitHub Action。
- 希望憑據容易輪換。

考慮 ChatGPT-managed auth：

- 必須以 Codex account 身份執行，而不是 API key。
- runner 是可信私有基礎設施。
- 遠端 runner 不能執行 browser login。
- 能在 runs 之間儲存重新整理後的 `auth.json`。
- 同一份 `auth.json` 不會被併發 job 或多臺機器同時使用。

有一項不滿足，就不要用 `auth.json` 方案。

## auth.json 風險

`auth.json` 不適合多機共享。一個 runner 或一個序列 workflow stream 使用一份獨立 copy。併發使用會導致 token refresh 互相覆蓋，最終出現 401 或無法重新整理。

Self-hosted runner 最適合高階方案，因為它能在 jobs 之間保留 `CODEX_HOME`。第一次缺檔案時 seed `auth.json`，後續不要每次用原始 secret 覆蓋它。

Ephemeral runner 也能做，但必須實現 restore、run、persist 閉環：

1. 從安全儲存恢復當前 `auth.json`。
2. 執行 Codex。
3. 把本次可能重新整理過的檔案寫回安全儲存。

關鍵點是寫回重新整理後的檔案，不是寫回原始 seed。

## 常見坑

- 在公開儲存庫裡用 ChatGPT-managed auth。
- 把 `auth.json` 當普通配置檔案。
- 每次 run 都覆蓋原檔案，丟掉重新整理後的 token。
- 多個併發 job 共享同一份 `auth.json`。
- 自己手寫 OAuth refresh 請求。
- refresh token 被 revoke、expired 或被別的機器旋轉後，沒有重新 seed。
- 把完整 `auth.json` 上傳 artifact。

## 出問題怎麼判斷

出現 401 時，先判斷：

- runner 是否能讀取當前 `auth.json`。
- 它是否被舊 secret 覆蓋。
- 是否有併發 job 使用同一份檔案。
- secure storage 的 restore / persist 是否成功。
- persist 是否寫回本次執行後的檔案。

仍然失敗時，不要手寫 refresh 請求。回到可信機器重新 `codex login`，生成新的 `auth.json`，重新 seed runner。

## 驗收清單

- API key 只存在 CI secret 中，日誌沒有列印。
- job 能執行 `codex exec`，失敗時能輪換 key。
- ChatGPT-managed auth 只在可信私有 runner 使用。
- `auth.json` 許可權收緊，沒有進入儲存庫、日誌和 artifact。
- 每次 run 後能保留重新整理後的檔案。
- 同一份 `auth.json` 不會被兩個 job 同時使用。
- 一旦懷疑洩露，立即重新登入、替換 secret、撤銷舊憑據。

## 官方資料

- [Maintain Codex account auth in CI/CD](https://developers.openai.com/codex/auth/ci-cd-auth)
- [Non-interactive mode](https://developers.openai.com/codex/noninteractive)
- [Codex GitHub Action](https://developers.openai.com/codex/github-action)
