바이브코딩 API 키 안 새게, 비용 폭탄 안 터지게
키를 코드에 그냥 적으면, 남이 내 카드번호로 긁는 거나 마찬가지예요.
API 키를 환경변수로 숨기고, 공개된 곳에 안 올리고, 한도·알림으로 요금 폭탄을 막는 법까지.
지난 편들에서 미뤄둔 보안 얘기를 제대로 풀어요.
API 편(Part 7)에서 “API 키는 절대 코드에 노출하지 말라”고 하고 미뤄뒀죠. 이번 편이 그 얘기예요.
왜 그렇게 강조했냐면, 키가 새면 남이 내 카드로 긁는 일이 벌어지거든요. 그것도 내가 모르는 사이에요. 겁주려는 게 아니라, 막는 법이 의외로 간단해서 꼭 짚고 가요.
이 편에서 얻는 것:
- 키가 새면 왜 위험한지
- 키를 안전하게 두는 실제 단계
- 비용이 갑자기 터지지 않게 막는 법
API 키 = 내 카드번호
Part 7에서 API 키를 출입증에 빗댔죠. 보안 얘기를 할 땐 한 발 더 나가 카드번호라고 보는 게 정확해요.
키는 “이 사람이 정식 사용자다”를 증명할 뿐 아니라, 그 키로 쓴 만큼 나에게 요금이 매겨져요. 그래서 키가 새면 남이 내 한도를 쓰고, 비용은 내가 물게 돼요.
왜 코드에 적으면 안 되나
여기서 많이들 오해해요. “내 코드는 나만 보는데 뭐 어때?”라고요.
문제는, 화면을 그리는 코드는 누구나 들여다볼 수 있다는 점이에요. 브라우저에서 마우스 오른쪽 버튼 몇 번이면 그 페이지의 코드가 그대로 보여요. Part 3에서 “JS 파일에 키를 그냥 적지 말라”고 했던 게 이 얘기였어요.
저는 실무에선 키를 코드에 둘 일이 없는데, 비전공자 친구들을 옆에서 도와보면 이게 의외로 자주 새요. 부주의해서가 아니에요. AI가 알아서 걸러주려니 하고 맡겨뒀다가, 뜻대로 안 풀리면 결국 “그냥 되게 해줘”로 넘어가요. 그러다 키가 코드에 그대로 노출된 채 배포되는 거죠.
공개된 저장소(예: 공개 GitHub)에 키를 올리는 건 더 위험해요. 새 키가 올라오는지 훑는 자동 프로그램이 돌아다녀서, 올린 지 몇 분 만에 주워가는 일도 흔해요.
비밀키는 코드 밖에 둬요
먼저 정리 하나. 지금처럼 정적 페이지 한 장만 있으면, 코드에 든 건 Supabase publishable key(예전 튜토리얼의 anon key 자리)뿐이에요. 그건 원래 공개돼도 되는 키라 숨길 게 없어요(뒤에 나오는 RLS로 지켜요).
숨겨야 하는 건 결제·메일·AI API처럼 쓴 만큼 돈이 나가는 비밀키예요. 근데 이런 키는 정적 페이지 코드에 두면 브라우저에서 다 보여요. 환경변수를 써도 결국 브라우저로 나가면 마찬가지고요. 그럼 이 비밀키는 어떻게 다루냐. 입문 단계에선 순서가 있어요.
먼저 키를 대신 들고 있어 주는 완성형 서비스가 있는지 봐요. 문의 메일은 폼 전송 서비스, 결제는 호스팅 결제 링크처럼요. 그럼 내 코드엔 키가 안 들어가고, 서버도 안 만들어요. 정적 그대로 끝나죠. 대부분은 여기서 해결돼요.
완성형 서비스가 없고 유료 API를 내 손으로 직접 불러야 할 때만, 비로소 Part 7의 ‘작은 서버’가 필요해요. 근데 이건 파일 드래그를 넘어서는 단계라, 솔직히 비전공자가 처음 혼자 하기엔 벅차요. Part 10에서 말하는 개발자에게 맡기거나 한 단계 올라서는 구간이에요. 아래 원칙은 그 서버를 둘 때 키를 어디에 두느냐예요. 코드도, 공개 저장소도 아니고 Cloudflare 대시보드의 환경변수죠.
두 파일은 딱 이렇게 생겼어요. 정말 이게 전부예요.
# .env (로컬 테스트용. 진짜 배포 키는 Cloudflare 대시보드 환경변수에)
OPENAI_API_KEY=sk-xxxxxxxxxxxx
# .gitignore (여기에 한 줄만 추가)
.env
점검할 때 쓸 프롬프트 (복붙용)
나는 index.html 한 파일짜리 정적 사이트를 Cloudflare Pages에 올려. [서비스 이름] API를 붙이려고 해.
1. 이 API 키가 브라우저에 노출돼도 되는 키인지, 숨겨야 하는 키인지
2. 숨겨야 한다면, 서버를 직접 안 만들고도 쓸 수 있는 완성형 서비스(폼 전송·호스팅 결제 등) 대안이 있는지
3. 그런 대안이 없다면, 비밀키를 안전하게 두는 원칙(코드·공개 저장소 금지, 사용량 한도, 노출 시 재발급)
초보자 기준으로 순서대로 알려줘.
알려주는 대로 따라 하면 되고, 막히는 화면이 나오면 그 부분을 캡처해 다시 물어보면 풀려요. Part 8에서 익힌 디버깅 흐름이랑 똑같아요.
비용이 터지지 않게
키를 지켜도, 비용은 따로 챙겨야 해요. Part 2에서 토큰이 곧 돈이라고 했죠. 외부 API도 같아요. 쓴 만큼 요금이 미터기처럼 올라가거든요.
겁낼 일은 아니에요. 미리 상한만 정해두면, 모르는 사이 새는 일을 막을 수 있어요.
- 무료 한도 확인
- 가입 전에 '무료로 월 몇 건'인지 보고, 한동안은 그 안에서 써요
- 사용량 알림
- '이만큼 쓰면 메일로 알려줘'를 걸어두면, 새기 전에 알아챌 수 있어요
- 결제 상한
- 한도를 걸면 그 위로 자동으로 막아주는 서비스도 있어요. 단, 서비스마다 달라요
이 설정들은 서비스 대시보드 어딘가에 있어요. 어디 있는지 모르면, 서비스 이름을 대고 AI에게 “여기서 사용량 알림이랑 결제 한도 어디서 설정해?”라고 물으면 짚어줘요.
여기서 조심할 게 하나 있어요. ‘한도 걸었으니 안전’은 아니에요. 서비스에 따라 진짜로 지출을 멈춰주는 곳도 있지만, 클라우드 서버(AWS·GCP·Cloudflare 등)의 예산 설정은 대개 알림까지만이고 지출 자체를 막지는 않아요. 그래서 한도를 걸었더라도, 무료 한도 안에서 쓰고 사용량을 이따금 확인하는 습관이 진짜 방어예요.
내 데이터, 아무나 못 건드리게
키 말고 한 가지 더요. Part 6에서 만든 목록은 지금 누구나 읽고 쓸 수 있게 임시로 열어둔 상태예요. 공개 배포 전에 이걸 좁혀야 해요.
여기서 보안은 키를 숨기는 것이 아니라 누가 접근할 수 있는지를 규칙으로 정하는 것이에요. Supabase에는 행 단위 접근 제어(RLS)라는 게 있어서, “읽기는 누구나, 쓰기는 막기” 같은 규칙을 걸 수 있어요.
참고로 Part 6에서 화면 코드에 넣은 publishable key가 딱 이런 경우예요. 그 키는 원래 공개돼도 되는 키라, 숨기는 대신 이 규칙으로 지켜요. 반대로 결제·메일처럼 쓴 만큼 돈이 나가는 키는 앞서 본 대로 작은 서버에 숨겨야 하고요.
여기엔 한계가 하나 있어요. “수정은 로그인한 나만”을 제대로 하려면 로그인(Authentication)을 붙여야 하는데, 그건 이 정적 시리즈 범위를 넘어가요. 로그인 없이 지금 할 수 있는 가장 안전한 조치는 방문자는 읽기만, 쓰기는 막기예요. 그러면 목록은 보여주되 아무나 고치진 못하고, 내용은 내가 Supabase 대시보드(내 계정으로 로그인된 화면)에서 관리하면 돼요.
AI에게 이렇게 시키면 돼요.
Supabase projects 테이블에서, Part 6에서 만든 '누구나 읽고 쓰기' 임시 정책을 먼저 지우고(DROP),
익명(anon)은 읽기(select)만 되고 쓰기(insert·update·delete)는 막히는 RLS 정책으로 바꾸는 SQL을 줘.
Supabase SQL Editor에 붙여넣을 거야.
Supabase 공식 문서를 같이 봐도 돼요. 방문자도 글을 남기게 하고 싶다면(방명록 등) 로그인이 필요하고, 그건 Part 10에서 말하는 ‘개발자에게 맡기거나 한 단계 올라서는’ 구간이에요.
공개 전 보안 점검
내놓기 전에 이것만 훑어요. 다 체크되면, 적어도 키와 비용으로 사고 날 일은 크게 줄어요.
공개 전 5분 점검
이 중 코드 안에 키가 그대로 박혀 있는지는, AI에게 코드를 보여주며 “여기 키가 노출돼 있으면 짚어줘”라고 물어보면 돼요. 다만 AI가 볼 수 있는 건 내가 보여준 코드까지예요. 이미 공개된 곳(깃허브 같은)에 올라갔는지는 AI가 알 수 없으니, 그건 해당 서비스의 노출 키 알림이나 커밋 기록으로 직접 확인해야 해요.
자주 묻는 질문
환경변수가 뭔지 아직 잘 모르겠어요.
값을 코드 바깥에 따로 보관하는 자리예요. 배포할 땐 배포 서비스(예: Cloudflare) 대시보드의 환경변수 자리에 '키이름=실제키'로 넣고, 로컬에서 테스트할 땐 '.env' 파일에 같은 값을 둬요. 코드에서는 실제 키 대신 그 이름표만 불러서, 누가 코드를 봐도 이름표만 보이고 키 자체는 안 보여요. 단, 이건 키를 서버 쪽(작은 서버·Functions)에서 쓸 때 얘기예요. 순수 정적 페이지에서 그대로 불러 쓰면 그 값이 화면 코드에 박혀 노출되니, 돈이 나가는 키는 서버를 거쳐 써야 해요. 만드는 법은 도구마다 달라서 AI한테 물으면 단계로 알려줘요.
Supabase의 publishable key도 숨겨야 하나요?
그 키는 원래 화면 코드에 들어가는 키라 숨긴다고 안전해지는 게 아니에요. 데이터는 접근 규칙(RLS)으로 지켜요. 반대로 결제·메일·AI API처럼 쓴 만큼 돈이 나가는 키는 꼭 환경변수로 숨겨야 해요.
무료로만 쓰면 비용 걱정은 없나요?
비용은 대체로 그래요. 다만 무료 한도를 넘기면 과금되는 서비스도 있으니, 결제 한도와 사용량 알림을 걸어두는 게 안전해요. 그리고 요금과 별개로, 키 자체는 무료든 유료든 똑같이 숨기고 공유하지 말아야 해요. 무료 키라도 남이 쓰면 내 한도가 막히고, 비밀키는 요금과 상관없이 내 데이터·계정을 열어줄 수 있거든요.
키가 새면 어떻게 되나요?
남이 그 키로 서비스를 쓰고 요금이 나에게 청구될 수 있어요. 그래서 새면 지우는 게 아니라 폐기하고 재발급받아요. 이미 나간 키를 무효로 만드는 게 가장 확실한 수습이에요.
레스덕의 정리
현직에서 제가 가장 조심하는 것 하나만 꼽으라면, 솔직히 키예요. 화려한 해킹보다, 키 한 줄이 실수로 새는 쪽이 더 아프거든요. 키가 담긴 파일을 무심코 공개로 올리는 실수는, 개발을 오래 한 사람도 한 번씩 겪어요.
다행인 건, 막는 법이 어렵지 않다는 거예요. 코드 바깥에 두고, 공개되는 곳엔 안 올리고, 한도를 걸어두기. 이 셋만 손에 익히면 입문 단계에선 충분해요.
겁먹고 미루기보다, 작은 습관으로 만들어 두세요. 입문이든 실무든, 한 번 데어보기 전에 챙기는 게 제일 싸게 먹혀요.
드디어 마지막이에요. Part 10에서 만든 걸 세상에 내놓고, 혼자 안 될 땐 언제 개발자를 부르는지까지 보며 시리즈를 닫아요.
여기 말고 다른 데서 막혔다면
증상만 고르면 지금 뭘 하면 되는지 짚어줘요.
참고 자료
읽으면서 떠오른 사람에게 공유해 주세요
레스덕
· 운영자현직 개발자가 AI·바이브코딩·개발자 커리어를 직접 겪고 판단한 개인 기록입니다. 공식 자료를 간략히 요약하고, 그 위에 저의 경험·판단을 덧붙입니다. 전문 자문이 아니므로, 중요한 결정 전에는 최신 원문과 전문가 상담을 함께 확인해 주세요.
최종 수정 2026.07.03 · 문의 lessduck2@gmail.com