AI 정보보호 설계 (3) AI가 답하지 않고 실행하기 시작했습니다
입력과 응답을 검사하는 것으로 충분하다고 생각했습니다. AI가 답하는 대신 사내 시스템을 직접 실행하기 시작하면서 전제가 깨졌습니다.
AI가 사내 시스템을 직접 실행할 때를 다룹니다. 시리즈의 다른 글 보기
안녕하세요. 오픈소프트랩에서 생성형 AI 거버넌스 제품을 만드는 개발팀입니다.
1편에서 무엇이 AI로 들어가는지를, 2편에서 그걸 어떻게 판정할지를 썼습니다.
두 글의 전제가 같습니다. 사용자가 무언가를 보내고, AI가 답을 돌려준다. 그 사이를 검사하면 된다는 그림입니다.
이 전제가 깨졌습니다.
전제가 깨진 장면
개발자가 쓰는 에이전트 도구에 사내 시스템을 연결해두면, 문장 하나로 이런 일이 일어납니다.
"VIP 고객 목록 뽑아서 슬랙에 공유해줘"
→ db_query
SELECT * FROM customers WHERE tier="VIP";
실행 완료 · 1,247건 반환
→ slack_post
channel="#partner-external"
실행 완료 · 외부 채널 전송됨예시입니다. 실제 고객 데이터가 아닙니다.
여기서 사용자가 보낸 것은 한 문장뿐입니다. 민감정보가 하나도 없습니다. 1편에서 다룬 첨부 파일도 없습니다.
그런데 1,247명의 이름과 연락처가 조회됐고, 협력사가 들어와 있는 외부 채널로 나갔습니다. 사전 확인은 없었고, 회사에 남은 기록도 없었습니다.
입력과 응답만 보는 검사는 이 요청을 문제없는 요청으로 판정합니다. 검사할 것이 정말로 없으니까요.
용어를 정리하고 가겠습니다.
- 도구(Tool) — AI에게 열어 준 업무 기능 하나입니다. 곧 권한 하나이기도 합니다
- 에이전트(Agent) — 목적을 받아 도구를 순서대로 실행하는 AI입니다
- MCP(Model Context Protocol) — 도구를 AI에 연결하는 표준 규격입니다
목록을 거르면 되지 않을까
처음 생각은 단순했습니다. 에이전트에게 보여주는 도구 목록을 줄이면 된다.
위험한 도구를 목록에서 빼면 에이전트가 그 도구의 존재를 모릅니다. 모르면 호출하지 않습니다.
절반은 맞습니다. 실제로 목록을 줄이는 건 지금도 합니다. 그런데 이것만으로는 안 되는 이유가 두 가지 있었습니다.
첫째, 목록과 실행이 다른 경로입니다. 목록은 "뭘 쓸 수 있는지 알려주는" 응답이고, 실행은 별도 호출입니다. 목록에 안 띄워도 도구 이름을 아는 쪽에서 직접 호출하면 그대로 실행됩니다. 목록 필터는 안내판이지 문이 아닙니다.
둘째, 같은 도구라도 인자에 따라 위험이 다릅니다. db_query라는 도구 하나를 허용하면, 그 안에서 어떤 쿼리가 나가는지는 도구 단위로 통제할 수 없습니다. 조회 한 건과 전체 덤프가 같은 도구입니다.
그래서 목록을 거르는 대신 모든 호출이 실제로 지나가는 자리를 만들었습니다. 안내판이 아니라 문으로 바꾼 겁니다.
나가는 것만 보면 부족했습니다
호출을 붙잡아 검사하기 시작했습니다. 토큰이 유효한지, 권한 범위 안의 도구인지, 실행 명령에 문제가 없는지 봤습니다.
여기까지 하고 나서 놓친 걸 발견했습니다. 위 장면을 다시 보면 문제가 어디서 생기는지 보입니다.
db_query ← 실행해도 되는 조회. 담당자 권한 안에 있음
slack_post ← 실행해도 되는 전송. 이것도 권한 안에 있음두 호출 다 개별로는 정상입니다. 조회 권한도 있고 슬랙에 글 쓸 권한도 있습니다.
문제는 순서입니다. 내부에서 꺼낸 데이터가 외부로 나가는 흐름이 되는데, 호출 하나씩만 보면 이게 안 보입니다.
그래서 돌아오는 것도 검사하기로 했습니다. 실행을 허용했더라도 결과에 개인정보가 있으면 가리고, 내부에서 조회한 데이터가 외부로 나가는 흐름은 막습니다.
2편에서 만든 다섯 칸이 여기서도 쓰입니다.
"최근 3개월 거래 없는 계좌 고객 목록 뽑아줘"
→ 실행 허용
→ 조회 결과 1,284건
→ 반환 데이터 검사
→ 이름·연락처만 가려서 전달 (홍** · 010-****-1234)예시입니다.
목록은 만들어지고 업무는 진행됩니다. 이름과 연락처만 빠집니다. 차단 한 칸만 있었으면 담당자는 이 작업을 못 했을 겁니다.
도구 정의도 검사 대상이었습니다
이건 나중에 알았습니다.
도구는 "이런 이름으로 이런 인자를 받는다"는 정의를 에이전트에게 알려줍니다. 에이전트는 그 정의를 보고 호출을 만듭니다.
그 정의가 바뀌면 어떻게 될까요. 같은 이름의 도구가 다른 일을 하게 만들 수 있습니다. 에이전트는 정의를 믿고 호출하니 이상한 점을 모릅니다.
그래서 도구 정의가 등록 시점과 같은지 확인하는 검사를 넣었습니다. 사용자 권한 검사와는 별개입니다. 권한이 맞는 사용자가 정상적으로 호출해도, 도구 자체가 바뀌어 있으면 막아야 합니다.
얻은 것과 포기한 것
얻은 것 — 우회 경로가 없습니다. 실제 호출이 반드시 이 자리를 지나므로 목록 필터처럼 건너뛸 방법이 없습니다.
포기한 것 — 지연입니다. 모든 호출이 한 자리를 지나면 그만큼 시간이 붙습니다. 에이전트는 도구를 여러 번 연속으로 부르기 때문에 한 번에 붙는 지연이 작아도 쌓입니다.
그리고 기존 시스템을 다시 만들지 않기로 한 것도 선택이었습니다. 표준 MCP 서버만 받으면 구조가 깔끔해지는데, 그러면 이미 있는 REST API와 DB를 전부 MCP 서버로 감싸야 합니다. 도입하는 쪽에서 할 일이 너무 많아집니다. 그래서 기존 API·파일 서버·DB를 그대로 도구로 등록할 수 있게 열었고, 대신 연결 방식마다 다른 처리를 떠안았습니다.
경계를 어디에 그을 것인가
어디까지를 하나의 작업으로 볼 것인가.
위 장면에서 문제는 호출 하나가 아니라 호출 두 개의 연결이었습니다. 그러면 몇 개까지를 하나로 묶어서 봐야 할까요.
조회하고 바로 전송하면 잡힙니다. 그런데 조회하고, 가공하고, 다른 걸 조회하고, 한참 뒤에 전송하면 어떨까요. 중간에 다른 작업이 섞이면 어디까지가 같은 흐름인지 경계가 흐려집니다.
지금은 짧은 구간만 보기로 했습니다. 길게 볼수록 잡히는 건 늘지만 오탐도 늘고, 상태를 들고 있어야 해서 지연이 붙습니다. 에이전트는 도구를 연속으로 부르기 때문에 지연이 특히 민감합니다.
구간을 늘리는 대신 바깥으로 나가는 도구 쪽을 조이는 방향을 보고 있습니다. 흐름 전체를 추적하는 것보다, 외부로 나가는 지점에서 한 번 더 확인하는 편이 같은 위험을 더 싸게 막을 수 있을 것 같습니다.
에이전트가 스스로 도구를 요청할 때.
필요한 도구가 목록에 없으면 에이전트가 문장으로 요청하게 해뒀습니다. 권한 안이면 바로 추가하고 아니면 승인 요청을 만듭니다. 에이전트가 멈추지 않게 하려는 장치인데, 이 경로로 목록이 계속 늘어나는 조직이 생길 수 있습니다. 승인이 형식적으로 흘러가면 처음에 목록을 줄인 의미가 없어집니다.
그래서 목록에 도구가 추가된 이력을 따로 남기고 있습니다. 승인 건수가 아니라 목록이 얼마나 빨리 늘어나는지를 보려는 것입니다. 승인 피로는 건건이 막기 어렵고, 늘어나는 속도로 먼저 드러난다고 봤습니다.
이건 2편의 승인 대기 문제와 뿌리가 같습니다. 사람이 관여하는 절차를 어떻게 지치지 않게 만들 것인가 — 두 글에 걸쳐 남은 숙제입니다.
다음 시리즈에서는 지금까지 만든 것들이 공통으로 남기는 것을 다룹니다. — 시리즈 목차
오픈소프트랩 개발팀이 작성합니다. 생성형 AI 사용 통제와 AI 에이전트의 도구 실행 통제를 만들고 있습니다.