본문으로 건너뛰기
inflfeed

키 보관부터 유출 의심 시 대응까지

내 AI 에이전트가 API 키를 읽었을까?

내 키가 읽힐 수 있는 경로와 남아 있는 기록을 확인하고 유출이 의심될 때 폐기·교체할 순서를 정해봐요.

키 접근 권한, 읽기 기록, 외부 사용 흔적을 나눠 확인하는 개념 UI
AI 생성 일러스트예요. 실제 서비스 화면이나 내 계정의 점검 결과가 아니에요.

에이전트에게 API 연결을 고쳐달라고 한 뒤 작업 기록에서 키를 발견했나요? 사용하지 않은 시간에 요금이 늘어 원인을 찾고 있을 수도 있어요. 이때는 키를 어디에 저장했는지와 함께, 어떤 프로그램이 읽었고 어디로 보낼 수 있었는지 확인해야 해요.

유출 정황이 있다면 의심되는 실행을 멈추고 발급처에서 키를 폐기하는 대응부터 하세요. 기록을 전부 분석할 때까지 기다릴 필요는 없어요. 아직 정황이 없다면 아래 순서로 접근 권한과 남아 있는 흔적을 점검해보세요. 실제 키 값을 AI 대화에 붙여 넣거나, 읽을 수 있는지 보려고 에이전트에게 출력시키지는 마세요.

이 글은 내 키 하나를 대상으로 보관·접근·사용 기록과 회수 절차를 확인하는 안내예요. 접근 가능한 상태와 실제 유출은 다르고 기록이 없으면 과거 일을 완전히 복원하지 못할 수도 있어요.

유출이 의심되면 무엇부터 해야 하나요?

Google Cloud의 유출된 서비스 계정 키 대응 문서는 탐지 내용을 보고 관련 로그를 확인한 뒤 키를 즉시 폐기하라고 안내해요. 동시에 키 삭제가 애플리케이션을 중단시킬 수 있으므로 영향을 받는 서비스를 확인하라고 해요. 아래 순서는 이 문서와 노출 대응 자료를 개인·팀 작업에 적용한 편집부 안내예요. 실제 폐기 방법은 키를 발급한 서비스의 현재 절차를 따라야 해요.

  1. 의심되는 에이전트 작업과 자동 실행을 멈춰요. 같은 권한으로 계속 실행하면 노출이 이어질 수 있어요. 원인을 찾겠다며 같은 작업을 재실행하거나 기록부터 지우지 마세요.
  2. 발급처의 키 관리 화면에서 해당 키를 폐기하거나 비활성화해요. 에이전트 앱에서 연결을 지우는 것과 별개예요. 팀의 운영 키라면 담당자에게 알리고 차단·대체·서비스 중단의 순서를 바로 정하세요. 장시간의 원인 조사 때문에 활성 키를 그대로 두지 마세요.
  3. 대응과 함께 최소한의 증거를 남겨요. 발급처, 키의 이름·식별자, 발견 시각과 시간대, 의심되는 작업·저장소·공개 URL을 적어요. 바로 확보할 수 있는 기록을 보관하되 폐기를 늦추지 말고 공유용 기록에는 키 원문을 넣지 마세요.
  4. 발급처의 사용량·요금·감사 기록을 확인해요. 의심 시각 전후의 호출, 사용한 서비스와 리소스, 표시된다면 IP·키 식별자를 비교하세요. 모르는 호출이 있으면 발급처 지원 또는 팀의 보안 담당자에게 키 식별자와 시각을 전달해요. 한도를 정했더라도 알림만 보내는 기능인지 요청을 차단하는 기능인지 확인해야 해요.
  5. 새 키는 필요한 연동에만 넣고 정상 동작을 확인해요. 앱·서버·CI·예약 작업 가운데 기존 키를 쓰던 곳을 교체하고 이전 키가 폐기된 상태인지 발급처에서 확인하세요. 의심되는 에이전트 환경을 정리하기 전에 새 키부터 다시 넣지 마세요. 다른 비밀에도 접근한 흔적이 있다면 그 범위까지 대응을 넓혀요.
유출된 서비스 계정 키의 주체와 키 이름으로 로그를 찾고 대응하는 Google Cloud 공식 문서
실제 Google Cloud 문서 화면이에요. principalEmail과 serviceAccountKeyName을 함께 써서 키의 사용 흔적을 좁히는 구간이며 아래에는 즉시 폐기와 서비스 연속성에 관한 안내가 있어요.Google Cloud원문 보기

이 화면은 Google Cloud의 특정 서비스 계정 탐지 예시예요. 다른 API 서비스가 같은 항목을 제공한다는 뜻은 아니에요. 키별 사용 내역이 없으면 확인할 수 있는 범위도 줄어요. 폐기한 키가 이미 접근한 데이터까지 되돌려지는 것은 아니므로, 낯선 리소스나 권한 변경도 살펴보세요.

GitGuardian의 노출 대응 글은 교체로 무엇이 중단되는지 먼저 파악하라고 강조해요. 노출 사고 자체를 다룬 글이며 정기 교체만의 안내가 아니에요. 개인 키와 운영 중인 공유 키의 중단 영향은 다르지만 실제 침해가 의심될 때의 긴급 차단은 발급처의 대응 절차에 맞춰 진행해야 해요.

키를 Git에서 지우거나 대화 기록을 삭제해도 이미 복사된 키의 권한은 사라지지 않아요. 발급처에서 무효화한 뒤 노출 파일·기록·공개 사본을 정리하세요.

키 파일을 막았는데도 에이전트가 읽을 수 있나요?

Maria Otworowska는 가짜 키를 넣은 작은 프로젝트로 202회의 실행을 비교했어요. 에이전트가 .env를 직접 여는 경우와, 프로그램을 실행하다 출력에서 키를 받는 경우를 따로 살폈어요. 후자가 특히 실용적인 점검 단서예요.

작성자의 실험에서는 직접 만든 출력 예제 42회 중 41회에 키가 에이전트 문맥에 들어갔어요. 실제 라이브러리를 쓴 예제 중 curl -v는 6회 모두 테스트 키를 출력했어요. .env를 읽지 말라는 규칙만으로 프로그램의 출력까지 막을 수 없었던 거예요. 연결 문자열인 DATABASE_URL이 이름 기준 마스킹에서 빠진 사례도 있었어요.

가짜 키 실험의 결과와 프로그램 출력 경로를 설명하는 Fidelius 원문 화면
영문 화면 요약: 규칙을 둔 실험과 프로그램 출력으로 키가 문맥에 들어간 실험을 따로 설명해요. 아래에는 마스킹 결과와 작성자 도구의 조건도 있어요. 작성자의 실험이며 독립 재현 결과는 아니에요.Maria Otworowska원문 보기

실험에서 구분해야 할 경로는 다음과 같아요.

  • 파일: .env나 비밀값이 들어 있는 설정 파일을 읽어요. 작업 폴더 밖의 자료도 도구 권한에 따라 접근 대상이 될 수 있어요.
  • 환경변수: 에이전트 또는 그 하위 프로그램에 전달된 값이에요. 저장 파일을 따로 열지 않아도 프로그램이 이미 값을 갖고 있을 수 있어요.
  • 도구 출력: 오류 메시지, HTTP 디버그 출력, 연결 문자열, 빌드 로그에 값이 찍혀 에이전트로 돌아와요.
  • 기록: 그 출력이 세션 기록·터미널 기록·CI 로그·스크린샷에 다시 남을 수 있어요. 한 곳을 가려도 다른 사본은 별도로 확인해야 해요.

여기서 에이전트 문맥에 들어갔다는 결과를 공격자에게 전송됐다는 결과와 합치면 안 돼요. 작성자는 일부 Mac 실행에서 문맥에 들어간 키가 세션 로그에도 남았다고 설명해요. 모델 서비스로 보내는 내용과 보관 방식은 쓰는 제품의 현재 정책·배포 방식에 따라 따로 확인할 대상이에요.

이 실험은 2026년 10월 7~8일의 작은 고정 프로젝트와 가짜 키, 권한 우회 모드에 관한 결과예요. 조건별 반복은 1~5회이고 작성자가 출력 마스킹 도구도 만들었어요. 모든 에이전트의 유출률이나 그 도구의 안전성을 입증한 결과로 읽지는 마세요. Maria Otworowska는 Fidelius를 만드는 개발자로, 실험 조건과 실행 기록을 공개해 결과가 나온 경로를 따라가게 해요.

내 환경에서 읽기와 전송 흔적을 어떻게 구분하나요?

Aonan Guan과 공동 연구자의 「Comment and Control」은 외부 PR·이슈의 내용이 에이전트의 작업 지시로 취급되고 같은 실행 환경의 자격증명이 GitHub 댓글·커밋·Actions 로그로 나가는 재현 사례예요. 전송 목적지가 익숙한 GitHub라는 이유만으로 안전하다고 볼 수 없었던 장면이에요.

GitHub 입력에서 에이전트 실행과 댓글·로그 노출까지의 경로를 설명하는 연구자 원문 화면
영문 화면 요약: PR·이슈의 내용이 작업 문맥에 들어가고 실행 환경의 자격증명이 댓글·커밋·로그로 나가는 재현 경로예요. 특정 GitHub Actions 조건의 설명이며 내 환경의 유출 판정은 아니에요.Aonan Guan원문 보기

2026년 4월 공개한 특정 GitHub Actions·에이전트 조합의 연구자 재현이며 지금 쓰는 개인용 에이전트도 같은 영향을 받는다는 판정은 아니에요. 신고 후의 처리 상태도 원문에 갱신되어 있어요. 공격 문구를 따라 실행하는 대신 내 작업에서 아래 세 가지 증거를 나눠 찾아보세요.

1. 이 작업이 키를 읽을 수 있었나요?

쓰는 도구와 버전, 작업 폴더, 허용한 파일 경로·명령 실행·MCP·외부 통신을 적어요. .gitignore는 Git이 추적하지 않을 파일을 정하는 설정이므로 에이전트의 읽기 권한을 대신하지 않아요. 키를 읽지 말라는 자연어 지시와 실제 접근 제한도 별개예요.

Claude Code를 쓴다면 현재 세션의 /permissions에서 적용 중인 허용·거부 규칙, /mcp에서 연결 서버, /hooks에서 실행되는 훅을 확인해보세요. /context와 /status는 어떤 지침·도구·설정이 로드됐는지 살펴보는 보완 수단이에요. 공식 설정 진단 문서의 명령이며 다른 도구에서는 그 제품의 현재 권한 화면을 확인해야 해요. 이 화면들은 과거에 특정 키를 읽었다는 증거가 아니에요.

Git을 쓰는 macOS·Linux 프로젝트라면 직접 연 로컬 터미널에서 다음을 실행해 추적 중인 파일명과 해당 경로의 변경 이력을 확인할 수 있어요. 키 값이나 파일 본문은 출력하지 않아요.

git ls-files -- '.env' '.env.*' '*.pem' '*.key'
git log --all --format='%h %aI' -- '.env' '.env.*' '*.pem' '*.key'

첫 줄에 파일이 나오면 그 파일에 진짜 비밀이 들어 있는지 로컬 편집기에서 확인하세요. .env.example처럼 가짜 값만 있는 파일도 검색될 수 있어요. 두 번째 줄은 현재 로컬 저장소의 참조가 가리키는 이력이므로 원격의 모든 사본을 조사한 결과가 아니에요. 출력이 비어도 미추적 파일, 다른 이름의 설정, 환경변수, MCP 서버까지 안전하다고 판정할 수는 없어요.

2. 실제로 읽은 기록이 있나요?

의심 시각의 세션에서 파일 읽기 도구의 결과와 실행한 프로그램의 출력을 함께 살펴보세요. 파일 이름만 보이는 기록과 실제 값이 도구 결과에 들어간 기록을 구분해요. 디버그 로그가 당시 켜져 있지 않았다면 지금 활성화해도 과거 기록이 생기지는 않아요.

이미 보관한 로그 파일에서 문자열 하나를 확인하고 싶다면 아래 예제를 쓸 수 있어요. 발급처에서 먼저 폐기한 키 또는 아무 권한이 없는 가짜 표식만 사용하고 에이전트 도구가 아닌 직접 연 로컬 터미널에서 실행하세요. Python 3가 필요해요. 아래 코드를 check-local-log.py로 저장하고 python3 check-local-log.py로 실행하세요. 코드는 지정한 파일 하나를 로컬에서 읽고 일치 여부만 출력해요. 키를 명령행 인자나 스크립트 파일에 적지 않으며 입력한 값도 화면에 표시하지 않아요.

from getpass import getpass
from pathlib import Path

path = Path(input("로그 파일 경로: ")).expanduser()
marker = getpass("폐기한 키 또는 가짜 표식: ").encode()
if not marker:
    raise SystemExit("빈 값은 확인하지 않아요.")
found = marker in path.read_bytes()
print("문자열이 있어요." if found else "같은 문자열을 찾지 못했어요.")

편집부가 만든 단순한 확인 예제예요. 일치하면 그 파일에 정확한 문자열이 있다는 뜻이에요. 에이전트가 외부로 보냈다는 증거까지 되지는 않아요. 없다고 나와도 잘린 값, 인코딩·분할된 값, 다른 파일, 남지 않은 기록은 놓쳐요. 파일이 크면 메모리가 많이 필요하고 경로·읽기 권한 오류가 나면 확인하지 못한 상태로 남겨두세요. 로그 전체를 AI나 온라인 검사 사이트에 업로드하지 마세요.

3. 밖으로 나가거나 사용된 흔적이 있나요?

같은 시간대의 도구 호출 인수, 외부 요청·프록시 기록, 게시한 댓글·첨부·CI 로그, 발급처의 사용 기록을 맞춰봐요. 어떤 목적지로 무엇을 보냈는지 남아 있는 기록이 가장 구체적인 단서예요. 공급자의 사용량 증가만으로는 어느 에이전트가 키를 읽었는지 알기 어려워요. 키를 전송만 하고 아직 사용하지 않았을 가능성도 있어요.

Google Cloud 문서는 많은 서비스에서 Data Access 감사 로그가 기본으로 꺼져 있고 일부 호출 정보가 가려질 수 있다고 설명해요. 다른 서비스도 로그 범위·보관 기간을 확인해야 해요. 요청 목적지만 있는 로그와 본문까지 확인 가능한 기록도 달라요. 기록이 부족하면 유출 여부 미확인으로 남기고 앞의 긴급 대응과 권한 축소를 진행하세요.

Aonan Guan은 AI 에이전트와 MCP의 공격 경로를 공개하는 보안 연구자예요. 이 글은 각 단계에서 어떤 권한과 출력 경로가 필요했는지 설명하므로, 팀의 자동 코드 리뷰나 이슈 처리 작업을 점검할 때 읽을 만해요. 제목과 설명은 한국어로 옮겼으며 현재 버전의 수정 여부는 실제 사용하는 워크플로와 함께 확인해야 해요.

다음 키는 어떻게 보관하고 맡겨야 할까요?

일단 키를 프로젝트·작업별로 나누고 필요한 서비스·행동·유효 기간으로 제한할 수 있는지 발급처에서 확인해보세요. 개발 작업에 운영 전체의 관리자 키가 꼭 필요한지도 다시 보세요. 가능한 경우 짧게 유효한 자격증명을 쓰면 장기간 같은 키를 보관하는 부담을 줄일 수 있어요.

에이전트 실행 환경도 구분해야 해요. 비밀 관리 도구나 OS 키체인에 저장했더라도 꺼낸 실제 값을 에이전트의 환경변수로 넘기면 그 프로세스가 값을 갖게 돼요. 작업 폴더에서 .env를 옮기는 조치만으로 모든 도구의 파일 접근이 차단되지는 않아요. 별도 작업 환경과 제한된 파일·명령·통신 권한을 함께 확인하세요. Claude Code의 셸 샌드박스도 내장 파일 도구·MCP·훅까지 전부 포괄하는 기능은 아니에요.

Infisical의 「AI 에이전트의 자격증명 중개 방식」 영상은 그 다음 설계를 설명해요. 영어 대본의 03:56~04:59 구간에서는 에이전트 쪽의 대체 값이 별도 중개 서버를 거쳐 실제 인증 요청으로 바뀌고 중개 서버의 요청 기록을 확인하는 시연을 설명해요. 05:02~07:08에는 인증서와 네트워크 경계, 중개 서버를 거치도록 제한하는 조건이 나와요. 영상 프레임을 독립 검증하거나 제품을 설치해 재현한 결과는 아니에요.

실제 키는 호스트 프록시가 주입하고 샌드박스에는 대체 값을 제공한다고 설명하는 Docker 문서
실제 Docker 문서 화면이에요. 프록시가 처리하는 자격증명과 실제 토큰이 전달되는 OAuth passthrough를 구분해서 읽어보세요. 제품 이름보다 어떤 값이 어느 프로세스에 들어가는지가 점검 기준이에요.Docker원문 보기

Docker의 현재 자격증명 문서도 비슷한 경계를 설명해요. 프록시 주입에서는 샌드박스가 대체 값을 보지만 OAuth의 passthrough: true는 실제 토큰을 전달해요. 두 방식을 같은 수준의 격리로 보면 안 돼요.

중개 서버를 둬도 허용된 API를 악용하는 문제까지 사라지지는 않아요. Agent Vault의 기본 전달 동작과 strict-deny 옵션, 프록시를 거치지 않는 통신, 중개 서버 자체의 권한·기록 보호를 따로 검토해야 해요. 이 영상은 공급자 설명이므로 설치만 하면 유출을 막는다고 읽지 마세요. 직접 관리할 여력이 없다면 먼저 키의 범위와 에이전트의 접근 권한을 줄이는 데서 시작해도 돼요.

Infisical은 비밀 관리 도구와 Agent Vault를 만드는 팀이에요. 저장소에 넣지 않는 것에서 더 나아가 에이전트 프로세스가 실제 값을 받아야 하는지 살펴보려는 개발자에게 이 설명을 권해요.

내 키 하나의 점검 기록을 남겨보세요

키 원문을 적지 않고 아래 항목만 채워도 다음에 확인할 곳이 구체적으로 남아요.

  • 대상: 도구·버전, 프로젝트, 발급처와 키 식별자.
  • 권한: 허용된 서비스·행동·만료 조건, 운영 키가 필요한 이유.
  • 전달 경로: 보관처, 실제 값을 받는 프로세스, 읽을 수 있는 파일·환경변수·MCP·훅.
  • 확인 결과: 접근 가능한 상태인지, 실제 읽기·전송·사용 흔적이 있는지. 기록의 기간과 공백도 함께 적어요.
  • 대응: 발급처의 폐기 위치, 교체할 앱·CI·예약 작업, 마지막 확인 시각.

모르는 칸은 미확인으로 남겨두세요. 유출 정황을 발견했다면 목록을 끝까지 채우기에 앞서 의심되는 실행을 멈추고 발급처의 긴급 대응부터 진행하세요.

내 키 하나에서 확인할 것

접근 권한과 실제 흔적을 나누고 발급처의 폐기 위치와 교체할 연동을 기록해보세요.

다음에 소개할 사람

찾는 크리에이터가 없나요?

소개하고 싶은 크리에이터의 이름이나 채널 링크를 알려주세요.