Codex는 기본적으로 OPENAI_API_KEY와 같은 환경 변수를 실행 명령어에 그대로 전달합니다:
요약
본 기사는 AI 코딩 도구 Codex가 실행 명령어에 환경 변수를 전달하는 보안 정책을 분석합니다. `config.toml`의 `shell_environment_policy` 설정이 이 과정을 제어하며, 기본적으로 API 키와 같은 민감한 변수가 자동으로 제외되지 않고 노출될 수 있습니다. 따라서 개발자는 추가 필터링 설정을 통해 보안을 강화해야 합니다.
핵심 포인트
- Codex는 기본적으로 OPENAI_API_KEY 등 환경 변수를 명령어에 전달합니다.
- `shell_environment_policy`를 통해 환경 변수 전달 여부를 제어할 수 있습니다.
- 민감한 변수는 자동 제외되지 않으므로, 명시적인 필터링이 필수적입니다.
- 테스트는 codex-cli 0.165.0의 sandbox 기능을 활용하여 진행되었습니다.
- Codex가 명령을 실행할 때 어떤 환경 변수를 전달하는지는
config.toml의[shell_environment_policy]에서 결정됩니다 (공식 Advanced Configuration의 "Shell environment policy" 섹션). 공식에 따르면ignore_default_excludes의 기본값은true이며, 이름에KEY,SECRET, 또는TOKEN을 포함하는 변수도 자동으로 제외하지 않습니다. 직접 테스트해 본 결과, 설정 없이도OPENAI_API_KEY나GITHUB_TOKEN(더미 값)이 그대로 명령어에 전달되었습니다. -ignore_default_excludes = false로 설정하면 이들은 제외되었습니다. 다만DB_PASSWORD나 URL 내부에 비밀번호가 포함된DATABASE_URL은 이름 패턴에 해당하지 않아 남아있었습니다. 이는filters에서 추가적으로 제외해야 합니다. - 확인은 codex-cli 0.165.0의codex sandbox(로그인 불필요)를 통해 진행했습니다. 로그인한 에이전트 본체가 실행하는 명령어에서는 테스트하지 않았습니다.
API 키를 export한 셸이나, .env 파일을 셸에 로드하는 메커니즘(direnv 등)을 사용하는 셸에서 AI 코딩 에이전트를 시작할 때, 해당 셸의 환경 변수가 에이전트가 실행하는 명령어에도 전달되는지 궁금했습니다.
Codex에는 전달할 환경 변수를 제한하는 shell_environment_policy라는 설정이 있습니다. 공식 설명과 실제 동작을 확인해 보았습니다.
-
codex-cli 0.165.0 (npm의
@openai/codex) - Debian GNU/Linux 13 (trixie), kernel 6.12.94 -
CODEX_HOME과HOME은 임시 디렉토리로 사용했으며,~/.codex에는 접근하지 않았습니다 - 값은 모두 더미입니다. 필자의 환경 변수가 섞이지 않도록,env -i를 사용하여 비운 환경에서 시작했습니다 -
codex sandbox -- <명령어>
(도움말 설명은 "Run commands within a Codex-provided sandbox")로, 샌드박스 내 명령어에서 보이는 환경 변수를env로 표시했습니다 -
로그인한 Codex 본체(에이전트 세션)가 실행하는 명령어에서의 동작. 공식 설명에는 "Codex가 시작하는 명령어(spawned commands)에 전달되는 변수"라고 되어 있으므로, 같은 설정이 적용될 것이라 추측합니다.
-
macOS 및 Windows에서의 동작.
Advanced Configuration의 "Shell environment policy" 섹션에는 다음과 같이 쓰여 있습니다.
shell_environment_policy
controls which environment variables Codex passes to spawned commands.
ignore_default_excludes
defaults to true, so Codex doesn't automatically remove variable names containing KEY, SECRET, or TOKEN. Set it to false to apply those automatic exclusions before your explicit filters run.
Configuration Reference에도 shell_environment_policy.ignore_default_excludes 설명으로 "(default: true)"라고 되어 있습니다. 또한 shell_environment_policy.inherit에는 all | core | none의 세 가지 값이 있습니다.
같은 섹션에 따르면, 처리 순서는 다음과 같습니다.
- 자동 제외 (
ignore_default_excludes = false일 때의 KEY / SECRET / TOKEN) -
filters의 `
(하나라도 있으면, 일치하는 변수만 남깁니다)
패턴은 대소문자를 구분하지 않으며, *와 ?를 사용할 수 있습니다 (동일 절).
더미(dummy) 변수를 넣어 사내 격리 환경(sandbox)의 env를 확인해 보겠습니다.
export OPENAI_API_KEY=dummy-openai GITHUB_TOKEN=dummy-gh STRIPE_SECRET=dummy-stripe
export AWS_ACCESS_KEY_ID=dummy-aws DB_PASSWORD=dummy-db DATABASE_URL=postgres://app:dummy-pass@db/app
export my_api_key=dummy-lower MONKEY_MODE=on
...
실행 결과 (HOME은 일회용 디렉토리입니다):
AWS_ACCESS_KEY_ID=dummy-aws
DATABASE_URL=postgres://app:dummy-pass@db/app
DB_PASSWORD=dummy-db
...
설정 없이 실행하면, 입력된 변수가 모두 명령어에 전달되었습니다. 이는 공식 문서의 "기본적으로 자동으로 제외하지 않는다"는 설명과 일치합니다.
codex sandbox -c shell_environment_policy.ignore_default_excludes=false -- sh -c "$show"
DATABASE_URL=postgres://app:dummy-pass@db/app
DB_PASSWORD=dummy-db
HOME=/workspace/gqx/tmp/codex-env/home
...
OPENAI_API_KEY,GITHUB_TOKEN,STRIPE_SECRET,AWS_ACCESS_KEY_ID는 사라졌습니다.- 소문자인
my_api_key도 사라졌습니다 (대소문자를 구분하지 않기 때문에). MONKEY_MODE도 사라졌습니다. 이름에KEY라는 문자열을 포함하기 때문입니다.
비밀이 아닌 변수가 사라져서 곤란할 때는, set으로 복구할 수 있습니다 (아래의 5. 참조).
- 이름에 KEY / SECRET / TOKEN을 포함하지 않았기 때문에
DB_PASSWORD와DATABASE_URL은 남아있습니다.DATABASE_URL은 URL 안에 비밀번호가 들어 있어도, 이름만으로는 판별되지 않습니다.
$CODEX_HOME/config.toml (일반적으로 ~/.codex/config.toml)에 다음과 같이 작성했습니다.
[shell_environment_policy]
ignore_default_excludes = false
[shell_environment_policy.filters]
...
codex sandbox -- sh -c "$show"
HOME=/workspace/gqx/tmp/codex-env/home
LANG=C.UTF-8
넣었던 더미 비밀 정보는 모두 전달되지 않게 되었습니다. 제외하고 싶은 변수 이름은 프로젝트마다 다릅니다. env | cut -d= -f1 | sort로 현재 환경 변수 이름을 목록화하여, 제외할 것을 결정해 주세요 (값은 표시되지 않습니다).
inherit = "core"로 설정하면, 처음부터 적은 수의 변수만 상속받게 됩니다.
codex sandbox -c 'shell_environment_policy.inherit="core"' -- sh -c "$show"
HOME=/workspace/gqx/tmp/codex-env/home
LANG=C.UTF-8
다른 시도에서는, inherit = "core"일 때 전달된 변수 중 남아있는 것은 HOME, LANG, PATH뿐이었습니다. core에 어떤 변수가 포함되는지에 대한 목록은 공식 페이지에서 찾을 수 없었습니다.
inherit = "none"일 때는 PATH마저 전달되지 않았고, env에는 CODEX_SANDBOX_NETWORK_DISABLED=1과 PWD만 표시되었습니다. 필요한 변수는 set으로 추가할 수 있습니다 (예: set = { PATH = "/usr/bin:/bin" }로 PATH를 설정).
이것이 전달되는 것을 확인했습니다).
set은 제외(exclusion) 이후에 적용되므로, 제외했던 변수를 복원할 수도 있습니다. ignore_default_excludes=false에 set={GITHUB_TOKEN="from-set"}을 추가하자, GITHUB_TOKEN=from-set이 전달되었습니다. 이는 공식 문서의 "Because set runs after exclusions, it can restore an excluded variable."와 일치합니다.
-
공식 문서에 따르면, 구형
exclude/include_only배열과[shell_environment_policy.filters]를 같은 설정 계층에서 함께 사용하면 Codex가 오류를 발생시킵니다 ("Shell environment policy" 섹션). - 이 설정이 걸러내는 것은 환경 변수입니다. 작업 폴더의.env파일 내용을 읽을 수 있는지 여부는 별개의 문제입니다. 파일을 읽지 못하게 하는 설정은 permission profile의deny를 통해 수행합니다 (공식 "Permissions"). 필자의 과거 글 「Codex CLI에 .env를 읽지 못하게 설정하기」에서 테스트했습니다. -
공식 문서에 따르면, 프로젝트의
.codex/config.toml파일은 해당 프로젝트가 신뢰될 때만 로드됩니다 (Advanced Configuration "Project config files"). 자신의 환경에서 확실히 적용하고 싶은 설정은 사용자 측의~/.codex/config.toml에 작성하는 것이 좋다고 생각합니다 (추측). -
Codex는 공식 기본 설정 상태에서는 KEY / SECRET / TOKEN을 포함하는 환경 변수도 자동으로 제외하지 않습니다. 설정을 하지 않았을 때, 더미 값인
OPENAI_API_KEY등이 명령어에 전달되었습니다 (codex 0.165.0의codex sandbox로 확인).ignore_default_excludes = false를 사용하면 이름에 KEY / SECRET / TOKEN이 포함된 변수는 제외되지만,DB_PASSWORD나DATABASE_URL같은 변수는filters에서 별도로 제외해야 했습니다.- 설정을 마친 후에는
codex sandbox -- env로 무엇이 전달되는지 한 번 확인해 보세요.
-
Advanced Configuration – Codex (Shell environment policy / Project config files)
-
Configuration Reference – Codex (shell_environment_policy.*)
-
Permissions – Codex
※ 사양은 2026-10-29 시점의 공식 문서를 기반으로 합니다. 동작은 Linux의 임시 환경에서 codex sandbox를 사용하여만 테스트했습니다.
업데이트 정보나 간단한 Tips는 X (@supportapp3_lab)에서 발신하고 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기