API 키를 .env 파일 없이 터미널에 넘기는 법 (맥)

업데이트

.env 파일이 새는 이유

.env 파일은 디스크에 있는 평문입니다. 내 계정으로 실행되는 모든 프로그램이 읽을 수 있고, 백업·동기화 폴더와 프로젝트를 읽는 AI 코딩 도구도 마찬가지입니다. .gitignore에서 한 줄 빠뜨리면 커밋되고, 열어 둔 채 화면을 공유하면 녹화에 남습니다. ~/.zshrc의 export 줄도 같은 문제가 있고, 그 셸에서 실행하는 모든 프로그램에 키를 넘깁니다.

macOS 기본 기능: 키체인

macOS에는 로그인 키체인에 비밀을 암호화해 저장하는 security 명령이 들어 있습니다.

# 한 번 저장 (-w 를 맨 끝에 두면 값을 물어봐서 셸 기록에 남지 않는다)
$ security add-generic-password -a "$USER" -s OPENAI_API_KEY -w

# 명령 하나에 넘기기
$ OPENAI_API_KEY="$(security find-generic-password -a "$USER" -s OPENAI_API_KEY -w)" npm run dev

디스크의 평문 키는 이걸로 없어집니다. 다만 로그인해 있는 동안 키체인은 열려 있어서, 내 계정으로 실행되는 어떤 프로그램이든 같은 security 명령으로 묻지 않고 키를 꺼낼 수 있습니다. 누가 읽었는지 남지 않고, 프로젝트마다 직접 연결해야 합니다.

CopyBuffer로: 요청마다 Touch ID

  1. 보관함에 키 넣기: 웹 콘솔이나 예전 .env의 OPENAI_API_KEY=sk-… 같은 줄을 고르고 ⌃⌘C를 누르면, 환경변수 이름까지 채워진 보관함 새 항목이 열립니다. 확인하고 ⌘S로 저장합니다. 이미 있는 항목이라면 편집(⌘E) 화면의 터미널 환경변수에 이름을 적습니다(영문자·숫자·밑줄만, 숫자로 시작할 수 없음).
  2. 명령 설치: 설정 ▸ 터미널 ▸ 설치. ~/.local/bin/cbvault가 앱 안의 명령을 가리킵니다. PATH에 없다면 ~/.zshrc에 export PATH="$HOME/.local/bin:$PATH"를 추가하세요.
  3. 명령을 cbvault로 실행: Touch ID 창에 어떤 프로세스가 어떤 이름을 요청하는지 보이고, 허락하면 그 명령과 하위 프로세스에만 값이 들어갑니다.
# 그 명령에만 넣어 실행 (가장 안전)
$ cbvault run OPENAI_API_KEY STRIPE_KEY -- npm run dev

# 지금 셸에 등록 / 값만 출력 / 등록된 이름
$ eval "$(cbvault export OPENAI_API_KEY)"
$ cbvault get OPENAI_API_KEY
$ cbvault list

# ~/.zshrc 에 한 줄 넣으면 cbload / cbunload 가 생긴다
$ eval "$(cbvault shell-init)"
$ cbload OPENAI_API_KEY
불러옴: OPENAI_API_KEY
$ cbunload OPENAI_API_KEY

dotenv 류 로더는 대부분 이미 설정된 환경변수를 덮어쓰지 않으므로, .env에서 키 줄만 지우고 나머지는 그대로 둬도 됩니다.

키를 지키는 장치

  • 요청마다 Touch ID(또는 Mac 로그인 암호). 같은 터미널에서 같은 이름은 5분 동안 다시 묻지 않고, 보관함을 잠그면 바로 취소됩니다.
  • 진짜 cbvault만: 앱은 본인만 접근할 수 있는 소켓(agent.sock, 0600)으로만 요청을 받고, 연결한 프로세스가 같은 사용자이며 앱과 같은 인증서로 서명된 cbvault인지 커널 감사 토큰으로 확인합니다. 복사하거나 고친 실행 파일은 거부됩니다.
  • 접근 기록: 요청한 프로세스 경로, 작업 폴더, 허락·거부가 보관함의 암호화된 기록에 남습니다.
  • 화면 녹화 고려: 화면을 녹화하거나 공유하는 중에는 잠긴 보관함을 열지 않고, 키가 화면에 그대로 찍히는 파이프 없는 cbvault get·cbvault export도 거절합니다. cbvault run과 eval "$(cbvault export …)"는 그대로 됩니다.
.env 파일키체인 + securitycbvault run
디스크에평문암호화암호화 (보관함)
꺼낼 때 확인없음로그인 중엔 없음Touch ID
값을 받는 범위그 파일을 읽는 모든 프로그램감싼 명령지정한 명령과 그 하위 프로세스
누가 요청했는지 기록없음없음프로세스·폴더·시각

한계

  • export·cbload로 셸에 등록한 값은 그 셸에서 실행하는 모든 프로그램이 볼 수 있습니다. 가능하면 cbvault run을 쓰세요.
  • 실행한 프로그램은 진짜 키를 받으므로, 그 프로그램이 로그에 남기거나 흘릴 수는 있습니다.
  • CopyBuffer가 실행 중이어야 하고, 보관함은 이 Mac에만 있습니다. 팀 공유와 동기화는 없습니다.
  • 내 Mac에서 쓰는 도구이지 CI·서버용이 아닙니다. 그쪽은 CI의 비밀 저장소를 쓰세요.

자주 묻는 질문

cbvault를 CI나 서버에서 쓸 수 있나요?

아니요. 내 Mac의 CopyBuffer 앱과 Touch ID가 있어야 합니다. 파이프라인에는 CI 서비스의 비밀 저장소를 쓰세요.

.env 파일을 읽는 도구도 계속 쓸 수 있나요?

네. .env에서 비밀 줄만 지우고 cbvault run 이름 -- 명령으로 실행하세요. dotenv 류 로더는 대부분 이미 환경에 있는 변수를 그대로 둡니다.

화면 공유 중에 cbvault를 쓰면 어떻게 되나요?

cbvault run과 eval "$(cbvault export …)"는 그대로 됩니다. 파이프 없는 cbvault get·cbvault export는 키가 화면에 찍히므로 거절됩니다.