Codex 로그인: 브라우저 없는 SSH 서버에서 쓰는 방법 3가지와 선택 기준
헤드리스 서버에서는 codex login --device-auth가 먼저입니다. 막히면 ssh -L로 1455 포트를 넘기거나 auth.json을 복사하고, 자동화에는 API 키를 씁니다.
목차

SSH로 접속한 서버나 컨테이너처럼 브라우저가 없는 곳에서 Codex CLI에 ChatGPT 계정으로 로그인하려면 codex login --device-auth부터 실행합니다. 터미널에 나온 주소를 휴대폰이나 노트북 브라우저에서 열고 일회용 코드를 입력하면 되고, 서버 쪽에는 브라우저도 열린 포트도 필요 없습니다. OpenAI 문서가 원격·헤드리스 환경에 먼저 권하는 방법도 이것입니다.
디바이스 코드 로그인이 계정이나 워크스페이스 설정에서 막혀 있으면 두 가지가 남습니다. 내 컴퓨터에서 ssh -L로 서버의 1455 포트를 끌어와 일반 브라우저 로그인을 그대로 쓰거나, 브라우저가 있는 머신에서 로그인한 뒤 ~/.codex/auth.json을 서버로 복사하는 것입니다. 사람이 터미널 앞에 없는 CI나 스케줄러는 로그인 대신 API 키나 액세스 토큰을 쓰는 쪽이 맞습니다.
아래 내용은 2026년 10월 2일 기준 최신 안정판인 Codex CLI 0.160.0에 맞춘 것이고, 어디까지가 직접 실행해 본 결과인지는 다음과 같습니다.
- 실제로 실행해 확인한 것: Ubuntu 24.04(glibc 2.39, OpenSSH 9.6p1)와 Codex CLI 0.160.0에서 축약 표기
127.1이 IPv4 루프백 주소로 해석되는 것, 이 표기를 대상으로 건 실제 SSH 포워딩이 동작하는 것, 그 포워딩이 Codex의 콜백 서버까지 닿는 것(상태 값 없이 보낸 요청에400 Bad Request와State mismatch응답), 1455가 사용 중일 때 1457로 넘어가는 것, 디바이스 코드 안내문과 15분 만료 표시. - 하지 않은 것: 어느 방법으로도 로그인을 끝까지 마치지 않았습니다. 브라우저에서 승인한 뒤의 화면은 본 적이 없고,
auth.json을 다른 머신에 복사해 쓰는 것과 토큰 갱신·폐기 동작도 실행해 보지 않았습니다. Alpine 같은 musl 기반 시스템은 확인하지 않았고, 터널 시험은 양쪽 끝이 같은 머신 한 대였습니다.
그래서 로그인 완료 이후의 절차는 OpenAI의 인증 문서와 0.160.0 소스 코드에 적힌 내용이며, 실행 결과가 아닌 대목은 그때마다 출처를 밝힙니다.
기본 codex login이 SSH 서버에서 끝나지 않는 이유
기본 로그인은 브라우저가 CLI와 같은 머신에 있다고 가정하기 때문입니다. codex login을 실행하면 CLI는 그 머신의 루프백 주소에 작은 콜백 서버를 띄우고 인증 URL을 출력합니다. 브라우저에서 로그인을 마치면 OpenAI 쪽이 브라우저를 그 콜백 주소로 돌려보내고, CLI가 거기서 인증 정보를 받아 저장합니다.
SSH 서버에서 출력된 URL을 내 노트북 브라우저에 붙여 넣으면 로그인 화면까지는 정상으로 진행됩니다. 문제는 마지막 단계입니다. 브라우저가 돌아가는 곳은 노트북 자신의 1455 포트인데, 콜백 서버는 원격 서버에서 기다리고 있습니다. 노트북에는 그 포트를 듣는 프로그램이 없으니 브라우저에는 연결 거부 화면이 뜨고, 서버 터미널의 codex login은 끝나지 않은 채 멈춰 있습니다.
CLI도 이 상황을 알고 있습니다. 브라우저 없는 Ubuntu에서 codex login을 실행하면 첫 줄에 "Starting local login server on" 뒤로 루프백 호스트 이름과 포트 1455가 붙은 주소가 나오고, 이어서 "If your browser did not open, navigate to this URL to authenticate:"와 auth.openai.com의 인증 URL이 출력됩니다. 0.160.0 소스에는 그 뒤에 붙는 문장이 하나 더 있습니다.
On a remote or headless machine? Use `codex login --device-auth` instead.세 가지 방법은 이 콜백 문제를 각각 다르게 풉니다. 디바이스 코드는 콜백 자체를 없애고, 포트 포워딩은 콜백이 서버까지 닿게 길을 내고, auth.json 복사는 로그인을 아예 다른 머신에서 끝냅니다.
어떤 방법을 고를까: 네 가지 조건으로 가르기
위에서부터 차례로 확인해서 처음 맞는 줄을 쓰면 됩니다.
| 내 상황 | 쓸 방법 | 먼저 갖춰야 할 것 |
|---|---|---|
| 휴대폰이든 노트북이든 브라우저가 있는 기기가 하나 있고, ChatGPT 보안 설정을 바꿀 수 있음 | 디바이스 코드 로그인 codex login --device-auth | ChatGPT 설정에서 디바이스 코드 로그인 허용. 워크스페이스 계정은 관리자가 켜야 함 |
| 디바이스 코드는 막혀 있지만 내 컴퓨터에서 서버로 SSH 포트 포워딩이 됨 | ssh -L로 콜백 포트를 넘기고 일반 codex login | 내 컴퓨터의 브라우저, 비어 있는 1455 포트 |
| 포워딩도 안 됨. 컨테이너이거나 중간 서버가 포워딩을 막음 | 다른 머신에서 로그인 후 auth.json 복사 | 인증 정보가 파일로 저장돼 있을 것. 복사본은 머신 한 대에서만 사용 |
| 사람이 없는 CI, 스케줄러, 스크립트 | API 키, CODEX_API_KEY, 관리형 워크스페이스의 액세스 토큰 | 과금이 ChatGPT 플랜이 아닌 API 사용량으로 바뀌는 점 확인 |

0.160.0의 codex login --help에 있는 로그인 플래그는 --device-auth, --with-api-key, --with-access-token 세 개와 status 하위 명령이 전부입니다. 콜백 포트를 바꾸는 플래그도, 브라우저를 열지 않게 하는 --no-browser 플래그도 없습니다. 예전 글에 나오는 --api-key는 사라졌고, 실행하면 키를 파이프로 넘기라는 안내와 함께 종료 코드 1로 끝납니다.
디바이스 코드 로그인: codex login --device-auth와 15분짜리 코드
서버에서는 명령 하나만 실행하고, 나머지는 브라우저가 있는 아무 기기에서 합니다. OpenAI 문서의 순서는 세 단계입니다.
- ChatGPT에서 디바이스 코드 로그인을 허용합니다. 개인 계정은 보안 설정에서, 워크스페이스는 관리자가 워크스페이스 권한에서 켭니다.
- 서버 터미널에서
codex login --device-auth를 실행합니다.codex를 처음 실행했을 때 나오는 선택 화면에서 Sign in with Device Code를 골라도 같습니다. - 터미널에 나온 링크를 브라우저에서 열어 로그인하고 일회용 코드를 입력합니다.
codex login --device-auth0.160.0에서 이 명령을 실행하면 터미널에 아래 안내문이 나옵니다. 코드 자리는 가렸습니다.
Follow these steps to sign in with ChatGPT using device code authorization:
1. Open this link in your browser and sign in to your account
https://auth.openai.com/codex/device
2. Enter this one-time code (expires in 15 minutes)
XXXX-XXXXX
Continue only if you started this login in Codex. If a website or another person gave you this code, cancel.실행해서 본 것은 이 안내문까지이고, 코드를 브라우저에 입력해 로그인을 마치는 단계는 OpenAI 문서의 설명입니다. 마지막 줄의 경고는 그대로 지켜야 합니다. 웹사이트나 다른 사람이 건넨 코드를 입력하면 그 사람의 CLI에 내 계정을 넘겨주는 셈이 됩니다. 소스 코드에 따르면 15분 안에 입력하지 않을 때 CLI는 device auth timed out after 15 minutes로 끝나며, 명령을 다시 실행해 새 코드를 받아야 합니다.
디바이스 코드 로그인 허용 설정은 어디에 있나
OpenAI 직원이 GitHub 이슈 #2798에서 밝힌 위치는 개인 계정이 chatgpt.com/#settings/Security, 워크스페이스 관리자가 chatgpt.com/admin/permissions입니다. 스위치의 공식 이름과 기본값, 어떤 플랜에서 쓸 수 있는지는 OpenAI 문서에 나와 있지 않습니다. 사용자들이 이슈에 적은 바로는 설정의 보안 항목 아래에 "Enable Codex Device Code Authorization"이라는 이름으로 보인다고 하니, 보안 설정에서 device code라는 단어가 들어간 항목을 찾으면 됩니다.
이 설정이 꺼진 상태에서도 터미널에는 코드가 발급될 수 있습니다. 사용자 보고에 따르면 브라우저에서 계정 선택과 2단계 인증까지 마친 다음에야 "Enable device code authorization for Codex in ChatGPT Security Settings, then run codex login --device-auth again."이라는 안내가 나옵니다. 로그인 화면이 계속 되풀이되는 것처럼 보인다면 설정부터 확인하는 편이 빠릅니다.
워크스페이스 계정은 관리자가 꺼 두면 구성원이 직접 켤 수 없습니다. 이때 사용자들이 본 문구는 "Please contact your workspace admin to enable device code authentication"입니다. 관리자에게 요청할 수 없는 상황이면 아래 두 방법으로 넘어갑니다.
이 기능은 문서에 베타로 표시돼 있고, 안정판에는 0.44.0(2025년 10월 3일)부터 들어갔습니다. 그보다 오래된 CLI를 쓰고 있다면 먼저 업데이트해야 하며, 방법은 Codex CLI 설치와 설정에 있습니다.
SSH 포트 포워딩: ssh -L로 1455 포트를 내 컴퓨터로 가져오기
내 컴퓨터의 1455 포트를 서버의 1455 포트에 이어 두면, 브라우저가 돌아가는 콜백이 터널을 타고 서버의 CLI까지 도착합니다. 일반 브라우저 로그인을 그대로 쓰는 방식이라 ChatGPT 쪽 설정을 바꿀 필요가 없습니다.

내 컴퓨터에서 포워딩을 걸고 서버에 접속합니다.
ssh -L 1455:127.1:1455 user@remote그 SSH 세션 안에서 로그인을 시작하고, 출력된 주소를 내 컴퓨터 브라우저에서 엽니다.
codex loginOpenAI 문서는 같은 명령의 포워딩 대상을 루프백 호스트 이름으로 적습니다. 위 명령의 127.1은 IPv4 루프백 주소의 표준 축약 표기로, 가리키는 곳은 같습니다. IPv4를 명시하는 데에는 이유가 있습니다. 0.158.0(2026년 9월 28일)부터 Codex의 콜백 서버는 IPv4 루프백에만 바인딩하는데, 루프백 호스트 이름을 IPv6 주소로 먼저 해석하는 머신도 있기 때문입니다. 이 표기는 Ubuntu 24.04(glibc 2.39, OpenSSH 9.6p1)에서 실행해 확인했습니다. getent ahosts 127.1이 IPv4 루프백 주소를 돌려주고, IPv4 루프백에만 바인딩한 서버가 이 주소로는 응답하지만 IPv6 루프백으로는 연결이 거부됩니다. codex login이 1455에서 기다리는 상태에서 대상을 127.1:1455로 적은 ssh -L 포워딩을 걸고 터널 너머 /auth/callback에 빈 요청을 보내면 HTTP/1.1 400 Bad Request와 본문 State mismatch가 돌아옵니다. 터널 없이 직접 보냈을 때와 같은 응답이며, 상태 값이 없는 콜백을 Codex의 콜백 서버가 거절한 것이므로 요청이 터널을 지나 그 서버까지 닿았다는 뜻입니다.
이 시험이 보여 주는 것은 거기까지입니다. 실제 브라우저 로그인의 콜백을 터널로 받아 로그인을 마친 것은 아니고, 터널의 양쪽 끝도 같은 머신이었습니다. 포워딩 대상 주소는 어느 경우든 서버 쪽에서 해석되지만, 서로 다른 두 머신 사이의 네트워크 경로는 거치지 않았습니다. Alpine처럼 musl을 쓰는 서버에서 127.1이 어떻게 해석되는지도 이 시험 범위 밖입니다. 그런 서버에서 터널이 연결되지 않으면 OpenAI 문서의 원래 명령을 그대로 쓰세요.
포트는 1455 고정, 사용 중이면 1457
콜백 포트는 소스 코드에 고정돼 있고 플래그나 설정으로 바꿀 수 없습니다. 설정 파일의 mcp_oauth_callback_port는 MCP 서버의 OAuth용이라 로그인과는 관계없습니다. 0.128.0(2026년 4월 30일)부터는 1455가 사용 중일 때 자동으로 1457로 넘어갑니다. 0.160.0에서 다른 프로그램으로 1455를 먼저 점유한 뒤 codex login을 실행하면 시작 안내의 포트가 1457로 바뀌어 출력됩니다. 소스 코드에 따르면 둘 다 막혀 있을 때만 Port … is already in use 오류로 끝납니다. OpenAI 문서에는 아직 1455만 적혀 있습니다.
여기서 따라 나오는 결론이 하나 있습니다. 서버의 Codex가 1457로 넘어갔다면 1455만 연 터널로는 콜백을 받을 수 없습니다. codex login은 시작할 때 실제로 연 포트를 출력하므로, 그 숫자가 1455가 아니면 터널을 그 포트로 다시 걸어야 합니다. 처음부터 두 포트를 함께 여는 방법도 있습니다. 이것은 문서에 없는 제안이고 위의 포트 동작에서 끌어낸 것으로, 아래 명령 자체는 실행해 보지 않았습니다.
ssh -L 1455:127.1:1455 -L 1457:127.1:1457 user@remote내 컴퓨터 쪽 포트 번호를 다른 숫자로 바꿔서 잇는 것은 통하지 않습니다. 브라우저가 돌아갈 주소에 포트 번호가 들어 있어서, 내 컴퓨터에서도 같은 번호로 받아야 합니다. 내 컴퓨터에서 Codex가 로그인 대기 중이거나 다른 프로그램이 1455를 쓰고 있으면 먼저 정리하세요.
WSL, VS Code Remote-SSH, Codespaces에서 콜백이 실패한다는 이슈에 대해 OpenAI는 방화벽이나 VPN 같은 로컬 네트워크 구성을 원인으로 꼽고 디바이스 코드 로그인을 권했습니다. VS Code Remote-SSH나 JetBrains Gateway의 자동 포트 포워딩이 이 콜백을 대신 처리해 주는지에 대한 공식 안내는 없습니다.
auth.json 복사: 다른 머신에서 로그인하고 파일을 옮기기
브라우저가 있는 머신에서 로그인을 끝낸 뒤 인증 캐시 파일을 서버의 같은 위치에 두는 방법입니다. 포워딩이 막힌 서버나 컨테이너에서 쓸 수 있고, OpenAI 문서에 명령까지 실려 있습니다.
- 브라우저가 있는 머신에서
codex login을 실행합니다. ~/.codex/auth.json이 생겼는지 확인합니다.- 그 파일을 서버의
~/.codex/auth.json으로 복사합니다.
SSH로 복사할 때:
ssh user@remote 'mkdir -p ~/.codex'
scp ~/.codex/auth.json user@remote:~/.codex/auth.jsonscp 없이 한 줄로:
ssh user@remote 'mkdir -p ~/.codex && cat > ~/.codex/auth.json' < ~/.codex/auth.jsonDocker 컨테이너로 복사할 때는 MY_CONTAINER를 컨테이너 이름이나 ID로 바꿉니다.
CONTAINER_HOME=$(docker exec MY_CONTAINER printenv HOME)
docker exec MY_CONTAINER mkdir -p "$CONTAINER_HOME/.codex"
docker cp ~/.codex/auth.json MY_CONTAINER:"$CONTAINER_HOME/.codex/auth.json"복사한 뒤 서버에서 chmod 600 ~/.codex/auth.json으로 권한을 좁혀 두는 것은 문서에 없는 일반적인 관행이지만 해 두는 편이 좋습니다. 이 파일에는 tokens 아래에 id_token, access_token, refresh_token이 들어 있고, OpenAI 문서도 비밀번호처럼 다루라고 적습니다. 저장소에 커밋하거나 티켓, 채팅에 붙여 넣으면 안 됩니다.
파일이 없을 때: 인증 정보 저장 위치 확인
~/.codex/auth.json이 보이지 않으면 인증 정보가 파일이 아닌 곳에 저장된 것입니다. 저장 위치는 config.toml의 cli_auth_credentials_store가 정하며, 값은 file, keyring, auto, ephemeral 네 가지입니다. 0.160.0 소스의 기본값은 모든 운영체제에서 file이지만, 직접 바꿨거나 관리자가 강제했다면 OS 자격 증명 저장소에 들어가 있을 수 있습니다. 이 경우 로그인하는 머신에서 아래처럼 설정한 뒤 다시 로그인해야 파일이 생깁니다.
cli_auth_credentials_store = "file"CODEX_HOME을 직접 지정했다면 파일은 ~/.codex가 아니라 그 디렉터리 아래에 있습니다. 서버에서 CODEX_HOME을 쓸 때는 그 디렉터리가 미리 존재해야 합니다.
auth.json 하나는 머신 한 대에만
복사본 하나를 서버 두 대에 나눠 쓰면 안 됩니다. OpenAI의 CI/CD 인증 가이드는 "Do not share the same file across concurrent jobs or multiple machines."라고 적습니다. 이유는 토큰 갱신에 있습니다. Codex는 last_refresh가 약 8일보다 오래됐거나 요청이 401을 받으면 토큰을 갱신하고 새 값을 auth.json에 다시 씁니다. 한 머신이 먼저 갱신하면 다른 머신에 남은 리프레시 토큰은 이미 쓰인 옛것이 됩니다.
처음 얼마 동안은 두 대가 모두 잘 돌아가는 것처럼 보일 수 있습니다. OpenAI 직원이 이슈 #10332에서 설명한 대로, 리프레시 토큰은 한 시간 안팎의 제한된 시간 동안은 여러 번 쓸 수 있고 그 뒤에 영구히 무효가 되기 때문입니다. 그 시간이 지나면 한쪽이 "refresh token was already used"가 들어간 오류와 함께 로그아웃됩니다. 서버가 두 대면 각각 따로 로그인하거나, 디바이스 코드 로그인을 서버마다 한 번씩 하세요.
원래 머신에서 다시 로그인하면 서버 쪽은 어떻게 되나
서버의 복사본이 무효가 될 수 있습니다. 2026년 6월 12일에 병합된 PR #27674 이후 codex login은 브라우저 방식이든 디바이스 코드 방식이든 시작하기 전에 그 머신에 저장돼 있던 인증 정보를 먼저 폐기하고 지웁니다. codex logout도 폐기 요청을 보냅니다.
여기서부터는 문서에 적힌 내용도 실행해 본 결과도 아닌, 이 동작에서 나오는 추론입니다. 노트북에서 로그인하고 auth.json을 서버로 복사한 뒤 노트북에서 다시 codex login이나 codex logout을 실행하면, 폐기되는 것은 서버가 들고 있는 것과 같은 인증 정보입니다. 그러면 서버는 다음 갱신 때 아래 오류를 만나게 됩니다.
Your access token could not be refreshed because your refresh token was revoked. Please log out and sign in again.복사한 뒤에는 원래 머신에서 로그인 상태를 건드리지 않는 것이 안전하고, 이 오류가 나면 다시 로그인해서 새 파일을 복사합니다.
CI와 자동화: API 키, CODEX_API_KEY, 액세스 토큰 중 무엇을 쓰나
사람이 코드를 입력해 줄 수 없는 환경에서는 로그인을 흉내 내지 말고 API 키를 쓰는 것이 OpenAI의 권고입니다. 브라우저 없이 한 줄로 끝납니다.
printenv OPENAI_API_KEY | codex login --with-api-key다만 이것은 ChatGPT 플랜을 브라우저 없이 쓰는 방법이 아닙니다. API 키로 로그인하면 사용량이 플랜에 포함된 한도에서 빠지지 않고 OpenAI Platform 계정에 표준 API 요금으로 청구됩니다. ChatGPT 워크스페이스나 클라우드 서비스에 의존하는 기능은 제한되거나 쓸 수 없고, Codex cloud는 ChatGPT 로그인이 필수입니다. 어느 쪽이 유리한지는 Codex API 키와 ChatGPT 구독 차이에서 과금 경로별로 비교할 수 있습니다.
codex exec로 비대화형 실행만 한다면 로그인 상태를 저장하지 않고 실행할 때만 키를 넘길 수도 있습니다.
CODEX_API_KEY=여기에_API_키 codex exec --json "triage open bug reports"비대화형 모드 문서에 따르면 CODEX_API_KEY는 codex exec, codex review, TypeScript SDK, codex exec-server --remote에서 쓸 수 있습니다. 대화형 codex는 이 변수를 읽지 않습니다. 그리고 환경 변수 문서가 인증용으로 나열하는 것은 CODEX_API_KEY와 CODEX_ACCESS_TOKEN이며, 환경에 OPENAI_API_KEY만 설정해 두는 것은 codex exec의 인증 수단으로 올라 있지 않습니다. 저장소의 코드가 함께 실행되는 작업에서는 키를 작업 전체의 환경 변수로 두지 말고, 위처럼 Codex를 실행하는 줄에만 붙이라는 것이 문서의 주의 사항입니다.
관리형 워크스페이스에서 ChatGPT 쪽 권한과 한도를 그대로 쓰면서 자동화해야 한다면 Codex 액세스 토큰이 있습니다. 워크스페이스 소유자가 권한을 켠 뒤 chatgpt.com/admin/access-tokens에서 만들고, 만료는 7·30·60·90일 중에서 고르며 직접 정할 때 가장 짧은 기간은 1일입니다.
printenv CODEX_ACCESS_TOKEN | codex login --with-access-token대상 플랜은 OpenAI 문서끼리 표현이 다릅니다. 인증 문서는 ChatGPT Enterprise 워크스페이스라고 쓰고, 액세스 토큰 문서는 ChatGPT Business와 Enterprise 워크스페이스에서 지원한다고 씁니다. Business 워크스페이스라면 관리자 화면에 해당 항목이 실제로 보이는지로 판단하세요.
ChatGPT 계정 인증을 CI에서 유지하는 방법도 문서에 고급 절차로 실려 있습니다. auth.json이 없을 때만 넣어 주고, 실행 중에 Codex가 갱신한 파일을 다음 작업까지 보존하는 방식입니다. 신뢰할 수 있는 비공개 러너에서만 쓰고 공개 저장소에서는 쓰지 말라는 조건이 붙어 있으며, 같은 문서가 대부분의 CI/CD 작업에는 여전히 API 키를 권합니다.
codex login status로 확인하고, 오류 문구별로 조치하기
어느 방법을 썼든 마지막에는 서버에서 상태를 확인합니다.
codex login status인증 정보가 있으면 Logged in using ChatGPT처럼 현재 방식이 표시되고 종료 코드는 0입니다. 없으면 Not logged in이 출력되고 종료 코드 1로 끝나므로, 스크립트에서 로그인 여부를 가르는 조건으로 쓸 수 있습니다.
중간에 막혔다면 문구로 원인을 좁힐 수 있습니다.
| 보이는 문구나 증상 | 뜻 | 조치 |
|---|---|---|
| 브라우저가 콜백 주소에서 연결 거부 화면을 띄움 | 브라우저가 있는 머신에서 그 포트를 듣는 프로그램이 없음. 터널이 없거나 포트가 다름 | ssh -L을 CLI가 출력한 포트로 다시 걸거나 디바이스 코드 로그인으로 전환 |
device auth timed out after 15 minutes | 일회용 코드 만료 | codex login --device-auth를 다시 실행 |
device code login is not enabled for this Codex server. Use the browser login or verify the server URL. | 디바이스 코드 발급 요청이 404를 받음 | 포트 포워딩이나 auth.json 복사로 전환. 사내 게이트웨이를 거친다면 서버 URL 설정 확인 |
| "Please contact your workspace admin to enable device code authentication" (사용자 보고) | 워크스페이스에서 디바이스 코드 로그인이 꺼져 있음 | 관리자에게 요청하거나 다른 방법 사용 |
Port … is already in use | 1455와 1457이 모두 사용 중 | 서버에 남아 있는 이전 codex login 프로세스를 종료 |
refresh token was revoked가 들어간 갱신 실패 | 저장된 인증 정보가 폐기됨. 다른 곳에서 다시 로그인했거나 로그아웃한 경우 | 다시 로그인하거나 새 auth.json을 복사 |
refresh token was already used가 들어간 갱신 실패 | 같은 auth.json을 여러 머신이나 동시 작업이 공유 | 머신마다 따로 로그인 |
ChatGPT login is disabled. Use API key login instead. | 관리자가 forced_login_method로 로그인 방식을 제한 | 허용된 방식으로 로그인. 반대 문구는 API key login is disabled. Use ChatGPT login instead. |
문구만으로 알 수 없을 때는 로그를 봅니다. codex login을 직접 실행하면 전용 로그가 남고, 기본 위치는 ~/.codex/log/codex-login.log입니다.
사내 TLS 프록시나 사설 루트 인증서를 쓰는 네트워크에서는 로그인 요청이 인증서 검증에서 막힐 수 있습니다. 이때는 로그인 전에 인증서 묶음을 지정합니다. 이 변수가 없으면 Codex는 SSL_CERT_FILE을 대신 읽습니다.
export CODEX_CA_CERTIFICATE=/path/to/corporate-root-ca.pem
codex login브라우저에서 승인까지 했는데 터미널이 403으로 끝난다면 원인이 헤드리스 환경이 아닐 가능성이 큽니다. 이 경우는 Codex 토큰 교환 403 실패에서 따로 진단합니다. 로그인 상태는 정상인데 요청마다 401이 난다면 Codex 401 Incorrect API key provided 오류 해결을 보세요. 로그인 도중 전화번호 인증을 요구받는 계정은 디바이스 코드 로그인으로 바꿔도 같은 요구를 받는다는 보고가 GitHub 이슈에 열려 있고, 아직 OpenAI의 공식 결론은 없습니다.
헤드리스 로그인에서 자주 헷갈리는 세 가지
같은 ChatGPT 계정으로 서버 여러 대에서 Codex를 쓸 수 있나요?
쓸 수 있지만 서버마다 따로 로그인해야 합니다. 문서가 금지하는 것은 같은 auth.json 파일을 여러 머신이 공유하는 것입니다. 서버마다 codex login --device-auth를 한 번씩 실행하면 서버별로 별도의 인증 정보가 발급되므로 갱신이 서로 엇갈리지 않습니다.
Docker 컨테이너 안에서는 어떤 방법이 맞나요?
터미널을 붙일 수 있는 컨테이너라면 디바이스 코드 로그인이 가장 간단합니다. 포트를 열 필요가 없기 때문입니다. 디바이스 코드가 막혀 있으면 호스트에서 로그인하고 위의 docker cp 명령으로 auth.json을 넣습니다. 컨테이너를 지우면 파일도 사라지므로 ~/.codex를 볼륨에 두어야 다시 로그인하지 않아도 되며, 그 볼륨을 동시에 실행되는 여러 컨테이너가 함께 쓰는 것은 파일 하나를 여러 머신이 공유하는 것과 같은 문제를 만듭니다.
헤드리스 로그인과 codex exec 헤드리스 실행은 같은 건가요?
다릅니다. 앞의 것은 브라우저 없는 머신에서 인증을 마치는 일이고, codex exec는 화면 없이 Codex에 작업을 시키는 비대화형 실행입니다. 둘은 이렇게 이어집니다. codex exec는 기본적으로 저장된 CLI 인증을 그대로 쓰므로, 위 세 가지 방법 중 하나로 로그인해 두면 추가 설정 없이 실행되고, 로그인 없이 돌리려면 CODEX_API_KEY를 넘깁니다.





