에이전틱스
도메인 3. 통합

3.2인증·인가 공백 분석

예상 학습 시간 45

에이전트 시스템의 인증과 인가는 사람이 쓰는 시스템과 다른 지점에서 무너집니다. 자격 증명이 어디에 놓이는지, 누구의 권한으로 행동하는지, 프롬프트 인젝션이 어떻게 권한 경계를 넘는지를 설계 관점에서 분석합니다.

자격 증명은 샌드박스에 들어가면 안 된다

에이전트가 외부 API를 호출하려면 자격 증명이 필요합니다. 가장 흔한 설계 실수는 이 자격 증명을 에이전트가 코드를 실행하는 환경 안에 두는 것입니다.

문제는 단순합니다. 샌드박스 안에 있는 값은 그 안에서 실행되는 모든 코드가 읽을 수 있습니다. 에이전트가 직접 작성한 코드도 포함됩니다. 프롬프트 인젝션으로 유도된 코드가 환경 변수를 읽어 외부로 보내는 것을 막을 방법이 없습니다.

올바른 구조는 자격 증명을 경계 바깥에 두고, 요청이 샌드박스를 떠난 뒤 주입하는 것입니다.

[샌드박스]                    [경계]              [외부 서비스]
 에이전트 코드   ──요청──▶   자격 증명 주입   ──▶   API
 (플레이스홀더만 봄)          (실제 값 치환)

이 방식에서 샌드박스 안의 코드가 보는 것은 불투명한 자리표시자뿐이고, 실제 비밀 값은 나가는 요청에 치환됩니다. 인젝션으로 환경 변수를 덤프해도 얻을 것이 없습니다.

주의할 제약이 둘 있습니다.

  • 치환 위치: 주입은 보통 요청 헤더와 본문에만 적용됩니다. URL 경로에 비밀이 박히는 방식(경로 자체가 토큰인 웹훅 URL 같은 것)은 치환 대상이 아니므로 이 구조로 보호할 수 없습니다. 헤더 기반 인증으로 바꿔야 합니다.
  • 클라이언트 측 형식 검증: 어떤 CLI나 SDK는 네트워크 호출 전에 키 형식을 검사합니다. 자리표시자를 보고 형식이 틀렸다며 시작 단계에서 실패할 수 있습니다.

자격 증명 저장소를 쓸 수 없는 환경이라면 대안은 호출 자체를 바깥으로 옮기는 것입니다. 에이전트에는 인자만 받는 커스텀 툴을 주고, 실제 인증된 호출은 스트림을 읽고 있는 오케스트레이터가 자기 자격 증명으로 수행한 뒤 결과만 돌려줍니다. 샌드박스는 키를 본 적이 없습니다.

절대 하지 말아야 할 우회는 시스템 프롬프트나 사용자 메시지에 키를 넣는 것입니다. 프롬프트와 메시지는 세션 이력에 저장되고 조회 가능하며 요약에도 섞여 들어갑니다. 한 번 넣으면 그 세션이 사는 내내 읽을 수 있는 상태로 남습니다.

누구의 권한으로 행동하는가

두 번째 공백은 권한 주체의 혼동입니다. 에이전트는 서비스 계정으로 인증하지만 실제 요청은 특정 사용자를 대신해 수행합니다. 이 둘이 분리되지 않으면 혼동된 대리자(confused deputy) 문제가 생깁니다.

전형적인 실패는 이렇습니다. 사내 문서 검색 에이전트가 전체 문서에 접근 가능한 서비스 계정으로 인덱스를 조회합니다. 사용자 A가 질문하면 A가 볼 권한이 없는 문서까지 검색 결과에 들어오고, 모델이 그 내용을 요약해 답합니다. 에이전트는 규칙을 어긴 적이 없습니다 — 규칙이 없었을 뿐입니다.

설계 원칙은 인가는 검색 단계에서, 프롬프트가 아니라 데이터 계층에서 적용한다는 것입니다.

잘못된 위치왜 실패하는가
시스템 프롬프트에 "A가 볼 수 없는 문서는 언급하지 마라"모델이 이미 내용을 봤고, 지시는 보장이 아닙니다
검색 후 결과를 모델이 필터링같은 문제 — 필터링 주체가 모델입니다
검색 쿼리에 사용자 권한 필터를 포함권한 없는 문서가 애초에 반환되지 않습니다

세 번째가 정답입니다. 검색 인덱스에 문서별 접근 제어 메타데이터를 함께 저장하고, 질의 시 요청자의 권한을 필터 조건으로 넣습니다. 모델은 볼 수 있는 것만 봅니다.

토큰 위임 구조도 같은 원리입니다. 에이전트가 사용자를 대신해 외부 서비스를 호출한다면, 서비스 계정 토큰이 아니라 그 사용자에게 발급된 토큰을 써야 권한 범위가 자동으로 맞습니다. 다만 이 방식은 토큰 수명 관리가 따라옵니다 — 만료된 토큰의 자동 갱신, 사용자별 자격 증명 격리가 설계에 포함되어야 합니다.

프롬프트 인젝션은 인가 문제다

프롬프트 인젝션을 프롬프트 문제로 보면 해법을 찾지 못합니다. 인가 문제로 봐야 방어가 설계됩니다.

인젝션의 구조는 이렇습니다. 에이전트가 신뢰할 수 없는 데이터(웹 페이지, 사용자가 올린 문서, 외부 API 응답, 리포지터리의 파일)를 읽습니다. 그 데이터 안에 에이전트에게 지시하는 문장이 들어 있습니다. 에이전트가 그 지시를 따르면, 공격자가 에이전트의 권한을 빌려 행동한 셈이 됩니다.

핵심은 마지막 문장입니다. 인젝션의 피해 범위는 에이전트가 가진 권한과 정확히 같습니다. 읽기만 가능한 에이전트에 대한 인젝션은 잘못된 답변으로 끝나지만, 메일 발송과 파일 삭제가 가능한 에이전트에 대한 인젝션은 데이터 유출과 파괴로 이어집니다.

따라서 방어는 세 층으로 쌓습니다.

1. 권한 축소 — 가장 효과적인 층입니다. 3.1의 최소 권한 감사가 그대로 인젝션 방어가 됩니다.

2. 데이터와 지시의 구분 — 외부에서 들어온 내용은 데이터로 표시해 전달하고, 그 안의 명령형 문장을 지시로 취급하지 않도록 시스템 프롬프트에서 명확히 합니다. 완전한 보장은 아니지만 성공률을 낮춥니다.

3. 되돌리기 어려운 행동의 게이트 — 외부 발송, 삭제, 권한 변경은 사람 확인을 거치게 합니다. 이 층이 있으면 앞의 두 층이 뚫려도 최종 피해가 막힙니다.

특히 주의할 경로가 리포지터리에 담긴 에이전트 지시 파일입니다. 저장소를 마운트하면 그 안의 스킬·규칙 파일이 세션 시작 시 로드될 수 있는데, 이 파일들은 저장소에 커밋 권한이 있는 누구나 바꿀 수 있습니다. 외부 기여자가 있는 저장소를 마운트한다면 이 경로를 신뢰 경계 안으로 들이는 것이므로, 마운트 전에 지시 파일을 감사해야 합니다.

신뢰 경계 점검 질문
1. 이 에이전트가 읽는 데이터 중 외부인이 쓸 수 있는 것은?
   → 웹 페이지, 업로드 문서, 티켓 본문, 저장소 파일, MCP 응답
2. 그 데이터가 지시로 해석되면 무엇을 할 수 있는가?
   → 에이전트의 툴 목록이 곧 피해 범위
3. 그중 되돌릴 수 없는 것은?
   → 이것들만 사람 확인 게이트를 건다

네트워크 경계와 두 층의 허용 목록

마지막 공백은 네트워크 egress입니다. 에이전트가 코드를 실행할 수 있다면 임의의 호스트로 데이터를 보낼 수 있습니다. 인젝션이 성공했을 때 유출 경로가 되는 것이 바로 여기입니다.

기본 설계는 거부 우선(deny by default) 입니다. 실행 환경의 네트워크를 제한 모드로 두고 필요한 호스트만 허용 목록에 넣습니다.

여기서 자주 틀리는 지점은 허용 목록이 두 층에 따로 있다는 것입니다.

무엇을 통제하는가
실행 환경이 호스트로 나갈 수 있는가
자격 증명이 호스트로 나갈 때 비밀을 붙일 것인가

둘은 목적이 다르고 서로를 대신하지 못합니다. 자격 증명의 허용 호스트에 도메인을 넣어도 실행 환경이 그 호스트를 막고 있으면 요청 자체가 나가지 못합니다. 반대로 실행 환경만 열어두고 자격 증명 범위를 좁히지 않으면, 키가 의도하지 않은 호스트로 함께 나갈 수 있습니다. 양쪽 모두에 등록해야 동작하고, 양쪽 모두 좁혀야 안전합니다.

패키지 관리자와 외부 연결 서버는 별도 스위치로 다루는 경우가 많습니다. 제한 모드에서 이것들을 켜지 않으면 관련 툴이 조용히 실패하는데, 오류 메시지가 네트워크 문제로 보이지 않아 디버깅이 오래 걸리는 대표적인 함정입니다.

마지막으로 키 범위 자체를 좁히는 것을 잊지 마십시오. 에이전트가 쓰는 키는 그 작업에 필요한 최소 권한으로 발급해야 합니다. 저장 위치를 아무리 잘 설계해도, 키 자체가 관리자 권한이면 사고 시 피해 범위가 그만큼 넓어집니다.

시험 함정

  • 자격 증명을 환경 변수로 샌드박스에 넣으면 안전하다는 선택지 — 샌드박스 안의 코드는 환경 변수를 읽을 수 있으므로 경계 바깥에 두고 나갈 때 주입해야 합니다.
  • 시스템 프롬프트에 API 키를 넣어 에이전트가 쓰게 하는 방안 — 프롬프트는 세션 이력에 저장되고 조회 가능하며 요약에도 섞입니다.
  • 권한 없는 문서를 언급하지 말라고 프롬프트에 지시해 접근 통제를 구현하는 방안 — 모델이 이미 내용을 봤으므로 통제가 아니고, 인가는 검색 단계에서 적용해야 합니다.
  • 프롬프트 인젝션을 프롬프트 작성 문제로만 다루는 선택지 — 피해 범위는 에이전트의 권한과 같으므로 권한 축소가 1차 방어입니다.
  • 자격 증명의 허용 호스트만 좁히면 egress가 통제된다는 서술 — 실행 환경과 자격 증명은 별개의 층이라 양쪽 모두 설정해야 합니다.
  • 마운트한 저장소의 지시 파일은 내부 자산이므로 신뢰해도 된다는 서술 — 커밋 권한이 있는 누구나 수정할 수 있어 인젝션 경로가 됩니다.

실습 시나리오

실제 시험과 같은 형식의 시나리오 문제입니다.

고객 문의를 처리하는 에이전트가 티켓 본문을 읽고, 사내 위키를 검색하고, 답변 메일을 발송합니다. 티켓은 외부 고객이 자유롭게 작성합니다. 보안 검토에서 가장 먼저 지적해야 할 구조적 결함은 무엇입니까?

빌드 연습 · 에이전트 신뢰 경계 다이어그램 작성

45
  1. 1.입력 출처 목록화

    에이전트가 읽는 모든 데이터 출처를 적고 각각에 대해 외부인이 내용을 쓸 수 있는지 표시합니다.

    기대 결과 · 외부 쓰기 가능 출처가 별도로 구분되고, 마운트된 저장소의 지시 파일도 목록에 포함됩니다.

  2. 2.피해 범위 산정

    에이전트의 툴 목록을 인젝션 성공 시 가능한 행동으로 다시 읽고, 되돌릴 수 없는 것을 표시합니다.

    기대 결과 · 되돌릴 수 없는 행동 목록이 만들어지고 각각에 현재 게이트 유무가 기록됩니다.

  3. 3.자격 증명 위치 추적

    각 외부 호출에 쓰이는 자격 증명이 샌드박스 안에 있는지 바깥에 있는지 확인합니다.

    기대 결과 · 샌드박스 안에 있는 자격 증명이 식별되고 각각에 대해 이전 방안이 기록됩니다.

  4. 4.인가 적용 지점 확인

    검색·조회 경로마다 요청자 권한이 어느 단계에서 적용되는지 추적합니다.

    기대 결과 · 프롬프트나 모델 후처리에 의존하는 경로가 드러나고 데이터 계층 필터로 옮길 계획이 세워집니다.

  5. 5.두 층 허용 목록 대조

    실행 환경의 네트워크 허용 목록과 자격 증명의 허용 호스트를 나란히 놓고 비교합니다.

    기대 결과 · 한쪽에만 있는 호스트가 발견되고, 각각이 의도된 것인지 판정됩니다.

출처 및 더 읽기