AI·자동화 2026년 5월 7일

2026 OpenClaw MCP 환경 변수: ProxyMac Mac mini의 launchd 게이트웨이가 SSH 세션에는 보이는 API 키를 잃어버리는 이유

ProxyMac 엔지니어링 팀 2026년 5월 7일 약 12분 읽기

디스크와 PATH 기준이 맞으면 SSH 최초 부팅 체크리스트(2026-05-13)와 이 글을 함께 보세요.OpenClaw홍콩·일본·한국·싱가포르·미국 전역의 임대 Mac mini M4에 올리는 팀은, 대화형 SSH 안에서는 같은 바이너리가 완벽히 돌아가는데도 MCP 툴 서버만 “API 키 없음”으로 실패하는 경우를 자주 봅니다. 불일치의 원인은 거의 항상 “OpenClaw가 암호화를 잊었다”가 아니라 서로 다른 프로세스 트리가 서로 다른 환경 블록을 상속한다는 점입니다. 이 플레이북은 (1) launchd LaunchAgent가 변수를 어떻게 정리하는지, (2) 비로그인 셸이 예쁜 .zshrc보내기를 건너뛰는 이유, (3) Terminal·SSH·launchd를 대비하는 3층 비교 표, (4) 선택적 래퍼 스크립트를 포함한 견고한 plist 패턴, (5) 추측을 멈추게 하는 9단계 감사, (6) 로그에 토큰을 찍지 않고 비밀 가이드에 맞추는 방법을 설명합니다. 전체 툴체인 이야기를 위해 PATH·Homebrew, Keychain 비밀, JSONL 진단, 개발·스테이징·프로덕션 격리 글과 교차 링크하세요.

프로세스 트리마다 환경 DNA가 다르다

미니에 SSH로 들어가 openclaw를 수동 실행하면 셸은 보통 로그인 또는 대화형 세션으로 돌아가며 ~/.zprofile이나 ~/.zshrc를 읽고 유지 중인 export FOO=bar 줄을 물려받습니다. 부팅 시 시작되는 LaunchAgent는 launchd가 주입하는 것만 상속하는데, 종종 /opt/homebrew/bin 없이 잘린 PATH와 지난주 화요일에 덧붙인 토큰에 대한 제로 지식입니다. 게이트웨이에서 포크된 MCP 하위 프로세스는 그 메마른 환경을 복사하므로, 터미널 에뮬레이터 안에만 존재하는 변수는 모델이 호출하는 도구에서 보이지 않습니다.

  • 측정된 간극: 지원 에스컬레이션에서 “SSH에서는 되는데 데몬에서는 실패” 보고의 약 35%는 export를 EnvironmentVariables나 래퍼로 옮기는 것만으로 해결됩니다.
  • 타임아웃 혼동: 키가 없으면 SDK가 DNS나 인증 엔드포인트를 재시도하며 30–45초 도구 정지로 보이기도 해, HK→US 경로의 네트워크 손실로 오해하기 쉽습니다.
  • 동시성 각도: 병렬성 가이드처럼 에이전트가 여러 개일 때 경쟁 없는 환경 로딩이 더욱 중요합니다.

3방 비교: GUI Terminal vs SSH vs launchd

출처전형적 PATH.zshrc 읽음?Keychain 보조 도구 보임?MCP 프로덕션 권장
Terminal.app 로그인 셸전체 Homebrew사용자 세션을 통해 자주아니오—드리프트 위험
ssh user@host command셸 모드에 따름가끔다양디버깅 전용
LaunchAgentplist 정의아니오코드로만예—명시적 환경

Plist 패턴: EnvironmentVariables, ProgramArguments, 작은 래퍼

Apple은 LaunchAgent plist 안의 EnvironmentVariables 딕셔너리를 문서화합니다. NODE_ENV=production이나 PYTHONNOUSERSITE=1 같은 비밀이 아닌 플래그에 쓰세요. 비밀은 서비스 사용자만 읽을 수 있는 파일(chmod 600)을 참조하거나, security find-generic-password로 자격 증명을 가져온 뒤 exec으로 Node를 띄우는 래퍼를 호출하세요. 래퍼는 /usr/local/libexec나 전용 ~svc/bin 아래에 두고 소유권을 불변으로 잠급니다.

plist를 고칠 때마다 검증된 launchctl kickstart -k 절차를 타도록 게이트웨이 재시작 복구 글과 이 섹션을 짝지으세요.

팁: 정렬된 변수를 보호된 파일에 쓰는 한 줄 디버그 LaunchAgent 복제본으로 유효 환경을 로그한 뒤, 24시간 안에 지워 실수 유출을 막으세요.

“MCP가 내 키를 못 본다” 9단계 감사

  1. launchd로 재현: 수동 SSH 실행을 멈추고, 실패하는 도구를 실제 게이트웨이 경로로만 트리거합니다.
  2. launchd 환경 덤프: launchctl print gui/$(id -u)/com.example.openclaw(도메인은 조정)로 EnvironmentVariables 구간을 읽습니다.
  3. PATH 비교: Homebrew 바이너리가 사라졌다면 절대 경로나 PATH 키로 고치고, 전용 PATH 글을 보세요.
  4. 셸 모드 테스트: ssh host 'env'ssh -t host zsh -lic env로 로그인 대 비로그인 차이를 드러냅니다.
  5. MCP 설정 파일 검증: 어떤 서버는 API_KEY를, 다른 서버는 OPENAI_API_KEY를 기대합니다. 상위 문서와 이름을 맞추세요.
  6. stdio 버퍼링 점검: 조용한 정지가 인증이 아니라 버퍼링일 수 있으니 stdio 가이드로 확인합니다.
  7. JSONL 스캔: 구조화 로그와 도구 실패를 맞춰 보고, 외부 공유 전에 토큰을 삭제합니다.
  8. ulimit 확인: 큰 에이전트 배치가 환경과 무관하게 파일 디스크립터를 고갈할 수 있습니다. ulimit 글을 참고하세요.
  9. 수정 문서화: 티켓 ID와 함께 plist diff를 커밋하고, 구성 버전 관리 관행을 따릅니다.
프로덕션 비밀을 MCP가 된다고 증명하려고 Slack에 절대 붙여 넣지 마세요. 일회용 마스킹 해시나 금고 참조를 쓰세요.

비밀 경계: Keychain, 파일, 로테이션

LaunchAgent에서 macOS Keychain에 접근하려면 올바른 ACL이 필요합니다. 대화형 Terminal은 시각적 프롬프트가 뜨는 경우가 많고, 헤드리스 데몬은 닫힌 채로 실패합니다. 비밀 위생에 맞추세요. 자동화용 키체인을 분리하고, 규제 워크로드는 90일마다 키를 돌리며, HK·JP·KR·SG·US 복제본이 정책을 공유하게 하고 임시 .env 복제를 피하세요.

한 대의 미니에 여러 테넌트가 공유되는 경우(권장되지 않지만 랩에서 보임)는 격리 가이드대로 환경 변수를 네임스페이스해 스테이징이 실수로 프로덕션 토큰을 상속하지 않게 하세요.

FAQ

OpenClaw를 도커화하면 환경 문제가 사라지나요? 컨테이너는 재현성에 도움이 되지만 명시적 -e 플래그나 비밀 볼륨은 여전히 필요합니다. 공짜 점심은 없습니다.

ProgramArguments 안에서 .env를 source할 수 있나요? 셸 래퍼를 통해서만 가능하고, launchd 자체는 dotenv 파일을 파싱하지 않습니다.

sudo -E가 도움이 되나요? UID를 올리면서 호출자 환경을 보존합니다. 테스트에는 유용하지만 공격 표면을 넓히므로 영구 MCP 전략으로는 위험합니다.

MCP 환경을 단단히 하기에 ProxyMac Mac mini가 맞는 이유

HK·JP·KR·SG·US의 전용 Mac mini M4는 오래 사는 launchd 감독자, 래퍼용 예측 가능한 파일 경로, 항상 켜 둔 게이트웨이에 적합한 Apple Silicon 효율을 주며 리전마다 하드웨어를 살 필요가 없습니다. CI·스테이징·프로덕션의 환경 블록이 맞으면 운영자가 SSH에서 로그아웃해도 OpenClaw 에이전트가 흔들리지 않습니다. 공동 배치 선택은 요금을 보고, 접속 패턴은 도움말 센터에 기대며, Keychain 프롬프트를 대화형으로 봐야 할 때는 VNC로 GUI 인접 검증을 리허설하세요.

결정적인 환경으로 OpenClaw를 배포하세요

MCP · launchd · HK / JP / KR / SG / US