한국어

CI/CD에서 Codex 계정 인증 유지하기(고급)

Codex의 기본 제공 갱신 흐름을 사용하여 신뢰할 수 있는 CI/CD 러너에서 auth.json이 계속 작동하도록 유지하세요

이 가이드에서는 OAuth 토큰 엔드포인트를 직접 호출하지 않고 신뢰할 수 있는 CI/CD 러너에서 ChatGPT가 관리하는 Codex 인증을 계속 작동하도록 유지하는 방법을 설명합니다.

자동화를 인증하는 올바른 방법은 API key를 사용하는 것입니다. 워크플로를 Codex 계정으로 실행해야 하는 특별한 경우에만 이 가이드를 사용하세요.

패턴은 다음과 같습니다.

  1. 신뢰할 수 있는 머신에서 codex login을 사용하여 auth.json을 한 번 생성합니다.
  2. 해당 파일을 러너에 배치합니다.
  3. Codex를 평소처럼 실행합니다.
  4. 세션이 오래되면 Codex가 세션을 갱신하도록 합니다.
  5. 갱신된 auth.json을 다음 실행을 위해 보관합니다.

이는 엔터프라이즈 및 기타 신뢰할 수 있는 비공개 자동화를 위한 고급 워크플로입니다. 대부분의 CI/CD 작업에는 여전히 API key가 권장됩니다.

이 방식이 작동하는 이유

Codex에는 ChatGPT가 관리하는 세션을 갱신하는 방법이 이미 내장되어 있습니다.

현재 오픈 소스 클라이언트 기준 동작은 다음과 같습니다.

  • Codex는 auth.json에서 로컬 인증 캐시를 로드합니다
  • last_refresh이 약 8일보다 오래되면 실행을 계속하기 전에 Codex가 토큰 번들을 갱신합니다
  • 갱신에 성공하면 Codex는 새 토큰과 새 last_refreshauth.json에 다시 기록합니다
  • 요청에서 401을 받는 경우에도 Codex에는 기본 제공 갱신 후 재시도 경로가 있습니다

즉, 지원되는 CI/CD 전략은 "갱신 API를 직접 호출하는 것"이 아닙니다. "Codex를 실행하고 업데이트된 auth.json을 영구 보관하는 것"입니다.

사용해야 하는 경우

다음 조건을 모두 충족하는 경우에만 이 가이드를 사용하세요.

  • API key가 아니라 ChatGPT가 관리하는 Codex 인증이 필요합니다
  • 원격 러너에서 codex login을 실행할 수 없습니다
  • 러너가 신뢰할 수 있는 비공개 인프라입니다
  • 실행 간에 갱신된 auth.json을 보존할 수 있습니다
  • 지정된 auth.json 사본은 하나의 머신 또는 직렬화된 작업 스트림에서만 사용합니다

이 가이드는 Codex가 관리하는 ChatGPT 인증(auth_mode: "chatgpt")에 적용됩니다.

다음에는 적용되지 않습니다.

  • API key 인증
  • 외부 토큰 호스트 통합(auth_mode: "chatgptAuthTokens")
  • Codex 외부의 일반 OAuth 클라이언트

자격 증명이 OS 키링에 저장되어 있다면 먼저 파일 기반 저장소로 전환하세요. 자격 증명 저장소를 참조하세요.

auth.json을 한 번 시드하기

브라우저 로그인이 가능한 신뢰할 수 있는 머신에서 다음을 수행하세요.

  1. Codex가 자격 증명을 파일에 저장하도록 구성합니다.
cli_auth_credentials_store = "file"
  1. 다음을 실행합니다.
codex login
  1. 파일이 관리형 ChatGPT 인증 형식인지 확인합니다.
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_tokentrue입니다

그런 다음 auth.json의 내용을 CI/CD 비밀 관리자에 저장하거나 신뢰할 수 있는 영구 러너에 복사합니다.

권장 패턴: 자체 호스팅 러너의 GitHub Actions

가장 간단한 완전 자동화 설정은 영구 CODEX_HOME이 있는 자체 호스팅 GitHub Actions 러너입니다.

이 패턴이 효과적인 이유는 다음과 같습니다.

  • 러너가 작업 사이에도 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 공유 러너 또는 기타 임시 환경을 사용하면 각 작업 후에 러너 파일 시스템이 사라집니다. 이 설정에서는 다음과 같은 왕복 과정이 필요합니다.

  1. 보안 저장소에서 현재 auth.json을 복원합니다
  2. Codex를 실행합니다
  3. 업데이트된 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 실행은 모두 세션을 갱신할 수 있습니다.

따라서 다음 두 가지 방법을 사용할 수 있습니다.

  • 기존 CI/CD Codex 작업에서 파일을 자연스럽게 갱신하도록 합니다
  • 실제 작업의 실행 빈도가 충분하지 않다면 위의 GitHub Actions 예시처럼 가벼운 예약 유지 관리 작업을 추가합니다

세션이 오래된 상태가 된 후 처음 실행되는 Codex 작업에서 auth.json을 갱신합니다.

중요한 운영 규칙

  • 러너 또는 직렬화된 워크플로 스트림마다 하나의 auth.json을 사용하세요.
  • 동시 작업이나 여러 머신에서 같은 파일을 공유하지 마세요.
  • 실행할 때마다 원본 시드로 영구 러너의 갱신 파일을 덮어쓰지 마세요.
  • auth.json을 저장소, 로그 또는 공개 아티팩트 저장소에 저장하지 마세요.
  • 기본 제공 갱신이 중단되면 신뢰할 수 있는 머신에서 다시 시드하세요.

갱신이 중단된 경우 수행할 작업

이 흐름은 수동 작업을 줄여 주지만 같은 세션이 영구적으로 유지된다고 보장하지는 않습니다.

다음과 같은 경우 새 auth.json으로 러너를 다시 시드하세요.

  • Codex에서 401을 반환하기 시작하고 러너가 더 이상 갱신할 수 없습니다
  • 갱신 토큰이 취소되었거나 만료되었습니다
  • 다른 머신이나 동시 작업에서 먼저 토큰을 교체했습니다
  • 보안 저장소 왕복 과정이 실패하여 오래된 파일이 복원되었습니다

다시 시드하려면 다음을 수행하세요.

  1. 신뢰할 수 있는 머신에서 codex login을 실행합니다.
  2. CI/CD에 저장된 auth.json 사본을 교체합니다.
  3. 다음 러너 작업부터 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"

영구 러너를 사용하는 경우 실행 사이에도 같은 파일이 계속 존재해야 합니다. 임시 러너를 사용하는 경우 다시 쓰기 단계에서 마지막 작업의 업데이트된 파일을 저장하는지 확인하세요.

소스 참조

오픈 소스 클라이언트에서 이 동작을 확인하려면 다음을 참조하세요.