앱에서 API 키를 안전하게 지키는 법
API 키를 안전하게 지키려면, 호스트의 환경 변수나 비밀 값으로 저장하고, 서버 측 코드에서만 사용하고, 채팅, 코드 파일, 스크린샷, Git 저장소에는 절대 붙여넣지 마세요. 각 키에는 필요한 최소한의 권한만 주고, 제공업체에서 지출 한도를 설정하고, 키가 유출되면 단순히 노출된 곳을 숨기지 말고 교체하세요. 새 키를 만들고 이전 키를 삭제하는 것입니다.
API 키는 서비스의 비밀번호입니다. OpenAI 키는 누군가가 여러분의 돈으로 AI를 쓰게 하고, Stripe 비밀 키는 누군가가 환불을 발행하게 하고, 이메일 제공업체 키는 누군가가 여러분 이름으로 메일을 보내게 합니다. AI 앱 빌더는 이런 키를 연결하는 데 능숙하지만, 키가 어디에 남는지 항상 신경 쓰지는 않습니다. 그래서 이 가이드는 키를 안전하게 지키는 방법과 확인하는 방법을 다룹니다.
공개 키와 비밀 키
모든 키가 비밀은 아닙니다. 차이를 알아야 쓸데없이 당황하지도 않고, 정말 중요한 키를 놓치지도 않습니다.
| 유형 | 예시 | 브라우저에 둘 수 있나요? |
|---|---|---|
| 공개 가능 / 공개 키 | Stripe pk_… 키, 도메인으로 제한된 지도 키, 일부 분석 ID | 예. 그렇게 설계되었습니다 |
| 비밀 키 | Stripe sk_…, OpenAI와 Anthropic 키, 이메일 제공업체 키, 데이터베이스 비밀번호 | 절대 안 됩니다 |
| 서비스·관리자 키 | 호스팅 데이터베이스의 접근 규칙을 우회하는 키 | 절대 안 됩니다. 가장 민감한 것으로 다루세요 |
어떤 종류인지 확실하지 않다면 제공업체 문서를 확인하세요. 애매하면 비밀로 취급하세요.
1단계: 키는 코드가 아니라 비밀 값으로 저장하세요
키는 호스트의 환경 변수나 비밀 값 설정에 두세요. 코드는 실행 시점에 이름으로 읽습니다(예: process.env.OPENAI_API_KEY). 그래서 값이 파일에 전혀 나타나지 않습니다. 배경 지식은 환경 변수와 비밀 값이란 무엇인가를 참고하세요.
모든 API 키를 코드에서 빼서 환경 변수로 옮겨 주세요. 찾은 키마다 목록을 만들고, 어느 파일에 있었는지, 어떤 변수 이름을 썼는지 알려 주세요. 값은 보여 주지 마세요.
그다음 아무것도 남지 않았는지 확인하세요:
설정 파일과 .env 파일을 포함해 프로젝트 전체에서 API 키나 비밀번호처럼 보이는 것을 검색해 주세요. 값이 아니라 파일과 줄 번호를 보고하세요.
2단계: 비밀 키는 서버에서만 사용하세요
가장 중요한 규칙입니다. 브라우저가 받는 것은 무엇이든 방문자가 읽을 수 있습니다. 페이지 소스와 자바스크립트 파일은 모두 개발자 도구에서 보입니다.
그래서 앱이 OpenAI를 호출해야 한다면, 브라우저는 여러분의 서버를 호출하고, 서버가 키로 OpenAI를 호출해야 합니다. 키는 서버 밖으로 나가지 않습니다.
채팅 기능이 브라우저에서 OpenAI를 직접 호출하고 있어요. 그 호출을 서버 API 라우트로 옮겨 주세요. 라우트는 환경 변수의 OPENAI_API_KEY를 읽어야 합니다. 브라우저는 우리 라우트만 호출하게 하고, 라우트는 로그인을 요구하게 해 주세요.
프론트엔드 프레임워크에서 흔한 함정도 조심하세요. 공개 접두사가 붙은 변수(Vite의 VITE_, Next.js의 NEXT_PUBLIC_)는 의도적으로 브라우저 코드에 포함됩니다. 비밀 키에 이런 접두사를 붙이면, 그것이 “환경 변수에 있더라도” 노출됩니다.
3단계: 아무것도 새지 않는지 테스트하세요
잘 됐을 거라고 믿지 말고, 실제 사이트를 확인하세요:
- 브라우저에서 게시된 앱을 여세요.
- 개발자 도구를 열고 Sources 또는 Network 탭으로 가세요.
- 파일 전체에서 각 비밀 키의 앞부분(예:
sk_또는sk-)을 검색하세요. - 앱이 보내는 네트워크 요청을 확인하세요. 브라우저에서 유료 AI 제공업체로 바로 가는 요청은 빨간 신호입니다.
비밀 키가 보이면 2단계에 따라 서버로 옮기고, 6단계에 따라 교체하세요. 이미 공개되었기 때문입니다.
4단계: 각 키가 할 수 있는 일을 제한하세요
많은 제공업체는 키를 제한할 수 있게 합니다:
- 앱이 필요한 일만 할 수 있는 범위가 지정되었거나 제한된 키. 예를 들어 Stripe는 특정 권한을 가진 제한 키를 지원합니다.
- 공개되어야 하는 키(예: 지도 키)의 도메인이나 IP 제한.
- 앱과 환경별로 분리된 키. 하나가 유출되어도 모든 것이 노출되지 않고, 하나를 폐기해도 다른 것이 깨지지 않습니다.
- 개발 중에는 테스트 키, 게시된 앱에서만 실제 키.
5단계: 피해에 상한을 두세요
잘 보호된 키라도 여러분의 앱을 통해 악용될 수 있습니다. 예를 들어 누군가 AI 기능을 수천 번 스크립트로 호출할 수 있습니다.
- 모든 유료 제공업체에 지출 한도나 알림을 설정하세요.
- 호출당 돈이 드는 기능에는 로그인을 요구하세요.
- 사용자별 속도 제한을 추가하세요. 속도 제한이란 무엇인가를 참고하세요.
/api/chat에 사용자당 시간당 AI 요청 30회 제한을 추가해 주세요. 한도에 도달하면 분명한 메시지를 반환하세요. 로그인하지 않은 사용자의 요청은 거부하세요.
6단계: 유출된 키는 교체하세요
비밀 키가 있어서는 안 될 곳에 나타났다면, 예를 들어 채팅 메시지, 커밋, 스크린샷, 지원 티켓, 브라우저 코드에 있다면, 침해되었다고 가정하세요.
- 제공업체에서 새 키를 만드세요.
- 앱 설정에서 비밀 값을 업데이트하세요.
- 라이브 앱이 새 키를 쓰도록 다시 배포하거나 다시 게시하세요.
- 제공업체에서 이전 키를 삭제하세요.
- 제공업체의 사용 기록에서 모르는 활동이 있는지 확인하세요.
채팅 메시지나 Git 커밋을 삭제하는 것만으로는 충분하지 않습니다. Git 기록은 이전 버전을 보관하고, 공개된 것은 이미 복사되었을 수 있습니다.
흔한 실수
- 프롬프트에 키를 붙여넣기. 이제 채팅 기록에 남습니다. 대신 비밀 값 입력 양식을 쓰세요.
- 비밀 변수에 공개 접두사 붙이기.
VITE_OPENAI_API_KEY는 모든 방문자에게 키를 보냅니다. - .env 파일 커밋하기. 처음 push하기 전에
.gitignore에 있는지 확인하세요. - 모든 곳에 같은 키 하나. 테스트와 실제, 그리고 앱마다 키를 분리하세요.
- 지출 한도 없음. 유출되거나 악용된 키에 상한이 없으면, 알아차리기 전에 큰 요금이 나올 수 있습니다.
- 숨기기만 하고 교체하지 않기. 한 번 노출된 키는 새 키로 바꿔야만 해결됩니다.
- 스크린샷에 키 노출. 도움을 요청하기 전에 설정 페이지를 잘라내거나 흐리게 처리하세요.
체크리스트
- 모든 키는 코드가 아니라 비밀 값이나 환경 변수로 저장됨.
- .env 파일이나 키가 Git에 커밋되지 않음.
- 비밀 키는 서버 측 코드에서만 사용됨.
-
VITE_나NEXT_PUBLIC_같은 공개 접두사가 붙은 비밀 변수가 없음. - 라이브 사이트의 자바스크립트에서 각 키의 접두사를 검색했고 아무것도 없음.
- 제공업체가 허용하는 경우 키를 범위 지정하거나 제한함.
- 테스트 키와 실제 키가 분리됨.
- 돈이 드는 기능은 로그인과 사용자별 한도를 요구함.
- 모든 유료 제공업체에 지출 상한이나 알림이 있음.
- 각 키를 어떻게 교체하는지 알고 있으며, 한 번이라도 노출된 키는 모두 교체함.
Mythex에서 키를 안전하게 지키기
Mythex는 키를 코드와 채팅 밖에 두는 두 가지 방법을 제공합니다:
- 비밀 값 요청 카드. 에이전트에게 키가 필요하면 채팅에 카드가 나타나며, 메시지 입력창이 아니라 양식 필드에 값을 입력하고, 값은 프로젝트 비밀 값으로 저장됩니다. 채팅에서 비밀 값 사용하기를 참고하세요.
- 프로젝트 설정 → 비밀 값, 또는 채팅의
/secrets에서 직접 키를 추가하거나 바꿀 수 있습니다. 환경 변수와 비밀 값을 참고하세요.
게시된 앱의 비밀 값을 바꾼 뒤에는 라이브 앱이 반영하도록 다시 게시하세요. 내보낸 프로젝트에는 비밀 값이 포함되지 않으므로, 코드를 다른 곳에서 실행할 때 다시 추가해야 합니다. 키가 채팅에 나타난 적이 있다면, 제공업체에서 교체하세요.
출시 전 나머지 보안 점검은 AI로 만든 앱을 위한 보안 체크리스트를 따라가세요. AI 기능을 추가하는 중이라면, LLM API 사용법에서 키와 비용을 더 깊이 다룹니다.
자주 묻는 질문
프론트엔드 코드에 API 키를 넣어도 안전한가요?
제공업체가 그 키를 공개용으로 설계한 경우에만 괜찮습니다. 예를 들어 Stripe의 공개 가능 키나, 여러분의 도메인으로 제한된 지도 키가 그렇습니다. 돈을 쓰거나 비공개 데이터를 읽을 수 있는 키는 반드시 서버에 두어야 합니다. 브라우저로 보낸 것은 누구나 읽을 수 있기 때문입니다.
API 키를 채팅이나 공개 저장소에 붙여넣었다면 어떻게 해야 하나요?
키를 교체하세요. 제공업체에서 새 키를 만들고, 앱의 비밀 값을 업데이트하고, 다시 게시한 뒤, 이전 키를 삭제하세요. 메시지나 커밋을 지우는 것만으로는 충분하지 않습니다. 복사본이 이미 존재할 수 있기 때문입니다.
API 키는 어디에 보관해야 하나요?
호스트의 환경 변수나 비밀 값 설정에 두세요. 서버 측 코드가 실행 시점에 읽는 방식입니다. 소스 파일에 적거나, Git에 커밋하거나, 스크린샷에 포함하면 안 됩니다.
내 웹사이트에 API 키가 노출되었는지 어떻게 알 수 있나요?
실제 사이트를 열고, 브라우저 개발자 도구에서 페이지 소스와 자바스크립트 파일을 본 뒤 키의 앞부분을 검색하세요. 나타나면 노출된 것이므로 서버로 옮기고 교체해야 합니다.