CI/CD에서 Codex 계정 인증 유지하기(고급)
Codex의 기본 제공 갱신 흐름을 사용하여 신뢰할 수 있는 CI/CD 러너에서 auth.json이 계속 작동하도록 유지하세요
이 가이드에서는 OAuth 토큰 엔드포인트를 직접 호출하지 않고 신뢰할 수 있는 CI/CD 러너에서 ChatGPT가 관리하는 Codex 인증을 계속 작동하도록 유지하는 방법을 설명합니다.
자동화를 인증하는 올바른 방법은 API key를 사용하는 것입니다. 워크플로를 Codex 계정으로 실행해야 하는 특별한 경우에만 이 가이드를 사용하세요.
패턴은 다음과 같습니다.
- 신뢰할 수 있는 머신에서
codex login을 사용하여auth.json을 한 번 생성합니다. - 해당 파일을 러너에 배치합니다.
- Codex를 평소처럼 실행합니다.
- 세션이 오래되면 Codex가 세션을 갱신하도록 합니다.
- 갱신된
auth.json을 다음 실행을 위해 보관합니다.
이는 엔터프라이즈 및 기타 신뢰할 수 있는 비공개 자동화를 위한 고급 워크플로입니다. 대부분의 CI/CD 작업에는 여전히 API key가 권장됩니다.
이 방식이 작동하는 이유
Codex에는 ChatGPT가 관리하는 세션을 갱신하는 방법이 이미 내장되어 있습니다.
현재 오픈 소스 클라이언트 기준 동작은 다음과 같습니다.
- Codex는
auth.json에서 로컬 인증 캐시를 로드합니다 last_refresh이 약 8일보다 오래되면 실행을 계속하기 전에 Codex가 토큰 번들을 갱신합니다- 갱신에 성공하면 Codex는 새 토큰과 새
last_refresh을auth.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을 한 번 시드하기
브라우저 로그인이 가능한 신뢰할 수 있는 머신에서 다음을 수행하세요.
- Codex가 자격 증명을 파일에 저장하도록 구성합니다.
cli_auth_credentials_store = "file"- 다음을 실행합니다.
codex login- 파일이 관리형 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_token이true입니다
그런 다음 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 공유 러너 또는 기타 임시 환경을 사용하면 각 작업 후에 러너 파일 시스템이 사라집니다. 이 설정에서는 다음과 같은 왕복 과정이 필요합니다.
- 보안 저장소에서 현재
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 실행은 모두 세션을 갱신할 수 있습니다.
따라서 다음 두 가지 방법을 사용할 수 있습니다.
- 기존 CI/CD Codex 작업에서 파일을 자연스럽게 갱신하도록 합니다
- 실제 작업의 실행 빈도가 충분하지 않다면 위의 GitHub Actions 예시처럼 가벼운 예약 유지 관리 작업을 추가합니다
세션이 오래된 상태가 된 후 처음 실행되는 Codex 작업에서
auth.json을 갱신합니다.
중요한 운영 규칙
- 러너 또는 직렬화된 워크플로 스트림마다 하나의
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저장소를 다룹니다