본문 바로가기
AI2026년 9월 18일10분 읽기

코딩 에이전트 샌드박싱 — 파일·네트워크·시크릿 경계 설계

YS
김영삼
조회 136
코딩 에이전트 샌드박싱 — 파일·네트워크·시크릿 경계 설계

코딩 에이전트는 파일을 읽고 쓰고 명령을 실행한다. 이 권한은 기능의 핵심이지만 동시에 공격면이다. 저장소의 문서, 의존성의 README, 웹에서 가져온 문서에 들어 있는 텍스트가 에이전트의 다음 행동에 영향을 줄 수 있다는 점을 전제로 설계해야 한다.

방어의 기본 원칙은 하나다. 에이전트가 무엇을 하든 피해 범위가 한정되게 만든다. 완벽한 통제는 불가능하므로, 통제 대신 경계를 설계한다.

나는 에이전트에게 처음 쉘 실행 권한을 줬을 때 막연히 불안했다. 그런데 무엇이 불안한지 구체화하기 어려웠다. 정리해 보니 질문은 네 개였다. 어디까지 읽을 수 있나, 어디까지 쓸 수 있나, 어디로 데이터를 보낼 수 있나, 무엇을 되돌릴 수 없나. 이 네 가지에 답하는 것이 곧 샌드박스 설계다.

네 가지 경계

경계통제 대상대표 수단
파일 읽기시크릿·개인 자료 노출작업 디렉터리 제한, 경로 정규화 후 검사
파일 쓰기시스템 손상·백도어 삽입쓰기 가능 경로 화이트리스트, 버전 관리로 변경 추적
네트워크데이터 유출·악성 페이로드 수신이그레스 허용 목록, 프록시 경유
되돌릴 수 없는 동작배포·삭제·전송·결제승인 게이트, 드라이런 기본값
가장 흔한 사고 경로 실제로 문제가 되는 건 정교한 공격이 아니라 평범한 실수다. 에이전트가 홈 디렉터리의 설정 파일을 읽어 컨텍스트에 넣고, 그 컨텍스트가 로그에 남고, 로그가 공유된다. 악의가 전혀 없어도 자격증명이 유출된다.

파일 경계 — 경로 검사는 정규화 후에

경로 제한의 고전적 실수는 문자열 비교로 검사하는 것이다. ../나 심볼릭 링크로 쉽게 우회된다. 반드시 정규화한 절대 경로로 비교해야 한다.

// 취약한 검사
function isAllowed(p) {
  return p.startsWith('/workspace');      // '/workspace/../etc/passwd' 통과
}

// 안전한 검사
import path from 'node:path';
import fs from 'node:fs';

function isAllowed(p, root = '/workspace') {
  const realRoot = fs.realpathSync(root);
  let target = path.resolve(root, p);
  // 심볼릭 링크 해석 — 존재하지 않는 경로는 상위 디렉터리 기준으로
  try { target = fs.realpathSync(target); }
  catch { target = path.resolve(fs.realpathSync(path.dirname(target)), path.basename(target)); }
  const rel = path.relative(realRoot, target);
  return rel !== '' && !rel.startsWith('..') && !path.isAbsolute(rel);
}
파일 경계 점검
작업 루트를 명시하고 모든 경로를 그 기준으로 정규화하는가
심볼릭 링크를 해석한 뒤 검사하는가
홈 디렉터리의 설정 파일(~/.aws, ~/.ssh, ~/.config)이 접근 범위 밖인가
.env와 시크릿 파일을 읽기 대상에서 제외했는가
쓰기 가능한 경로를 읽기보다 더 좁게 잡았는가
컨테이너를 쓴다면 볼륨 마운트가 필요한 경로만 연결돼 있는가

네트워크 경계 — 이그레스가 핵심

인바운드보다 아웃바운드가 중요하다. 데이터 유출은 나가는 연결로 일어나기 때문이다. 기본 차단 후 필요한 도메인만 허용하는 구성이 이상적이다.

# 컨테이너 기반 에이전트의 이그레스 통제 예 (개념)
# 1) 기본 아웃바운드 차단
iptables -P OUTPUT DROP
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 2) DNS 는 내부 리졸버로만
iptables -A OUTPUT -p udp --dport 53 -d 10.0.0.2 -j ACCEPT

# 3) 필요한 목적지만 허용 (패키지 레지스트리, 내부 저장소 등)
#    IP 는 변할 수 있으므로 실무에서는 프록시 경유가 더 관리하기 쉽다
#    HTTP(S)_PROXY 를 강제하고, 프록시에서 도메인 허용 목록을 관리

# 4) 프록시 로그로 어디에 접속했는지 감사
#    "빌드가 낯선 도메인에 접속했다"는 강력한 침해 신호다

프록시 방식이 관리하기 편한 이유는 도메인 단위로 허용할 수 있고, 로그가 남기 때문이다. IP 기반 규칙은 CDN을 쓰는 서비스에서 금방 무너진다.

시크릿 — 애초에 두지 않기

경계를 아무리 잘 그어도, 환경 안에 자격증명이 있으면 언젠가 컨텍스트나 로그에 섞인다. 가장 확실한 방어는 훔칠 것을 두지 않는 것이다.

1
환경 변수 정리
에이전트가 도는 프로세스의 환경에서 클라우드 키·DB 비밀번호를 제거한다.
2
필요 시점에만 주입
배포처럼 자격증명이 꼭 필요한 단계는 별도 프로세스·별도 잡으로 분리한다.
3
단기 토큰 사용
장기 키 대신 OIDC 기반 단기 자격증명을 쓰면 유출 시 피해 창이 짧다.
4
로그 마스킹
도구 출력과 로그에서 토큰 형태 문자열을 정규식으로 가린다.
5
시크릿 스캐닝
커밋 훅과 CI 양쪽에서 검사해 실수로 커밋되는 것을 막는다.
# 로그 마스킹 예 (간단한 형태)
MASK='s/(sk-[A-Za-z0-9]{16,}|ghp_[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16})/[REDACTED]/g'
agent-run 2>&1 | sed -E "$MASK" | tee run.log

# 더 나은 방법: 애초에 환경에 없게 만든다
env -i PATH=/usr/bin:/bin HOME=/workspace agent-run

승인 게이트 — 되돌릴 수 있는가로 나눈다

모든 동작에 승인을 요구하면 자동화의 의미가 없다. 기준은 단순하게 잡는 게 좋다. 되돌릴 수 있으면 자동, 되돌릴 수 없으면 승인.

동작되돌릴 수 있나정책
파일 수정(버전 관리 하)가능자동 허용
테스트·빌드 실행가능자동 허용
의존성 설치대체로 가능자동 허용 (락파일 변경은 리뷰)
브랜치 푸시가능(되돌리기 번거로움)조건부 — 보호 브랜치는 금지
프로덕션 배포어려움승인 필수
데이터 삭제·외부 전송불가승인 필수 + 감사 로그
드라이런을 기본값으로 파괴적 도구는 기본 동작을 드라이런으로 만들고, 실제 수행에는 명시적 플래그를 요구하는 설계가 안전하다. 에이전트가 실수로 호출해도 계획만 출력된다.

외부 콘텐츠를 데이터로 취급하기

에이전트가 읽는 파일, 웹 페이지, 이슈 코멘트에는 지시문처럼 보이는 문장이 들어 있을 수 있다. 이를 명령으로 실행하면 사고가 된다. 완전한 방어는 어렵지만, 구조적으로 위험을 줄일 수 있다.

  • 출처 표시 — 외부에서 가져온 내용은 경계를 명확히 표시해 컨텍스트에 넣는다.
  • 권한 분리 — 외부 콘텐츠를 읽은 세션과 배포 권한을 가진 세션을 분리한다.
  • 행동 제한 — 외부 콘텐츠 처리 중에는 되돌릴 수 없는 도구를 비활성화한다.
  • 검증 우선 — 결과는 항상 테스트·린트 같은 객관적 수단으로 확인한다.
  • 감사 로그 — 어떤 입력이 어떤 행동으로 이어졌는지 추적 가능하게 남긴다.

실행 환경 선택

컨테이너 기반
  • 파일·네트워크 격리가 명확
  • 환경 재현이 쉽다
  • 이그레스 통제를 붙이기 좋다
  • 손상 시 폐기하고 다시 만들면 된다
호스트 직접 실행
  • 설정이 간단하고 빠르다
  • 로컬 도구·캐시를 그대로 쓴다
  • 대신 격리가 사실상 없다
  • 홈 디렉터리 전체가 위험 범위

개인 실험은 호스트에서 해도 되지만, 자동화된 파이프라인이나 공유 환경에서는 컨테이너가 기본이다. 특히 에이전트가 사람의 승인 없이 도는 구간이 있다면 격리는 선택이 아니라 요건이다.

자주 묻는 질문

에이전트에게 쉘 실행 권한을 줘도 되나요?

작업 범위가 격리돼 있고 시크릿이 환경에 없다면 실용적입니다. 반대로 개인 노트북의 홈 디렉터리에서 무제한 실행하는 구성은 위험합니다. 최소한 작업 디렉터리 제한과 시크릿 분리는 갖춘 뒤 사용하세요.

경로 제한은 어떻게 구현하나요?

문자열 접두사 비교가 아니라 경로를 절대 경로로 정규화하고 심볼릭 링크를 해석한 뒤, 작업 루트와의 상대 경로가 상위로 올라가지 않는지 확인해야 합니다. 이 과정을 생략하면 쉽게 우회됩니다.

네트워크는 어디까지 막아야 하나요?

기본 차단 후 필요한 목적지만 허용하는 구성이 이상적입니다. 실무에서는 프록시를 강제하고 도메인 허용 목록을 프록시에서 관리하는 방식이 운영하기 편하며, 접속 로그가 남아 이상 탐지에도 쓸 수 있습니다.

시크릿이 컨텍스트에 섞이는 것을 어떻게 막나요?

가장 확실한 방법은 에이전트가 도는 환경에 자격증명을 두지 않는 것입니다. 꼭 필요한 단계만 별도 프로세스로 분리하고 단기 토큰을 사용하며, 로그와 도구 출력에 마스킹을 적용하세요.

어떤 동작에 사람 승인을 요구해야 하나요?

되돌릴 수 있는지를 기준으로 나누면 명확합니다. 버전 관리 하의 파일 수정이나 테스트 실행은 자동으로 두고, 프로덕션 배포·데이터 삭제·외부 전송처럼 복구가 어려운 동작에는 승인을 요구하세요.

외부 문서의 지시문이 에이전트를 움직이는 문제는요?

완전한 차단은 어렵지만 구조로 줄일 수 있습니다. 외부 콘텐츠는 출처를 표시해 데이터로 취급하고, 그것을 읽는 세션에서는 되돌릴 수 없는 도구를 비활성화하며, 결과는 항상 테스트 같은 객관적 수단으로 검증하세요.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록