본문으로 건너뛰기
메뉴
나에게 필요할까?에이전트가 내 컴퓨터에서 닿을 수 있는 것작동 방식에이전트와 시스템 사이에 놓이는 계층비교내장 샌드박스, Docker, VM설정작업에 필요한 것만 열기보안위협 모델과 한계설치
설정

기본은 닫힘, 스위치는 내 손에

옵션을 주지 않으면 에이전트는 프로젝트만 받습니다. 네트워크도 로그인도 키도 없습니다. 작업에 필요한 것을 스위치 하나씩 열면 되고, 감옥을 더 닫을 수도 있습니다.

설정이 들어오는 세 곳

설정은 프로젝트 안의 파일, 홈 디렉터리의 파일, 직접 입력한 플래그에서 옵니다. 권한이 낮은 것부터 높은 순으로 적었습니다.

세 가지 출처가 감옥으로 들어갑니다. 프로젝트의 .ai-jail 파일은 감옥을 더 조일 수만 있습니다. 전역 ~/.ai-jail 파일은 신뢰됩니다. 명령줄 플래그는 둘보다 우선합니다. 감옥 안에는 에이전트가 스위치 한 줄 뒤에 있고, 스위치는 대부분 꺼져 있습니다.
클론한 저장소는 자기 감옥을 스스로 열 수 없습니다.

프로젝트 .ai-jail

ai-jail은 이 파일을 신뢰하지 않습니다. 감옥을 더 조일 수만 있고 열 수는 없습니다. 심볼릭 링크로 걸려 있으면 따라가지 않고, 에이전트에는 그 자리에 빈 파일이 보입니다.

전역 ~/.ai-jail

내 파일이므로 ai-jail이 신뢰합니다. 모든 실행에 적용되는 기본 테이블이 있고, 명령의 첫 단어로 선택되는 [commands.<name>] 테이블을 둘 수 있습니다.

명령줄 플래그

플래그의 권한이 가장 높습니다. 스위치는 대부분 --network--no-network처럼 쌍으로 있어서, 파일이 연 것을 플래그로 닫을 수도 있습니다.

명령 테이블에서 단일 값은 기본 테이블의 값을 대체하고, 매핑이나 마스크 같은 목록은 기본 테이블의 목록에 더해집니다.

~/.ai-jail
# 기본 테이블: 모든 명령에 적용hide_dotdirs = [".my_secrets"]mask = [".env", ".env.*"] # 명령이 "claude"로 시작할 때만[commands.claude]network = trueagent_state = trueenv_pass = ["ANTHROPIC_BASE_URL"]mask = ["*.pem"]

스위치 목록

모든 행은 요청하기 전까지 꺼져 있고, 기능 플래그마다 다시 닫는 --no- 짝이 있습니다. 빨간 배지는 감옥을 약하게 만드는 스위치를 뜻합니다. 전체 목록과 이유는 보안 페이지에 있습니다.

네트워크와 서비스

플래그설정 키하는 일위험
--networknetwork = true제한 없는 네트워크 접근. 에이전트가 읽을 수 있는 것은 무엇이든 밖으로 보낼 수 있습니다.감옥을 약하게 함
--sshssh = true~/.ssh를 읽기 전용으로 열고 SSH 에이전트 소켓을 연결해서 git push가 되게 합니다.한 가지를 엶
--dockerno_docker = falseDocker 소켓. 데몬이 호스트를 마운트한 컨테이너를 띄울 수 있으므로 사실상 내 컴퓨터의 root 권한입니다.감옥을 약하게 함
--tailscaletailscale = trueTailscale 소켓.한 가지를 엶
--systemd-usersystemd_user = truesystemd 사용자 버스. 에이전트가 내 사용자 매니저에게 호스트에서 서비스를 실행해 달라고 요청할 수 있습니다. Linux 전용.감옥을 약하게 함

에이전트와 환경

플래그설정 키하는 일위험
--agent-stateagent_state = true~/.claude, ~/.codex 같은 에이전트 자신의 로그인과 설정. 켜면 감옥 안의 모든 것이 그 자격 증명을 쓸 수 있습니다.한 가지를 엶
--claude-dir <PATH>claude_dir = "..."지정한 디렉터리를 Claude의 상태 디렉터리로 쓰고 CLAUDE_CONFIG_DIR을 설정합니다.한 가지를 엶
--env <NAME[=VALUE]>없음셸에 있는 변수 하나를 전달하거나 NAME=VALUE로 변수 하나를 설정합니다. 여러 번 쓸 수 있고 디스크에 저장되지 않습니다.한 가지를 엶
--inherit-envinherit_env = true셸 환경 전체를 그 안의 시크릿까지 모두 전달합니다. 쓰지 마세요.감옥을 약하게 함
없음env_pass = ["NAME"]--env와 같지만 전역 파일에서만 동작합니다. 프로젝트 파일에 설정하면 무시됩니다.한 가지를 엶

데스크톱과 하드웨어

플래그설정 키하는 일위험
--gpuno_gpu = falseGPU 장치. 드라이버의 공격 표면도 함께 열립니다. Linux 전용.한 가지를 엶
--displayno_display = falseWayland 소켓만 열고 세션의 다른 것은 열지 않습니다. Linux 전용.한 가지를 엶
--x11x11 = trueX11 소켓. X11에서는 프로그램이 키 입력을 기록하고 스크린샷을 찍을 수 있습니다.감옥을 약하게 함
--audioaudio = truePipeWire와 PulseAudio 소켓, 그리고 /dev/snd. 감옥 안의 모든 것이 오디오를 녹음하고 재생할 수 있습니다. Linux 전용.한 가지를 엶
--host-shmhost_shm = true호스트의 /dev/shm. 감옥 바깥 프로세스와 공유하는 메모리가 열립니다.한 가지를 엶
--picturespictures = true~/Pictures, 읽기 전용.한 가지를 엶
--browser[=hard|soft]browser_profile = "hard"별도의 브라우저 프로필. hard(기본값)는 실행 사이에 아무것도 남기지 않고, soft~/.local/share/ai-jail/browsers 아래에 프로필을 보관합니다.한 가지를 엶

파일

플래그설정 키하는 일위험
--map <PATH|SOURCE:DEST>ro_maps = [...]경로 하나를 읽기 전용으로 추가 마운트합니다. 다른 위치에 마운트하려면 SOURCE:DEST로 씁니다. 여러 번 쓸 수 있습니다.한 가지를 엶
--rw-map <PATH|SOURCE:DEST>rw_maps = [...]경로 하나를 읽기·쓰기로 추가 마운트합니다. 여러 번 쓸 수 있습니다.한 가지를 엶
--overlay-map <PATH>overlay_maps = [...]경로를 copy-on-write로 마운트합니다. 에이전트가 쓴 내용은 별도 레이어로 가고 원본은 그대로 남습니다. Linux 전용이며 macOS에서는 읽기 전용 마운트가 됩니다.한 가지를 엶
--hide-dotdir <NAME>hide_dotdirs = [...].my_secrets처럼 이름을 지정한 점(.) 디렉터리를 절대 마운트하지 않습니다. 여러 번 쓸 수 있습니다.

끌 수는 있지만 끄면 안 되는 계층

플래그설정 키하는 일위험
--no-landlockno_landlock = true파일 규칙을 커널 안에서 한 번 더 적용하는 Landlock을 끕니다. --lockdown에서는 거부됩니다.감옥을 약하게 함
--no-seccompno_seccomp = true위험한 시스템 콜을 막는 필터를 끕니다.감옥을 약하게 함
--no-rlimitsno_rlimits = true폭주하는 프로세스를 멈추는 제한을 끕니다.감옥을 약하게 함
--no-private-homeprivate_home = false새 홈 디렉터리를 포기합니다. 실제 홈이 폭넓게 열립니다. 필요한 경로 하나만 --map으로 여는 편이 낫습니다.감옥을 약하게 함

각 계층이 하는 일은 작동 방식에서 설명합니다.

유틸리티

플래그하는 일
--dry-run샌드박스 명령을 출력하고 아무것도 실행하지 않습니다. 설정 파일도 쓰지 않습니다.
--init프로젝트 .ai-jail을 쓰거나 업데이트하고 종료합니다.
--clean이번 실행에서 프로젝트 .ai-jail을 무시합니다.
--bootstrapAI 도구 자체의 권한 설정을 생성합니다.
status현재 .ai-jail 설정을 보여 줍니다.
-v, --verbose감옥을 구성하는 동안 마운트를 하나하나 보여 줍니다.

나머지는 ai-jail --help로 확인하세요. 상태 표시줄, worktree, mise, 터미널 옵션이 있습니다.

프로젝트 안의 시크릿 숨기기

.env 파일은 프로젝트 안에 있고, 프로젝트는 읽고 쓸 수 있습니다. 네트워크가 켜져 있으면 에이전트는 거기서 읽은 것을 무엇이든 밖으로 보낼 수 있습니다. 마스킹하면 에이전트는 그 파일을 읽지 못합니다.

프로젝트 폴더. 에이전트는 src, package.json, README.md에 닿습니다. .env 파일은 마스킹되었고 secrets 폴더는 거부되었습니다. 둘 다 흐리게 막혀 있고 에이전트에서 나온 선이 닿지 않습니다.
프로젝트의 나머지는 그대로입니다.

--mask <PATH|GLOB>

일치하는 파일을 모두 빈 플레이스홀더로 바꿉니다. 에이전트는 파일이 있다는 것만 알고 내용은 받지 못하므로, 파일 존재 여부만 확인하는 도구는 계속 동작합니다.

--deny-path <PATH|GLOB>

일치하는 경로에 접근하면 모두 권한 오류가 납니다.

--mask-except--deny-path-except

규칙에서 경로 하나를 예외로 빼냅니다. 보호를 약하게 만들기 때문에 프로젝트 파일에서는 설정할 수 없습니다.

플래그로
# glob은 따옴표로 감싸야 셸이 확장하지 않고 패턴 그대로 ai-jail에 전달됩니다ai-jail --mask .env --mask '.env.*' --mask '*.pem' --deny-path secrets/ claude ai-jail --mask '.env.*' --mask-except .env.example claude
.ai-jail
# 프로젝트 파일은 조이는 것이 허용되므로 저장소 안에서도 동작합니다mask = [".env", ".env.*", "*.pem"]deny_paths = ["secrets/"]

락다운: 읽기만 하고 고치면 안 되는 코드

--lockdown은 리뷰와 감사에 씁니다. 에이전트는 프로젝트를 읽고 질문에 답할 수 있지만 프로젝트 안의 파일은 바꿀 수 없습니다.

패널 두 개. 일반 모드에서는 에이전트가 벽 안에서 읽고 쓸 수 있는 프로젝트 폴더와 /tmp 폴더 옆에 있습니다. 락다운에서는 벽이 더 두껍고 프로젝트 폴더는 읽기 전용이며, 쓸 수 있는 곳은 /tmp뿐입니다.
에이전트와 프로젝트는 같고, 쓸 수 있는 곳은 임시 디렉터리뿐입니다.

달라지는 점

  • 프로젝트가 읽기 전용으로 마운트됩니다
  • Linux에서는 /tmp에만 쓸 수 있습니다. macOS에서는 쓸 수 있는 곳이 없습니다
  • 홈의 점(.) 디렉터리, 추가 매핑, 오버레이가 모두 없습니다
  • 환경을 비우고 PATH를 시스템 디렉터리로 고정합니다
  • Landlock이 필수입니다. 적용할 수 없으면 실행이 실패합니다
  • 프로세스 수, 열린 파일 수, 파일 크기 제한이 더 엄격해집니다
  • 다른 플래그를 넘겼더라도 디스플레이, 오디오, GPU, Docker, SSH 에이전트, mise는 없습니다
터미널
ai-jail --lockdown claude

레시피

하나를 골라 복사하세요. 무엇이 만들어지는지 보려면 먼저 --dry-run을 붙여 실행합니다.

매일 쓰는 클라우드 에이전트

호스팅된 모델을 쓰려면 API에 닿기 위한 네트워크와 인증을 위한 에이전트 로그인이 필요합니다. 둘 다 전역 파일에 넣어 두면 명령이 짧게 유지됩니다.

~/.ai-jail
# 한 번만, ~/.ai-jail에[commands.claude]network = trueagent_state = true # 그다음에는 어느 프로젝트에서든ai-jail claude

SSH로 git push

--ssh~/.ssh를 읽기 전용으로 마운트하고 SSH 에이전트 소켓을 전달합니다. 푸시하려면 네트워크도 필요합니다.

terminal
ai-jail --network --ssh --agent-state claude

mise 툴체인

새 홈 디렉터리에는 mise로 설치한 것이 없어서 ai-jail이 mise를 건너뜁니다. mise 디렉터리 두 개를 읽기 전용으로 매핑하세요.

~/.ai-jail
[commands.claude]ro_maps = ["~/.config/mise", "~/.local/share/mise"]

에이전트용 브라우저

--browser만 주면 페이지를 불러올 수도 창을 열 수도 없는 브라우저가 됩니다. Linux에서는 --network--display가 함께 필요하고, X11 브라우저에는 --display 대신 --x11이 필요합니다.

terminal
# Waylandai-jail --browser=soft --network --display chromium# X11ai-jail --browser=soft --network --x11 chromium

Claude 프로필 분리

실행할 때마다 서로 다른 Claude 디렉터리를 지정해서 업무용 로그인과 개인용 로그인을 따로 관리합니다.

terminal
ai-jail --network --claude-dir ~/.claude-work claude

위험한 리팩터링을 사본에서 해 보기

오버레이를 쓰면 에이전트가 쓴 내용은 프로젝트의 .ai-jail-overlays 아래 별도 레이어에 남습니다. 끝난 뒤 원본과 비교해서 마음에 드는 것만 가져오면 됩니다. Linux 전용.

terminal
ai-jail --network --agent-state --overlay-map ~/Projects/my-app/src claude

예전 설정도 계속 동작합니다

하위 호환성은 프로젝트 규칙입니다. 이 프로젝트는 플래그나 설정 키를 없애지 않습니다. 모르는 키는 무시하고 빠진 키에는 기본값을 쓰므로, 예전 버전용으로 쓴 파일도 그대로 읽힙니다.

오래된 스위치는 true가 끈다는 뜻인 반전된 이름을 그대로 씁니다. no_gpu, no_docker, no_display, no_mise, no_landlock, no_seccomp, no_rlimits가 그렇습니다. 그래서 --gpuno_gpu = false로 저장됩니다. 새로 생긴 스위치는 network = true처럼 평범한 이름을 씁니다.

에이전트를 철창 안에 넣으세요

ai-jail은 바이너리 하나입니다. 데몬도 root 권한도 필요 없습니다. 평소 실행하던 명령 앞에 단어 하나만 붙이면 됩니다.

terminal
brew tap akitaonrails/tap && brew install ai-jailai-jail claude