.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
- 보관함에 키 넣기: 웹 콘솔이나 예전
.env의OPENAI_API_KEY=sk-…같은 줄을 고르고 ⌃⌘C를 누르면, 환경변수 이름까지 채워진 보관함 새 항목이 열립니다. 확인하고 ⌘S로 저장합니다. 이미 있는 항목이라면 편집(⌘E) 화면의 터미널 환경변수에 이름을 적습니다(영문자·숫자·밑줄만, 숫자로 시작할 수 없음). - 명령 설치: 설정 ▸ 터미널 ▸ 설치.
~/.local/bin/cbvault가 앱 안의 명령을 가리킵니다. PATH에 없다면~/.zshrc에export PATH="$HOME/.local/bin:$PATH"를 추가하세요. - 명령을 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 파일 | 키체인 + security | cbvault 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는 키가 화면에 찍히므로 거절됩니다.