.env 시크릿을 깃에 안 올리고 관리하기 gitignore 실수 복구까지, AI 코딩 프로젝트에서 바로 쓰는 셋업

결론부터 말하면 .env 파일은 절대 커밋하지 않고, 값이 비어 있는 .env.example만 저장소에 올리는 방식이 가장 안전합니다. 이미 올렸다면 단순히 삭제로 끝나지 않습니다. 노출된 키를 폐기하고, Git 추적에서 제거한 뒤, 필요하면 커밋 기록까지 정리해야 합니다.

저장소에서 `git ls-files | grep .env`를 실행해 추적 중인 시크릿 파일부터 확인하세요.

Claude Code나 Cursor로 Next.js, Supabase, OpenAI API를 붙여 만들다 보면 AI 에이전트가 파일을 잘 생성해줘도 시크릿 관리까지 대신 책임져주지는 않습니다. 특히 자동 커밋, GitHub 연동, 배포 자동화까지 붙이면 한 번의 실수가 실제 비용으로 이어질 수 있습니다.

먼저 3분 점검부터 하세요.
현재 저장소에 .env가 추적 중인지 확인하고, .env.example과 .gitignore를 바로 맞춰두는 것이 첫 단계입니다.
git ls-files | grep .env

제가 쓰는 기본 구조: 진짜 값은 로컬과 배포 플랫폼에만 둔다

AI 코딩 에이전트로 작은 SaaS 프로토타입을 만들 때 저는 보통 이렇게 나눕니다. 로컬 개발자는 .env.local에 실제 값을 넣고, Git에는 .env.example만 올립니다. Vercel, Render, Railway 같은 배포 플랫폼에는 대시보드의 Environment Variables에 직접 등록합니다.

# .gitignore
.env
.env.*
!.env.example

# Next.js라면 보통 유지
.next
node_modules

.env.example에는 값 대신 이름만 둡니다.

OPENAI_API_KEY=
SUPABASE_URL=
SUPABASE_ANON_KEY=
DATABASE_URL=

이렇게 해두면 Cursor나 Claude Code에게 “.env.example 기준으로 설정 가이드를 README에 추가해줘”라고 시켜도 실제 키가 섞일 가능성이 줄어듭니다.

구체적 예: Next.js + Supabase + OpenAI 프로젝트

예를 들어 AI 요약 대시보드를 만든다고 가정해보겠습니다. 로컬에는 .env.local을 만들고 OpenAI 키, Supabase URL, anon key를 넣습니다. Git에는 .env.example과 README의 설정 방법만 커밋합니다.

Claude Code에 작업을 맡길 때는 프롬프트에 이렇게 못박아두면 좋습니다. “실제 API 키를 코드에 쓰지 말고, 환경변수 이름만 참조해. .env.example만 수정하고 .env.local은 건드리지 마.” 짧지만 효과가 큽니다.

gitignore를 넣었는데도 .env가 올라가는 이유

가장 흔한 함정은 이미 한 번 Git이 추적하기 시작한 파일은 .gitignore에 추가해도 자동으로 빠지지 않는다는 점입니다. 이때는 아래처럼 캐시에서만 제거해야 합니다. 로컬 파일은 남습니다.

git rm --cached .env
git commit -m 'Remove env file from git tracking'

여러 환경 파일이 이미 잡혀 있다면 조심해서 확인한 뒤 처리합니다.

git ls-files | grep '^.env'
git rm --cached .env .env.local

이미 GitHub에 푸시했다면 복구 순서가 다릅니다

원격 저장소에 올라간 순간, 시크릿은 유출된 것으로 보는 편이 안전합니다. 먼저 OpenAI, Supabase, Stripe, GitHub 토큰 등 해당 서비스에서 키를 즉시 폐기하거나 재발급하세요. 그다음 저장소에서 파일 추적을 제거합니다.

공개 저장소였거나 민감도가 높은 키라면 커밋 히스토리 정리도 필요합니다. 요즘은 git filter-repo를 권장하는 경우가 많고, 오래된 글에 자주 나오는 BFG Repo-Cleaner도 선택지입니다. 다만 히스토리 재작성은 협업자에게 영향을 주므로 팀에 공지한 뒤 진행해야 합니다.

# 예시: 히스토리에서 .env 제거 전용 작업은 별도 브랜치/백업 후 진행
# git filter-repo --path .env --invert-paths

정리 후에는 강제 푸시가 필요할 수 있습니다. 이 과정은 저장소 상태에 따라 위험할 수 있으니, 회사나 팀 프로젝트라면 관리자와 함께 처리하는 것이 좋습니다.

시크릿 관리 방식 비교

방식 적합한 상황 장점 주의점
.env + .env.example 개인·소규모 프로젝트 가볍고 빠름, AI 에이전트와 궁합 좋음 실수로 커밋하지 않게 점검 필요
Vercel/Railway 환경변수 배포가 있는 웹앱 서버에 키를 안전하게 주입 로컬 값과 배포 값이 달라질 수 있음
1Password/Doppler 팀 개발, 여러 앱 운영 권한 관리와 공유가 편함 도입 비용과 운영 규칙 필요
GitHub Actions Secrets CI/CD 자동화 빌드·배포 파이프라인에 적합 로그 출력에 키가 찍히지 않게 주의

상황별 추천: 어떤 도구를 쓰면 좋을까

혼자 빠르게 만드는 빌더라면

.env.local, .env.example, .gitignore 조합이면 충분한 경우가 많습니다. 여기에 GitHub의 secret scanning 알림을 켜두면 1차 방어선이 됩니다.

팀으로 운영하거나 외주 협업이 있다면

1Password나 Doppler처럼 권한을 나눌 수 있는 도구를 검토하세요. Slack으로 키를 주고받는 방식은 편하지만, 나중에 누가 어떤 키를 봤는지 추적하기 어렵습니다.

CI/CD까지 자동화한다면

GitHub Actions Secrets, Vercel Environment Variables처럼 실행 환경에 맞는 비밀 저장소를 쓰는 편이 좋습니다. n8n, Zapier, Make 같은 자동화 도구를 붙일 때도 토큰은 각 서비스의 credentials 저장소에 넣고, 워크플로 설명 문서에는 변수 이름만 남기세요.

실수 방지 체크리스트

  • 새 프로젝트를 만들자마자 .gitignore에 .env*를 추가한다.
  • 단, 공유용 !.env.example은 예외로 둔다.
  • 커밋 전 git statusgit diff --cached를 확인한다.
  • AI 에이전트에게 실제 키를 코드·문서에 쓰지 말라고 명시한다.
  • 푸시 후 키 노출을 발견하면 먼저 키를 폐기한다.

FAQ

.env.example에도 키 일부를 적어도 되나요?

권장하지 않습니다. 실제 값처럼 보이는 문자열은 넣지 말고 your_api_key_here처럼 명확한 플레이스홀더를 쓰세요.

.env를 지우고 커밋하면 노출 문제가 해결되나요?

아닙니다. 이전 커밋 기록에 남아 있을 수 있습니다. 특히 원격 저장소에 푸시했다면 키 재발급이 먼저이고, 필요하면 히스토리 정리가 뒤따라야 합니다.

GitHub private repo면 괜찮지 않나요?

비공개 저장소라도 협업자, 액션 로그, 토큰 권한, 계정 침해 가능성이 있습니다. 운영 키나 결제 관련 키는 노출된 것으로 보고 교체하는 편이 안전합니다.

Claude Code나 Cursor가 .env를 수정하지 못하게 할 수 있나요?

완전히 보장하기보다는 규칙을 겹쳐두는 방식이 현실적입니다. 프롬프트에 금지 규칙을 적고, .gitignore를 설정하고, 커밋 전 diff를 확인하세요. 가능하면 실제 키 파일은 에디터 작업 범위에서 제외하는 것도 좋습니다.

바로 할 다음 행동

지금 저장소 루트에서 git ls-files | grep .env를 실행해보세요. 아무것도 나오지 않으면 첫 관문은 통과입니다. 파일명이 나온다면 git rm --cached로 추적을 끊고, 원격에 올라간 적이 있는지 확인한 뒤 키를 교체하세요.

AI로 코드를 빨리 쓰는 시대일수록 시크릿 관리는 느리게, 확인하면서 가는 편이 결국 빠릅니다. 한 번만 기본 셋업을 만들어두면 다음 프로젝트부터는 복사해서 바로 시작할 수 있습니다.

관련 링크

글쓴이 용기

AI 코딩 에이전트로 직접 빌드하는 개발자. Claude Code·Codex 실사용 후기와 빌더 일지를 씁니다.

지식창고