설치
Linux에서는 그대로 됩니다. 레지스트리와 github.com이 기본 목록에 있습니다. macOS에서는 --allow-host registry.npmjs.org처럼 하나를 더하거나, --network로 전부 여세요.
ai-jail은 프로그램 하나이고 데몬도 root도 필요 없습니다. 설치한 다음 평소 입력하던 명령 앞에 이름을 붙이면 에이전트가 샌드박스 안에서 시작됩니다.
키보드 앞에 앉은 사람을 위한 글입니다.
평소 명령줄 도구를 설치하던 방식을 고르세요. 어느 방법을 쓰든 똑같은 ai-jail 프로그램 하나가 설치됩니다.
brew tap akitaonrails/tap && brew install ai-jailmacOS와 Linux에서 됩니다.
yay -S ai-jail-binyay -S ai-jail첫 번째 패키지는 Linux x86_64용으로 미리 빌드된 바이너리입니다. 두 번째는 소스에서 빌드합니다.
cargo install --locked ai-jailRust 툴체인이 필요합니다. --locked를 주면 릴리스를 테스트할 때 쓴 의존성 버전으로 빌드합니다.
nix run github:akitaonrails/ai-jail -- claudenix profile install github:akitaonrails/ai-jail첫 줄은 아무것도 설치하지 않고 에이전트를 실행합니다. 둘째 줄은 내 사용자 계정에 설치합니다. flake는 ai-jail이 자체 포함된 bubblewrap을 쓰도록 연결합니다.
ai-jail-linux-x86_64.tar.gzai-jail-macos-aarch64.tar.gz압축 파일은 서명되어 있고 체크섬이 함께 올라와 있습니다. 하나를 풀어서 ai-jail을 PATH에 있는 위치에 두세요. 서명 확인 방법은 보안 페이지에 있습니다.
cargo build --release --lockedinstall -Dm755 target/release/ai-jail ~/.local/bin/ai-jail필요한 Rust 버전은 1.97.1입니다.
bubblewrap을 설치하세요. ai-jail이 샌드박스를 구성할 때 쓰는 작은 프로그램입니다. 대부분의 배포판에 bubblewrap이라는 패키지로 있습니다.
pacman -S bubblewrapapt install bubblewrapdnf install bubblewrap설치할 것이 없습니다. ai-jail은 macOS에 포함된 sandbox-exec를 씁니다. Apple은 이 인터페이스를 deprecated로 표시하고 있습니다. macOS에서는 패키지 레지스트리에 기본으로 닿지 않습니다. --allow-host로 하나를 더하거나, --network로 네트워크를 여세요.
지원하지 않습니다. WSL2를 쓰고 그 안에서 Linux 절차를 따르세요.
명령 세 개로 계획을 확인하고, 안을 둘러보고, 에이전트를 실제로 돌립니다. 에이전트의 로그인은 이미 안에 있고, API 호스트로 가는 길은 ai-jail이 대신 열어 줍니다.
↔ 옆으로 밀어 전체 다이어그램을 확인하세요
프로젝트로 이동해서 드라이 런을 요청합니다. ai-jail은 사용할 샌드박스 명령을 출력하고 종료합니다. 드라이 런은 파일을 쓰지 않습니다.
cd ~/Projects/my-appai-jail --dry-run claude감옥 안에서 일반 셸을 시작합니다. 프로젝트는 실제 경로에 그대로 있고 편집할 수 있습니다. 홈 디렉터리는 새로 만든 것이고 셸에 있던 토큰은 없습니다. 나가려면 exit를 입력합니다.
ai-jail bashai-jail은 에이전트 자신의 상태 폴더를 기본으로 마운트하므로 이미 로그인되어 있습니다. 아는 에이전트라면 그 에이전트 자신의 API 호스트도 필터링 프록시로 통과시킵니다. Claude Code는 api.anthropic.com, Codex는 api.openai.com과 chatgpt.com, Gemini는 generativelanguage.googleapis.com, Grok은 api.x.ai, Devin은 server.codeium.com이며, Linux와 macOS 모두 해당합니다. 텔레메트리 호스트는 닫힌 채로 남습니다. Linux에서는 툴체인이 crates.io, npm, PyPI 같은 패키지 레지스트리에 기본으로 닿아 빌드가 동작합니다. --network는 대신 네트워크 전체를 엽니다.
ai-jail claude# 아니면 네트워크 전체를 열고:ai-jail --network claude호스트 목록을 내 설정 파일인 ~/.ai-jail에 에이전트 이름 아래로 넣습니다. 목록은 에이전트 자신의 API 호스트에 더해지고, 그 호스트는 계속 허용되며, Linux에서는 github.com과 패키지 레지스트리가 이미 들어 있습니다. 아니면 --network로 네트워크 전체를 엽니다. 로그아웃 상태로 실행하려면 --no-agent-state를 넘기세요. 프로젝트 안의 .ai-jail 파일은 감옥을 더 조일 수만 있습니다. 호스트 목록이나 forward_ports 목록을 줄이거나 로그인을 끌 수는 있어도 그 반대는 안 되므로, 클론한 저장소가 스스로 감옥을 열 수는 없습니다.
[commands.claude]allow_hosts = ["api.example.com"]# ai-jail이 이미 허용하는 API 호스트와 레지스트리에 더해짐 # 아니면 한 번만 실행할 때:# ai-jail --network claude프롬프트가 (jail)로 바뀌고 프로젝트는 원래 있던 자리에 있습니다. 내 툴체인도 읽기 전용으로 거기 있습니다. 훔칠 만한 것은 보이지 않습니다. 에이전트 자신의 로그인만은 일부러 넣어 두었습니다.
$ ai-jail bash# 프로젝트는 실제 경로에 있습니다(jail) ~/Projects/my-app $ pwd/home/you/Projects/my-app# 셸에 export한 토큰은 따라오지 않았습니다(jail) ~/Projects/my-app $ echo $GITHUB_TOKEN # 이 홈에는 키가 없습니다(jail) ~/Projects/my-app $ cat ~/.ssh/id_ed25519cat: /home/you/.ssh/id_ed25519: No such file or directory# 감옥에는 전용 호스트 이름이 있습니다(jail) ~/Projects/my-app $ hostnameai-sandboxLinux 세션입니다. macOS에는 별도의 파일 트리를 만들 방법이 없어서 같은 경로가 존재하고, 읽으려고 하면 거부됩니다.
↔ 옆으로 밀어 전체 다이어그램을 확인하세요
안에서 보면 내 것 중에 바꿀 수 있는 것은 프로젝트뿐입니다. 내 툴체인(mise, cargo, npm 등)은 읽기 전용으로 있고, 의존성 캐시는 감옥 전용입니다. 네트워크는 알려진 에이전트 자신의 API 호스트와, Linux에서는 그 툴체인이 패키지를 받아 오는 레지스트리를 빼면 바깥에 있고, --allow-host로 호스트 하나를 열거나, --forward-port로 로컬 포트 하나를 열거나, --network로 전부 열기 전까지 그렇습니다. 툴체인 매핑 방식.
에이전트가 시작하는 모든 것이 에이전트와 함께 안에서 돌기 때문에, 막힌 것은 그냥 실패하고 아무도 내게 묻지 않습니다. 그때 어떻게 보이는지, 그리고 어떻게 확인하는지입니다.
--allow-host HOST를 주면 다음 실행부터 더해집니다.--env NAME이나 --env-from-file로 넘기지 않는 한 그렇습니다.--audit-log를 더하세요. 실행 하나하나와 프록시가 허용하거나 거부한 모든 연결을 기록합니다. ai-jail --audit-show가 그 기록을 출력합니다.ai-jail bash가 같은 감옥 안에서 셸을 엽니다.Linux에서는 그대로 됩니다. 레지스트리와 github.com이 기본 목록에 있습니다. macOS에서는 --allow-host registry.npmjs.org처럼 하나를 더하거나, --network로 전부 여세요.
내 컴퓨터의 루프백에 떠 있는 데이터베이스, 로컬 MCP 서버, 에디터 소켓은 Linux에서 --forward-port 5432로 그 포트 하나를 중계합니다. macOS에서는 --network입니다.
GitHub에서 클론과 풀은 Linux에서 그대로 됩니다. 푸시에는 자격 증명이 필요합니다. HTTPS로 gh 토큰을 쓰려면 --github(macOS에서는 --allow-host github.com도 더하세요), SSH 키를 쓰려면 --network --ssh입니다.
에이전트와 함께 감옥 안에서 시작합니다. 셸에서 토큰을 읽는 서버는 --env GITHUB_TOKEN이나 --env-from-file로 넘겨 주기 전까지 아무것도 받지 못합니다. HTTP로 닿는 원격 서버는 그 호스트가 --allow-host에 있어야 합니다.
README의 문제 해결 항목에 나오는 경우와, 설정하다가 자주 걸리는 규칙 두 가지입니다.
bwrap: setting up uid map: Permission deniedUbuntu 24.04 이상과 Debian 13 이상에는 프로그램이 root 없이 사용자 네임스페이스를 만들지 못하게 하는 AppArmor 정책이 들어 있습니다. bubblewrap은 바로 이 방법으로 감옥을 격리합니다. root 없이 동작하는 같은 종류의 도구가 모두 영향을 받습니다. 시스템 전체에서 정책을 완화하려면 이렇게 합니다.
echo 'kernel.apparmor_restrict_unprivileged_userns=0' \ | sudo tee /etc/sysctl.d/60-userns.confsudo sysctl --system정책은 그대로 두고 bwrap만 예외로 둘 수도 있습니다. 아래 내용을 /etc/apparmor.d/bwrap으로 저장한 뒤 sudo apparmor_parser -r /etc/apparmor.d/bwrap을 실행하세요.
abi <abi/4.0>,include <tunables/global>profile bwrap /usr/bin/bwrap flags=(unconfined) { userns,}BWRAP_BIN이 거부됩니다BWRAP_BIN으로 ai-jail이 쓸 bubblewrap을 지정할 수 있습니다. ai-jail은 그 경로가 root 소유이고 다른 사용자가 쓸 수 없는 프로그램이거나, 표준 다중 사용자 /nix/store 안의 프로그램일 때만 받아들입니다. 내 홈에 있는 사본은 거부합니다. 그 파일을 바꿔치기할 수 있는 사람이 감옥을 통제하게 되기 때문입니다.
Starting background server에서 멈춥니다opencode 2.x는 공유 백그라운드 서버와 통신합니다. 감옥은 새 홈을 가진 일회성 래퍼라서 그 서버가 실행 사이에 살아남지 못합니다. --standalone으로 opencode를 단독 실행하고, 매번 입력하지 않도록 설정 파일에 고정하세요. opencode가 이 옵션 없이 시작되면 ai-jail이 실행 시점에 경고합니다:
[commands.opencode]command = ["opencode", "--standalone"]Failed to create stream fd가 나옵니다Ubuntu 데스크톱에서 mise를 준비하는 동안 로그인 스크립트가 내는 메시지입니다. 해롭지 않고 mise도 정상 동작합니다. --no-mise를 주면 mise 준비를 건너뛰고 메시지도 나오지 않습니다.
ai-jail --no-mise claudeai-jail은 에이전트마다 로그인을 어디에 보관하는지 알고 있고 기본으로 마운트합니다. 시작하는 에이전트의 폴더만, 그것도 존재할 때만입니다. --no-agent-state로 끕니다. 셸에 설정되어 있으면 그 에이전트의 API 키 변수도 함께 들어갑니다: ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY 또는 GOOGLE_API_KEY, XAI_API_KEY, MOONSHOT_API_KEY.
| 실행하는 명령 | 기본으로 마운트되는 것 | 알아 둘 점 |
|---|---|---|
ai-jail claude | ~/.claude~/.claude.json | 두 번째 Claude 프로필을 쓰려면 --claude-dir로 해당 디렉터리를 지정하세요. |
ai-jail codex | ~/.codex | 창 크기를 바꾸면 ai-jail이 Codex에 다시 그리기 키를 보냅니다. macOS에서 lockdown이 아닌 Codex는 전용 ps 심을 받고, agent state가 켜져 있으면 앱 서버에 필요한 제한된 시스템 서비스도 받습니다. --no-agent-state는 서비스 권한만 없애며 심은 유지합니다. |
ai-jail gemini | ~/.gemini | |
ai-jail opencode | ~/.config/opencode~/.local/share/opencode | --standalone이 필요합니다. 위의 문제 해결 항목을 보세요. |
ai-jail antigravity | ~/.gemini | Gemini와 Google 로그인을 공유하므로 한 번 로그인하면 둘 다 됩니다. |
ai-jail kimi | ~/.kimi | 예전 위치인 ~/.kimi-code도 있으면 함께 마운트됩니다. |
ai-jail kiro-cli | ~/.kiro~/.local/share/kiro-cli | macOS에서는 두 번째 폴더가 ~/Library/Application Support/kiro-cli입니다. |
ai-jail prime-agent | ~/.prime/agent | 에이전트 자신의 폴더만 해당하고, ~/.prime 전체는 아닙니다. |
ai-jail devin | ~/.local/share/devin~/.config/devin | CLI 자체 설치본인 devin/cli/_versions 아래는 읽기 전용으로 남습니다. Devin은 호스트에서 업데이트한 뒤 새 세션을 시작하세요. |
ai-jail ai-memory run claude | 실행된 에이전트의 폴더 | ai-jail은 ai-memory가 실행하는 에이전트를 인식해서 그 에이전트의 설정을 적용하고, 두 프로그램을 한 감옥 안에서 실행합니다. |
crush, grok, jcode, pi, aider, soulforge, omp 명령도 똑같이 동작합니다. 그 밖의 명령도 실행됩니다. 같은 감옥을 받고 로그인 폴더는 받지 않습니다. ai-jail은 03단계의 다섯 에이전트에 대해 API 호스트를 기본으로 열고, 다른 에이전트에는 --allow-host나 --network가 필요합니다.
ai-jail은 바이너리 하나입니다. 데몬도 root 권한도 필요 없습니다. 평소 실행하던 명령 앞에 단어 하나만 붙이면 됩니다.
brew tap akitaonrails/tap && brew install ai-jailai-jail claude