백그라운드 에이전트가 시크릿을 유출하기 전에 팀이 설계해야 할 격리 모델

백그라운드 에이전트가 시크릿을 유출하기 전에 팀이 설계해야 할 격리 모델

에이전트에게 자율성을 주기 전에 먼저 답해야 할 질문—'스톨이 발생하면 무엇이 출력되는가'

서브에이전트 보안 시크릿 유출 격리 모델 credential isolation 리뷰 게이트웨이 Claude Code 취약점 AI 에이전트 보안 prompt injection
광고

Claude Code의 백그라운드 Opus 서브에이전트가 첫 턴에 스톨하면서 시스템 프롬프트 조각을, 그것도 인증 데이터 형태로 그대로 출력하는 재현 가능한 취약점이 공개됐다. 아직 열려 있는 이슈다. '간헐적'이라는 수식어가 붙었다고 안심하면 안 된다. 간헐적 실패는 재현하기 어렵다는 뜻이지, 발생 확률이 낮다는 뜻이 아니다.

이 취약점의 핵심 구조를 짚어보자. 서브에이전트는 신뢰할 수 있는 서브프로세스가 아니다. 컨텍스트 윈도우와 툴셋, 그리고 너무 자주 부모 에이전트와 동일한 크리덴셜을 들고 도는 자율 루프다. 이 루프가 스톨하고 결과 대신 프롬프트를 덤프하면, 컨텍스트 안에 있던 모든 것이 출력으로 흘러나온다. 토큰, 세션 문자열, 내부 엔드포인트—프롬프트에 담겨 있던 것이 그대로 표면으로 올라온다.

문제를 이렇게 프레이밍하면 해결책의 방향도 명확해진다. 패치가 아니라 구조다. dev.to에 공개된 분석은 세 가지 원칙을 제시한다. 첫째, 크리덴셜 범위를 세션이 아닌 서브에이전트 단위로 쪼갤 것. 리포를 읽기만 하는 에이전트가 배포 키를 들고 있을 이유는 없다. 태스크가 끝나면 토큰을 폐기한다. 둘째, 서브에이전트 출력을 비신뢰 데이터로 취급할 것. 에러 텍스트, 로그, 스톨 덤프—모두 파싱과 새니타이징 없이 공유 상태나 다른 에이전트의 컨텍스트로 파이프하지 않는다. 셋째, 시스템 프롬프트와 워킹 컨텍스트를 분리할 것. 스톨한 루프가 에코할 수 있는 프롬프트에 크리덴셜과 내부 라우팅 정보를 섞지 않는다. 모델이 출력할 수 있는 텍스트가 아니라, 호출할 수 있는 사이드 채널에 넣는다.

이 세 원칙이 익숙하게 들린다면 맞다. 이전 글에서 다룬 MCP 안전 원칙, 런타임 게이트, 에이전트 거버넌스 설계와 같은 맥락이다. 차이가 있다면 이번엔 취약점이 이미 재현됐다는 점이다. 이론적 위협 모델이 아니라 열려 있는 이슈 트래커가 있다. 팀 리드 입장에서 이건 '나중에 검토할 사항'이 아니라 '지금 당장 크리덴셜 범위 감사를 돌려야 한다'는 신호다.

보안 격리와 함께 검토해야 할 것이 리뷰 게이트웨이 설계다. Kiro 기반 개발 워크플로우를 위한 오픈소스 프로젝트인 Kiro External Spec Review Gateway는 에이전트가 생성한 산출물—요구사항, 설계 문서, 태스크 플랜, 코드 변경, 커밋 추천—을 그대로 수용하지 않고, 각 단계마다 외부 검토와 인간 승인 게이트를 명시적으로 삽입한다. 생성(Generation) → 리뷰(Review) → 승인(Approval) → 계속(Continuation)의 네 단계를 의도적으로 분리하는 구조다.

이 프로젝트가 특히 흥미로운 건 로컬 퍼스트 설계 원칙이다. 기본값이 모의 리뷰어(mock reviewer)다. 사용자가 명시적으로 설정하지 않으면 어떤 모델 호출도 발생하지 않는다. 외부 프로바이더 사용은 옵트인이고, 로컬 프로바이더 엔드포인트는 루프백 주소로만 제한된다. API 키는 저장되거나 출력되지 않는다. '무엇을 리뷰했고, 누가 승인했고, 콘텐츠가 로컬을 벗어났는가'가 메타데이터로 기록된다. 에이전트 워크플로우의 감사 가능성(auditability)을 설계 수준에서 보장한 사례다.

여기에 Claude Code 루틴—클라우드에서 cron 기반으로 실행되는 스케줄 에이전트—을 더하면 그림이 완성된다. 루틴은 격리된 클라우드 세션에서 실행되고, 세션은 로컬 환경 변수나 파일에 접근할 수 없다. 이 제약이 오히려 보안 설계를 강제한다. 루틴에 필요한 크리덴셜을 리포에 커밋하는 건 당연히 금물이다. 실제로 유효한 패턴은 '키드 릴레이'다. 실제 크리덴셜은 서버사이드 시크릿(Cloudflare Worker 등)에 두고, 루틴의 프롬프트에는 그 릴레이에 접근하는 랜덤 키만 담는다. 릴레이 키가 유출되더라도 폭발 반경은 크리덴셜 전체가 아니라 해당 액션 하나로 제한된다.

세 가지 소스를 묶으면 하나의 설계 원칙으로 수렴한다. 에이전트는 해피 패스를 가정하도록 만들어져 있지만, 팀은 실패 패스를 먼저 설계해야 한다. 스톨이 발생하면 무엇이 출력되는가. 에이전트 산출물이 검토 없이 다음 단계로 넘어가면 무슨 일이 생기는가. 스케줄 에이전트가 크리덴셜을 잘못 들고 있으면 폭발 반경은 어디까지인가. 이 질문들에 구조로 답하지 않으면, 에이전트 자율성은 편의가 아니라 리스크가 된다.

팀 규모와 상관없이 지금 당장 점검해야 할 세 가지가 있다. 첫째, 현재 실행 중인 백그라운드 에이전트가 들고 있는 크리덴셜의 범위를 확인하라. 태스크에 필요한 최소 권한인가. 둘째, 에이전트 출력이 파이프라인을 통과하는 경로를 추적하라. 새니타이징 없이 다른 에이전트의 컨텍스트로 흘러들어가는 지점이 있는가. 셋째, 시스템 프롬프트에 크리덴셜이나 내부 라우팅 정보가 포함되어 있는가. 있다면 사이드 채널로 분리하라.

격리 모델이 완성되면 스케줄 에이전트는 강력한 자산이 된다. 그 전까지는 편리한 취약점이다. 에이전트에게 자율성을 주기 전에 팀이 먼저 경계를 설계해야 한다는 원칙—이번엔 재현 가능한 취약점이 그것을 다시 한번 증명했다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요