저도 공공 API를 활용해 앱을 만든 적이 있습니다. 지금은 Cloudflare Workers를 서버 역할로 사용하면서 API 키도 그쪽에 보관해 두고 있습니다.

공공 API로 만들 수 있는 앱을 떠올려 보면, 이런 요청부터 시작할 수 있습니다.

“우리 동네 날씨와 미세먼지를 한 화면에 보여 주는 앱을 만들어 줘. 아침에 나가기 전에 휴대전화로 보고 싶어.”

AI가 화면을 만들고, 공공 API를 연결하고, 배포 방법까지 알려 줍니다. 휴대전화에 구름 아이콘과 미세먼지 정보가 나타납니다. 이제 친구에게 “이거 너도 써 봐”라며 링크를 보내고 싶어집니다.

바로 이때 확인할 것이 있습니다. 내가 공유하는 것은 날씨 화면뿐일까요? 데이터를 가져오는 인증키까지 함께 보내고 있지는 않을까요?

날씨와 미세먼지는 공개된 정보입니다. 하지만 그 정보를 내 계정으로 요청하는 권한까지 아무에게나 넘길 필요는 없습니다. 무료 API라 해도 호출 한도가 소진될 수 있고, 나중에 붙인 유료 지도나 AI 요약 기능은 비용을 만들 수 있습니다. AI가 개발을 대신해 주는 것과 앱의 권한·비용까지 알아서 안전하게 운영해 주는 것은 다른 문제입니다.

여기서 다룰 ‘동네날씨’는 설명을 위한 가상 앱입니다. 처음에는 공공 날씨·대기정보만 보여 주고, 이후 필요한 경우에만 즐겨찾기나 AI 요약을 붙이는 상황으로 살펴보겠습니다.

공개된 날씨와 내 인증키는 다른 것입니다

날씨 앱에서 API는 데이터 제공기관에 “이 지역의 예보를 보내 주세요”라고 요청하는 통로입니다. 인증키는 그 요청에 내 활용 신청과 이용 권한을 연결하는 데 쓰입니다. 화면에 보여 줄 정보와 그 정보를 요청할 자격을 분리해서 생각하면 이해하기 쉽습니다.

공공데이터포털의 기상청 단기예보 조회서비스는 무료로 안내되지만 인증키와 트래픽 조건이 있습니다. 에어코리아 대기오염정보도 무료입니다. 포털의 ‘신청 가능 트래픽’ 항목에 표시된 개발계정 수치는 기상청 10,000, 에어코리아 500으로 서로 다릅니다. 이 숫자를 내 운영 앱에 그대로 적용하지 말고, 각 서비스의 활용신청 내역과 승인된 조건을 확인해야 합니다. 기상청 단기예보 서비스, 에어코리아 대기오염정보

따라서 “무료니까 키가 보여도 손해가 없다”는 결론은 빠릅니다. 반대로 공공 API 인증키 하나가 보였다는 이유로 내 컴퓨터나 모든 계정이 해킹됐다고 결론 낼 필요도 없습니다. 그 키로 어떤 서비스를 호출할 수 있고, 어느 한도와 권한을 쓰는지가 피해 범위를 정합니다. 사용하는 API가 브라우저 직접 호출을 허용하는지, 공개 키나 출처 제한을 제공하는지도 서비스별로 확인해야 합니다.

동네날씨에서는 소유자의 공공 API 인증키를 서버에서 사용하고 방문자에게는 조회 결과만 전달하는 구조를 기본으로 잡겠습니다. 모든 API가 같은 키 정책을 가진다는 뜻이 아니라, 소유자 공통 키와 호출량을 한곳에서 관리하기 위한 설계입니다.

공격자에게도 AI라는 조수가 생겼습니다

작은 날씨 앱을 공개했는데 누군가 고도의 해킹을 시도할지부터 걱정하면 보안이 막연해집니다. 먼저 볼 것은 더 단순합니다. 밖으로 전달된 파일이나 요청에 재사용할 수 있는 인증 정보가 남아 있는가 하는 점입니다. 자동 수집은 AI 이전에도 가능했던 일이고, 공개된 키를 찾는 데 반드시 AI가 필요한 것도 아닙니다.

다만 공격자가 수집한 정보를 이해하고 도구를 고치고 후속 작업을 수행하는 과정에 AI가 활용되는 사례는 확인됐습니다. Anthropic의 2026년 9월 위협 보고서에는 고객 환경에서 탈취한 AI API 키가 다른 조직을 대상으로 한 공격에 약 3주간 사용된 사례가 나옵니다. 키 유출이 사용료 손실을 넘어 공격자의 작업 자원을 제공할 수 있다는 뜻입니다. Anthropic 위협 보고서

이 보고서는 업체가 관측한 특정 사례이지 전체 해킹의 AI 사용 비율을 보여 주는 통계는 아닙니다. 공공 날씨 키와 AI 서비스 키의 권한도 다릅니다. 여기서 가져올 판단 기준은 하나입니다. 공개 링크에 따라 나가는 정보 중에, 다른 사람이 내 계정의 자원으로 재사용할 수 있는 것이 있는가입니다.

“.env로 옮겼어요”라는 답변의 빈칸

AI에게 “키가 코드에 보이지 않게 해 줘”라고 요청했다고 해 보겠습니다. AI가 .env라는 설정 파일을 만들고, 코드 속 긴 키 문자열을 변수 이름으로 바꿉니다. 설명도 그럴듯합니다. “환경 변수로 분리했습니다.”

그런데 이 말에는 그 변수를 어디에서 사용하는지가 빠져 있습니다. 환경 변수는 설정값을 코드와 분리해 전달하는 방법입니다. 서버 안에 머무는지, 방문자의 브라우저로 전달되는지까지 파일 이름이 결정하지는 않습니다.

프론트엔드는 방문자의 브라우저에서 실행되는 부분입니다. 백엔드는 운영자가 관리하는 서버에서 처리하는 부분입니다. 브라우저가 인증키를 붙여 공공 API에 직접 요청한다면 브라우저도 그 값을 사용할 수 있어야 합니다. 화면에 키가 안 보여도 내려받은 JavaScript나 개발자 도구의 요청 내역에는 나타날 수 있습니다.

Vite는 VITE_로 시작하는 환경 변수를 클라이언트 코드에 노출하도록 설계돼 있습니다. 다음은 소유자 전용으로 관리하려는 인증키를 브라우저에 전달하게 될 수 있는 잘못된 배치 예시입니다. 값은 작동하지 않는 설명용 문자열입니다. Vite 환경 변수 문서

Text
# 피해야 할 예시: Vite 프로젝트의 .env
VITE_WEATHER_SERVICE_KEY=EXAMPLE_NOT_A_REAL_KEY

브라우저 코드가 import.meta.env.VITE_WEATHER_SERVICE_KEY를 읽어 요청에 쓰면, .env를 Git에 올리지 않았어도 값은 배포 결과에 포함될 수 있습니다. Next.js의 NEXT_PUBLIC_ 역시 브라우저에 값을 포함시키는 용도입니다. 접두사를 바꾸기만 하면 브라우저의 API 호출이 자동으로 서버로 옮겨지는 것은 아닙니다. 키를 사용하는 요청을 서버로 이동하고, 브라우저에는 필요한 데이터만 돌려줘야 합니다. Next.js 환경 변수 문서

같은 날씨·미세먼지 화면을 공유받은 방문자가 브라우저에 함께 전달된 인증 열쇠를 발견하고, 제작자와 AI 조수가 이를 살펴보는 장면
공유할 것은 날씨 조회 결과입니다. 방문자에게 전달한 파일과 요청에 소유자의 인증키가 들어가면, 화면에서 가려도 방문자가 가진 정보가 됩니다.

공공 API처럼 요청 URL에 인증키를 넣는 방식이라면 디버깅도 조심해야 합니다. “오류를 봐 달라”며 요청 주소 전체나 Network 화면을 캡처해 공개 게시판에 올리면, 코드에서는 지운 키를 질문 글로 다시 공개할 수 있습니다. URL 인코딩으로 문자가 달라져 보이는 것 역시 비밀을 암호화했다는 뜻은 아닙니다. 로그에는 실제 키를 가리고, 어떤 서비스·조건에서 오류가 났는지만 남기는 편이 좋습니다. OWASP 비밀 정보 관리 지침

코드를 압축하거나 변수 이름을 난해하게 만들어도 방문자에게 전달됐다는 사실은 달라지지 않습니다. 모바일 앱이나 데스크톱 프로그램에도 소유자의 장기 비밀 키를 그대로 넣는 방식을 피해야 합니다. 앱 안에서 풀 수 있도록 암호문과 복호화 수단을 함께 넣는 것도 같은 문제를 남깁니다. OWASP 앱 패키지의 비밀 정보

무료 앱이 멈추는 이유는 키 유출만이 아닙니다

이제 브라우저는 내 서버의 /api/weather?region=...에 요청하고, 서버가 인증키를 붙여 데이터를 가져오도록 고쳤습니다. 방문자는 키 원문을 받지 않습니다. 여기서 “보안 수정 완료”라고 끝내면 놓치는 것이 있습니다.

여기서 서버를 직접 빌려 관리해야 한다는 뜻은 아닙니다. 사용하는 앱 제작 도구나 호스팅의 서버 함수·비밀 설정 기능을 쓸 수도 있습니다. 중요한 것은 방문자에게 보내지 않는 실행 영역이 실제로 있느냐입니다. 정적 웹페이지에 환경 변수 이름 하나를 추가했다고 그 영역이 생기는 것은 아닙니다.

제가 사용하는 Cloudflare Workers도 이런 서버 역할을 맡길 수 있는 서비스입니다. 별도 서버를 직접 관리하는 대신 요청을 처리할 코드를 실행합니다. 날씨 앱에 적용한다면 브라우저는 Worker에 지역을 요청하고, Worker가 서버 쪽 인증키를 사용해 제공기관에서 데이터를 받아 필요한 결과만 돌려주도록 구성할 수 있습니다. Cloudflare Workers 소개

Workers에는 API 키 같은 민감한 값을 코드와 분리해 다루는 Secrets 기능도 있습니다. 공개 코드에 값을 적는 대신 Worker가 실행될 때 접근할 수 있는 비밀 설정으로 관리하는 방식입니다. 다만 이 기능을 사용해도 코드가 키를 응답이나 로그에 넣으면 다시 노출될 수 있습니다. 키의 보관 위치를 정한 뒤에는 Worker가 어떤 요청을 받아 주고 무엇을 반환하는지도 확인해야 합니다. Workers의 Secrets

방문자가 새로고침할 때마다 서버가 기상청과 에어코리아를 다시 조회하면 어떻게 될까요? 같은 동네의 같은 발표 자료를 반복해서 받아 올 수 있습니다. 공격자가 없어도 정상 사용만으로 호출량이 불어납니다.

단순한 계산을 해 보겠습니다. 방문자 100명이 각각 10번 화면을 열고, 화면을 열 때마다 두 API를 한 번씩 조회한다고 가정하면 기상청에 1,000회, 에어코리아에 1,000회를 요청합니다. 두 서비스의 합계는 2,000회지만, 어느 한도를 넘는지는 서비스별 1,000회를 각각 비교해야 합니다. 실제 호출 횟수는 앱의 요청 방식에 따라 달라지며, 이 수치는 실측이나 허용량이 아닌 계산 예시입니다.

수정할 지점은 캐시, 즉 이미 받은 결과를 일정 조건 동안 보관해 다시 사용하는 부분입니다. 같은 지역·발표 시각의 공용 자료라면 서버가 보관한 결과로 여러 방문자에게 응답할 수 있습니다. 방문자 수와 원본 API 호출 수를 분리하는 것입니다. 다만 서버를 여러 개 띄웠는데 각각 따로 보관하면 그만큼 원본 조회가 늘 수 있으므로, 실제 배포 구조에 맞는 공유·중복 방지도 필요합니다.

여러 사람이 같은 동네 날씨를 볼 때마다 관측 자료를 반복해서 가져오는 모습과 서버에 보관한 같은 자료를 나눠 주는 모습을 비교한 장면
날씨 화면을 여는 횟수와 원본 API를 조회하는 횟수는 같을 필요가 없습니다. 공용 자료의 캐시를 설명한 개념 장면입니다.

보관 시간을 무조건 길게 잡으면 오래된 날씨를 최신처럼 보여 주는 문제가 생깁니다. API마다 발표·관측 시각과 제공 방식이 다르므로, 데이터가 언제 갱신되는지에 맞춰 캐시를 갱신해야 합니다. 화면에도 자료의 기준 시각과 오래된 값인지 알 수 있는 상태를 표시합니다. 원본 조회에 실패했을 때 마지막으로 받은 값을 보여 줄 수는 있지만, 방금 갱신한 값처럼 꾸며서는 안 됩니다.

캐시만으로 악용까지 해결되지는 않습니다. 누군가 지역·시간 조건을 계속 바꿔 캐시에 없는 요청을 만들 수 있기 때문입니다. 앱에서 지원하는 지역과 조회 범위를 서버가 정하고, 한 번에 가져올 양과 요청 빈도, 재시도 횟수를 제한해야 합니다. 클라이언트가 전달한 아무 URL로나 인증키를 붙여 보내는 범용 중계기로 만들면 안 됩니다. OWASP도 요청 횟수뿐 아니라 요청 하나가 소비할 자원의 범위를 제한하도록 권고합니다. OWASP API 자원 소비 위험

호출 실패 시 무한 재시도를 붙이면 장애가 호출량을 더 늘릴 수도 있습니다. 재시도를 멈추는 조건과 사용자에게 보여 줄 상태를 정하고, 승인된 트래픽이 부족하면 운영 신청·증설 조건을 확인합니다. 한도 부족을 여러 키로 우회하도록 AI에게 요구하는 것은 운영 설계를 대신하지 못합니다.

유료 기능을 붙일 때는 계산이 달라집니다

여기까지의 동네날씨는 AI로 만들었지만 AI 모델을 호출하는 앱은 아닙니다. 기상청·에어코리아 조회가 무료라는 사실과 별개로, 배포 서버의 비용은 호스팅 계약에 따라 달라질 수 있습니다. 앱에서 어떤 동작이 어느 서비스의 사용량을 만드는지 나눠 봐야 합니다.

이제 “날씨를 한 문장으로 요약해 줘”, “지도를 더 자세히 보여 줘” 같은 기능을 추가하고 싶어졌다고 해 보겠습니다. 유료 AI나 과금형 지도 서비스를 선택했다면 그때부터는 새로운 비용 경계가 생깁니다. 무료 날씨 조회에 쓴 통제를 그대로 복사해 끝낼 수는 없습니다.

예를 들어 “오늘 날씨 요약” 버튼은 서버에 키를 숨겨도, 누구나 무제한 호출할 수 있으면 내 비용을 쓸 수 있습니다. 로그인 사용자에게만 열기로 했다면 서버가 인증을 검사하고, 계정별 사용량·한 번에 처리할 입력과 출력·전체 서비스 중지 조건을 정해야 합니다. 동시에 들어온 요청이 같은 잔여량을 중복 사용하지 않도록 차감도 서버에서 일관되게 처리합니다.

그런데 공개 날씨 화면까지 모두 로그인 전용으로 바꿀 필요는 없습니다. 공용 자료의 조회, 개인 즐겨찾기 수정, 유료 요약 생성을 서로 다른 요청으로 나누면 됩니다. 동네 날씨는 누구나 볼 수 있게 두고, 비용이나 개인 정보가 걸린 동작에 맞는 검사를 붙이는 것입니다.

예산 알림은 지출을 알려 주는 기능이고, 사용 중단 한도는 추가 요청을 막는 기능입니다. 제공자가 어느 기능을 지원하고 집계·차단에 지연이 있는지 확인해야 합니다. CORS로 허용한 웹사이트를 좁히는 것도 보조 조치일 뿐, API 호출자의 권한이나 사용량을 제한하는 장치를 대신하지 못합니다. OWASP REST 보안 지침

AI에게 실제 키를 보여 줘야 연결할 수 있을까요

동네날씨를 만들다 보면 “인증키를 여기에 넣으세요”라는 안내를 만나게 됩니다. 이때 실제 값을 대화창에 붙이기 전에, AI가 키를 넣을 위치와 변수 이름만으로 구현할 수 있는지부터 확인할 수 있습니다.

예를 들어 서버의 비밀 설정 이름을 WEATHER_SERVICE_KEY로 정하고, AI는 그 이름을 읽어 요청하는 코드를 만듭니다. 실제 값은 소유자가 호스팅의 비밀 설정 영역에 넣습니다. 서버가 실행할 때 키를 알아야 한다는 것과 코딩 AI가 대화에서 키 원문을 알아야 한다는 것은 다릅니다. 예제 코드·샘플 설정에는 실제 값 대신 작동하지 않는 자리표시자를 둡니다.

로컬 AI 도구가 프로젝트 파일과 터미널을 읽을 수 있다면 채팅에 안 붙였다고 끝나지는 않습니다. .gitignore는 Git 추적 제외 규칙이지 AI의 파일 읽기 제한이 아닙니다. 도구가 제공하는 접근 제한을 확인하고, 비밀 파일 전체나 인증키가 포함된 URL·오류 로그를 출력하는 디버깅을 피해야 합니다. 에이전트의 실제 접근 범위는 실행 환경과 권한 정책으로 제한해야 합니다. GitHub 에이전트 보안 설계

이 문제는 초보자에게만 생기지 않습니다. Wiz는 AI 기업의 공개 GitHub 자산에서 평문 mcp.json의 ElevenLabs 키, 코드·노트북·환경 파일의 LangSmith 키 등을 발견해 통보한 사례를 공개했습니다. 다만 그 유출을 모두 AI가 만든 사고라고 단정할 근거는 없습니다. 주목할 것은 코드 외의 도구 설정과 작업 기록도 키가 남는 경로라는 점입니다. Wiz 조사 원문

프로젝트별·개발과 운영별 키 분리는 피해 범위를 줄이는 선택입니다. 다만 서비스가 실제로 지원하는 발급 단위와 권한을 먼저 확인해야 합니다. 비밀 저장 기능을 쓰더라도 응답에 키를 포함시키거나 로그로 출력하는 코드는 별도로 막아야 합니다.

보이는 키를 전부 지우면 앱이 안전해질까요

동네날씨에 “자주 보는 동네 저장”을 추가하면 또 다른 경계가 생깁니다. 기상청의 예보는 공용 자료여도, 누가 어떤 위치를 개인 목록에 저장했는지는 별도로 취급해야 합니다. 계정 간 동기화가 필요 없다면 서버 DB 없이 내 기기에만 저장하는 선택도 있습니다.

계정별 동기화를 위해 Supabase 같은 서비스를 붙였다고 해 보겠습니다. 이 서비스의 publishable 키와 기존 anon 키는 클라이언트에서 사용할 수 있도록 설계됐습니다. 반면 secret·service_role처럼 강한 권한의 키는 비공개 서버에서만 취급해야 합니다. 키가 화면에 보이는지만으로 두 종류를 같은 유출로 분류하면 진단이 어긋납니다. Supabase 키 유형

핵심 비교
구분역할설명예시
공공 API 인증키신청한 데이터 조회이용 조건과 호출 한도를 확인합니다. 소유자 공통 키를 서버에서 쓰는 설계에서는 방문자에게 원문을 보내지 않습니다.기상청·에어코리아 활용 인증
공개용 프로젝트 키클라이언트 연결보이도록 설계된 키도 있습니다. 사용자 인증·데이터 접근 정책을 함께 확인해야 합니다.Supabase publishable·기존 anon
관리자·유료 API 키데이터·유료 작업권한에 따라 비공개 자료 접근이나 유료 호출을 허용합니다. 서버 보관과 별개로 요청자의 권한·한도를 검사합니다.DB secret·AI 호출 키
배포·관리 토큰앱과 설정 변경코드·비밀 설정·운영 환경을 바꿀 수 있는 범위에 따라 피해가 달라집니다. 프로젝트와 환경을 좁혀 관리합니다.호스팅·저장소 관리 자격 증명

키의 종류를 구분한 뒤에는 데이터 접근 정책을 확인합니다. Supabase의 행 수준 보안, RLS는 어떤 사용자가 어떤 데이터 행에 접근할 수 있는지 제한하는 기능입니다. 공개용 키를 사용하더라도 필요한 정책을 설정해야 하고, 강한 서버 키로 개인 요청을 처리한다면 서버가 요청자의 권한을 별도로 검사해야 합니다. Supabase 데이터 보호 문서

화면에서 내 목록만 보인다는 것만으로 충분하지 않습니다. “권한 오류가 나니까 일단 정책을 꺼 줘”라고 고치면 저장 기능은 작동해도 A가 B의 개인 목록을 읽거나 수정하는 문제가 남을 수 있습니다. 필요한 결과는 오류가 사라지는 것이 아니라 자기 목록은 바꿀 수 있고, 남의 비공개 목록은 바꿀 수 없는 상태입니다.

바이브 코딩 커뮤니티의 감사 경험 글에서도 프론트엔드의 Supabase 키가 위험 사례로 등장합니다. 하지만 키 종류와 정책을 구분하지 않은 표본·자기 보고를 전체 앱의 보안 통계로 받아들여서는 안 됩니다. 그 글에서 가져올 것은 불안한 비율보다 ‘공개용 키인가, 비밀 키인가, 실제 접근이 제한되는가’라는 질문입니다. Reddit 감사 경험 공유

AI의 완료 보고보다 확인할 만한 증거

“키 보안을 강화했습니다”라는 답변을 받으면 바꾼 위치와 확인 결과를 같이 요청합니다. 동네날씨에서는 첫 화면에 정보가 잘 나오는지에 더해, 새로고침했을 때 어디로 몇 번 요청하는지, 허용하지 않은 동작은 거절되는지를 봐야 합니다.

다음 점검은 소유하거나 명시적으로 허가받은 앱에서, 실제 개인 자료 대신 더미 데이터와 테스트 계정으로 진행합니다. 브라우저의 Sources·Network를 살펴보는 방식은 데스크톱 Windows·macOS·Linux에 공통으로 적용할 수 있습니다. 개발자 도구를 여는 메뉴와 단축키는 브라우저마다 다릅니다.

  1. 방문자에게 무엇이 전달되는지 봅니다. 배포된 JavaScript, 요청 URL·헤더와 응답에 소유자용 인증키가 있는지 확인합니다. 공개용 키와 사용자 세션 토큰을 무조건 비밀 키로 분류하지 않습니다. 검색에서 키가 안 나왔다는 것만으로 모든 노출 경로가 없다고 결론 내리지는 않습니다.
  2. 같은 지역을 반복해서 조회합니다. 캐시가 유효한 구간에서는 공용 자료의 원본 호출이 방문자 요청마다 늘지 않는지 서버 기록으로 확인합니다. 브라우저에서 내 서버를 호출하는 횟수와 내 서버가 원본을 호출하는 횟수는 다릅니다. 확인용 로그에는 키를 가립니다.
  3. 지원하지 않는 지역·시간 조건을 보냅니다. 앱이 허용한 범위를 벗어나면 원본 API 호출 전에 거절돼야 합니다. 아무 외부 URL이나 대신 요청해 주는 경로가 없어야 합니다.
  4. 원본 조회 실패를 테스트 환경에서 재현합니다. 실제 제공기관에 요청을 몰아넣지 않고 가짜 오류 응답을 사용합니다. 무한 재시도가 멈추는지, 마지막 자료의 시각과 갱신 실패 상태가 표시되는지 확인합니다.
  5. 추가 기능의 경계를 확인합니다. 개인 저장 기능이 있다면 A가 B의 목록을 읽거나 바꾸지 못해야 합니다. 로그인 사용자 전용 유료 요약이 있다면 로그아웃 요청이 유료 호출까지 진행되지 않아야 하고, 작은 테스트 한도를 소진하면 중지돼야 합니다.

무료 공용 날씨 조회가 로그아웃 상태에서 된다는 것은 이 앱의 의도된 기능일 수 있습니다. 반면 비공개 자료와 유료 기능이 같은 상태에서 동작하면 설계에 맞는지 다시 확인해야 합니다. 로그인 화면의 유무보다 요청별 허용 범위가 중요합니다.

저장소의 비밀 스캔과 push protection, 즉 업로드 전 비밀 탐지·차단도 보조 수단입니다. 지원하는 키 패턴과 설정에 따라 범위가 달라지며 배포된 파일·모든 로그·공개 앱의 접근 정책을 대신 검사하지는 못합니다. GitHub push protection, 탐지 패턴과 지원 범위

“안전하게 해 줘” 대신 이렇게 요청해 봅니다

아래 요청문은 키 원문 없이 구조를 살피고, 수정안과 검증 결과를 구분해 받기 위한 출발점입니다. AI가 통과라고 답했다는 이유만으로 보안 검증이 끝나는 것은 아닙니다.

Text
이 날씨·미세먼지 앱을 공개하기 전에 요청 경로와 인증키를 점검해 줘.
먼저 변경하지 말고 현재 구조를 조사해 줘.

실제 키 값, 비밀 파일 전체, 인증 헤더, 키가 들어간 URL은
대화·터미널·로그에 출력하지 마. 필요한 설정 이름과 권한만 알려 줘.

1. 브라우저 → 내 서버 → 제공기관의 요청 경로를 설명해 줘.
   방문자에게 전달되는 설정과 서버 전용 키를 구분하고,
   공개용 키 예외는 해당 서비스 공식 문서로 확인해 줘.
2. 각 API의 무료·유료 여부, 승인된 호출 한도와 운영 조건을 구분해 줘.
   확인하지 못한 조건과 실제 이용 내역은 미확인이라고 적어 줘.
3. 같은 지역·발표 자료의 캐시, 중복 호출 방지, 오래된 값의 표시,
   지원 지역·조회 범위·재시도 횟수 제한을 어디서 처리하는지 찾아 줘.
4. 개인 즐겨찾기·유료 AI 기능이 있다면 공용 날씨 조회와 분리해서
   사용자별 권한과 사용량 제한을 확인해 줘.
   권한 오류를 없애려고 DB 정책을 끄거나 모두 허용하지 마.
5. .gitignore와 AI 도구의 파일 접근 제한을 구분하고,
   배포 파일·저장소 이력·도구 설정·오류 로그의 노출 경로를 살펴 줘.

결과는 위치, 위험, 수정안, 확인할 증거로 정리해 줘.
내 테스트 환경의 가짜 키·더미 데이터·작은 한도로 점검을 계획하고,
실행한 확인과 아직 실행하지 않은 계획을 구분해 줘.
새 키 발급·기존 키 폐기·운영 설정 변경·배포는 바로 실행하지 말고
내가 검토할 구체적인 변경안과 서비스 영향을 먼저 보여 줘.

AI가 “캐시를 붙였다”고 하면 서버의 원본 요청 기록을, “개인 자료를 보호했다”고 하면 A와 B의 접근 결과를 받습니다. “키를 숨겼다”고 하면 새 배포의 전달물과 오류 로그를 확인합니다. 설명과 증거를 짝으로 받는 방식은 개발 지식이 부족할 때도 위임의 범위를 분명하게 만들어 줍니다. AI가 볼 수 있는 업무 자료 자체의 범위는 회사 문서를 AI에 넣기 전의 보안 기준에서 이어서 확인할 수 있습니다.

인증키가 이미 공개됐다면

공개 JavaScript나 게시판의 요청 URL에서 소유자용 키를 찾았다면, 그 값을 다시 AI 대화에 붙여 넣지 않습니다. 어느 서비스인지, 발견 위치와 시각, 키 식별자 또는 마스킹한 일부를 기록합니다. 그리고 해당 제공자가 지원하는 중지·회수·재발급 절차와 영향을 확인합니다. 서비스마다 관리 방식이 다르므로 없는 ‘즉시 폐기’ 메뉴를 있다고 가정해서는 안 됩니다.

즉시 회수할 수 있는 비밀 키라면 추가 악용을 막고, 새 키가 같은 공개 경로로 다시 나가지 않도록 원인을 함께 고쳐야 합니다. 정상 앱이 새 키를 사용하도록 바꾼 뒤 이전 키의 효력이 끝났는지 확인합니다. GitHub도 노출된 비밀을 저장소에서 지우는 작업보다 먼저 키의 회수·교체를 검토하도록 안내합니다. GitHub 인증 정보 노출 대응

노출 뒤 확인할 네 가지
  1. 추가 사용 차단제공자의 중지·회수 절차를 확인하고 노출된 키와 악용 경로를 막습니다. 필요하면 기능을 잠시 중지합니다.
  2. 안전한 교체공개 경로를 고친 뒤 새 키를 서버 비밀 설정에 연결하고 이전 키의 효력이 끝났는지 확인합니다.
  3. 영향 확인무료 조회는 호출량·한도·장애를, 유료 키는 비용을, 강한 관리 키는 자료 접근과 변경을 조사합니다.
  4. 남은 경로 정리이전 배포, 저장소 이력, 게시판 캡처, 로그와 도구 설정을 살피고 같은 노출을 다시 검사합니다.

최신 파일에서 문자열을 지웠어도 이전 배포와 Git 이력·복제본에는 남을 수 있습니다. 삭제만으로 이미 복사된 키를 회수할 수 없는 이유입니다. 사고 조사에 필요한 기록은 접근을 제한해 보존하면서, 인증키가 그대로 기록되는 원인을 고칩니다.

날씨 조회용 인증키를 찾았다고 사용자 DB까지 유출됐다고 단정할 필요는 없습니다. 반대로 DB 관리자 키나 배포 토큰이었다면 날씨 호출량만 확인해서는 부족합니다. 피해 범위를 정할 때도 출발점은 ‘그 키가 허용한 일’입니다.

동네날씨의 완성 기준은 내 휴대전화에 숫자가 잘 나오는 데서 한 걸음 더 나아갑니다. 친구에게 보여 줄 날씨는 열어 두고, 내 인증키와 개인 자료는 넘기지 않으며, 새로고침과 반복 요청이 어디까지 자원을 쓰는지 설명할 수 있는 상태입니다. 앱을 만드는 일은 AI와 함께 빨라졌지만, 공개해도 되는 범위를 정하는 질문까지 생략할 필요는 없습니다.

저도 공공 API 앱을 만들면서 보안을 조금 더 공부하게 됐고, 아직 모르는 것이 많다는 점을 느꼈습니다. 키를 어디에 둘지 정하는 데서 시작해, 어떤 요청을 허용하고 무엇을 확인해야 할지까지 공부할 범위가 넓어집니다. 모르는 부분을 구체적인 질문으로 바꾸고 하나씩 확인해 가는 과정도 앱을 만드는 일에 포함된다고 생각합니다.

VIEW—

© Chacolate. 일부를 인용할 때는 글 제목과 원문 링크를 함께 표시해 주세요. 무단 전재·재배포는 허용하지 않습니다.