~/VibeHandbook
무료 PDF

챕터 18 · 03

비밀값과 API 키: 노출된 키의 함정

비밀값은 접근을 허용하는 모든 것이다: (애플리케이션 프로그래밍 인터페이스) 키, 데이터베이스 비밀번호, 결제 제공자 토큰, 서명 키. 가장 흔하면서 — 또 가장 비싼 — 바이브 코딩 실수는 그중 하나를 새어나가게 하는 것이다.

사람들이 끊임없이 걸려드는 두 가지 함정:

  • 클라이언트 코드 안의 비밀값. 당신의 프론트엔드(브라우저에서 실행되는 JavaScript)에 있는 것은 무엇이든 공개다. 사용자는 개발자 도구를 열어 그것을 읽을 수 있다. AI에게 React 컴포넌트에서 API를 호출하라고 하면, 기꺼이 당신의 비밀 키를 거기 바로 붙여넣는다 — 그러면 이제 당신 사이트를 방문하는 누구나 그걸 복사해 당신의 청구서를 불려놓을 수 있다. 비밀 키는 서버에 있어야지, 브라우저로 배포되는 코드에는 절대 안 된다.
  • 저장소 안의 비밀값. 파일에 하드코딩된 키는 에 커밋된다. 나중에 지워도 git 히스토리에 영원히 남고, 봇들은 푸시 후 몇 분 안에 정확히 이걸 노리고 공개 저장소를 스캔한다.

비밀값의 올바른 거처는 **환경 변수()**다 — 런타임에 앱에 공급되는 값으로, 코드에서는 완전히 빠져 있다:

// VULNERABLE: 키가 소스에 들어 있고, git에 커밋될 것이다
const stripe = new Stripe("sk_live_51H8xQ2eZvK...");

// SAFE: 키는 환경에서 읽어오고, 코드에는 절대 쓰이지 않는다
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

비밀값에는 안전한 거처가 정확히 하나 있다 — 서버 측에서, 환경에서 읽어오는 것. 브라우저는 공개된 장소다: 거기로 배포된 것은 무엇이든 개발자 도구를 여는 누구라도 읽을 수 있다.

            ┌──────────────────────────────────────────┐
            │  .env  (gitignore됨, 커밋 안 함)          │
            │  STRIPE_SECRET_KEY=sk_live_...            │
            └───────────────────┬──────────────────────┘
                                 │ 런타임에 주입됨   
                                ▼
   ┌──────────────────────┐          ┌──────────────────────┐
   │   SERVER             │          │   BROWSER (클라이언트)│
   │   process.env.KEY ✓  │   ✗──────│   누구나 읽음         │
   │   여기서 Stripe 호출 │  금지    │   dev tools · "view   │
   │                      │  전송    │   source" · network   │
   └──────────────────────┘  여기    └──────────────────────┘
        안전: 비공개 유지                 공개: = 유출됨 

비밀값을 한 줄이라도 쓰기 전에 .env(그리고 .env.local 등)를 .gitignore에 추가하라. 키가 한 번이라도 당신의 코드나 히스토리에 들어갔다면, 타버린 것으로 취급하라: 로테이션하라(새 것을 생성하고 옛것을 폐기하라) — 줄을 지우는 것만으로는 부족한데, 옛 키는 여전히 유효하고 여전히 바깥에 떠돌기 때문이다.

오프라인으로 보고 싶으세요?

책 전체를 PDF나 EPUB으로 무료로 내려받으세요.