요약
마이크로소프트의 MXC는 믿을 수 없는 코드를 윈도·리눅스·맥에서 같은 정책으로 격리해 실행합니다.
마이크로소프트가 MIT 라이선스로 공개한 오픈소스 프로젝트입니다. AI 모델이 만든 코드나 플러그인, 외부 도구처럼 믿기 어려운 작업을 앱 안에서 격리해 돌리도록 Rust, .NET, Node용 SDK를 제공합니다.
왜 중요한가
- 운영체제마다 다른 격리 기술을 직접 설정하지 않고 하나의 JSON 정책으로 다룰 수 있습니다.
- 가벼운 프로세스 샌드박스부터 가상 머신까지 같은 방식으로 골라 쓸 수 있습니다.
핵심 내용
- 기본 격리 방식은 윈도가 ProcessContainer, 리눅스가 Bubblewrap, 맥이 Seatbelt입니다.
- 정책으로 경로별 읽기·쓰기·차단, 외부 통신, 클립보드와 화면 접근을 제한합니다.
- 감사 모드(--audit)는 실제 접근을 기록해 정책 작성을 돕지만, 켜 둔 동안 보안이 모두 꺼집니다.
- Windows Sandbox, MicroVM, Hyperlight 백엔드는 아직 실험 단계로 표시돼 있습니다.
- 원격 측정(사용 데이터 수집)은 기본으로 꺼져 있고, 윈도 공식 빌드에서 동의할 때만 켜집니다.
HN 반응
- Bubblewrap 같은 도구를 직접 엮기 어렵다며 반기는 의견이 많았고, 접근을 기록하는 감사 모드가 특히 호평받았습니다.
- 맥에서는 호스트별 통신 제어가 빠졌고 호스트 커널도 함께 써서, 작업마다 VM을 띄우는 smolvm이 낫다는 반론이 나왔습니다.
생각보다 꽤 괜찮아 보입니다. 물론 bubblewrap/seatbelt/processcontainer의 프런트엔드나 SDK쯤으로 볼 수도 있습니다. 하지만 이것들을 일관되게 설정하는 일은 결코 만만치 않고, 직접 손으로 짜는 건 정말 나쁜 선택입니다(경험에서 하는 말입니다).
런타임에 어떤 권한과 설정이 필요한지 알아내는 '학습' 모드, MIT 라이선스, 선택 사항인 텔레메트리를 분명하게 공개한 점, 가벼우면서도 읽기 쉬운 문서가 마음에 듭니다.
마이크로소프트를 어떻게 생각하시든, 이건 꽤 쓸모 있어 보입니다. 목적이 분명하고, 얼핏 봐도 첫 버전치고는 완성도가 높은 프로젝트입니다.
쉽고 깔끔해 보이긴 하네요.
그래도 smolvm을 버릴 생각은 없어요.
작업마다 인스턴스를 하나씩 띄우는 스크립트가 있고, 코딩 에이전트는 Nono로 감싸서 돌려요.
작업에 필요한 git clone은 제가 넣어 주고요.
정말 잘 돌아가요.
감사합니다.
덧붙이자면 MXC는 여전히 호스트 커널을 공유합니다.
즉 맥에서는 MXC가 seatbelt를 쓰기 때문에 에이전트가 여러분의 커널을 그대로 공유합니다.
반면 smolvm은 맥, 리눅스, 윈도 어디서나 작업마다 자체 커널을 가진 별도 VM을 줍니다. 여기에 사전 설정된 seccomp, landlock 같은 층도 가능한 곳마다 더해지고요.
맞아요, smolvm( https://smolmachines.com )은 정말 좋죠. 구성하신 환경을 자세히 정리해 두신 글이 있나요?
저도 예전에 bubblewrap을 만져 봤는데, 조금만 복잡한 걸 하려고 하면 다루기가 꽤 버거워진다는 데 동의합니다. 원하는 대로 조립할 수 있는 레고 블록이 한 통 가득 있는 셈인데, 최종 사용자 입장에서는 대부분 미리 조립된 몇 가지 세트만 있으면 충분하죠.
저도 동감입니다! SDK 설계까지는 뭐라 말씀드리기 어렵지만, 겉으로 보기엔 에이전트 하니스나 파이프라인에 통합하기에 아주 좋은 선택지 같습니다.
특히 "audit"와 "debug" 모드가 유용합니다. 저는 bubblewrap을 쓰는데, 새 하니스를 여기에 올릴 때마다 strace로 하니스의 의존성을 전부 찾아내느라 보통 몇 번씩 두더지 잡기를 합니다.
가능성은 보이지만, 제가 정말 중요하게 보는 기능이 하나 빠져 있습니다. 세밀한 네트워킹 제어입니다.
Windows와 Linux에서는 되는데, 안타깝게도 macOS에서는 빠져 있습니다. 여기 지원 표를 보세요: https://github.com/microsoft/mxc/blob/main/docs/backends/seatbelt/seatbelt-backend.md#what-seatbelt-can-and-cant-enforce
macOS에 없는 것으로는 "호스트 이름 기준 허용/차단"과 "IP, CIDR, 포트, 프로토콜 기준 허용/차단"이 있습니다.
나머지는 다 훌륭해 보이고, Linux나 Windows를 쓰신다면 이런 제약은 해당되지 않습니다.
여러 기술 위에 추상화 계층을 만들 때 늘 따라오는 숙명 같은 문제인 듯합니다.
안녕하세요 Simon,
그런데 smol machines는 바로 그 기능들을 맥, 리눅스, 윈도 전부에서 지원해요: https://github.com/smol-machines/smolvm/blob/main/AGENTS.md#networking
설정하면 이런 모양이에요:
smolvm 저도 +1이에요! 저는 로컬/셀프 호스팅 GitHub Actions인 preloop( https://github.com/preloopdev/preloop )에서 작업마다 smolvm을 하나씩 띄워요. 제 기억이 맞다면 deny-cidr 옵션을 추가하는 작업도 있었는데, 그러면 더 유연하게 쓸 수 있겠죠. 그래도 egress 필터만으로 필요한 건 대부분 해결돼서 지금도 잘 쓰고 있어요.
preloop 작업물 보니 반갑네요 :)
이건 어떻게 하는 건가요?
중간에 프록시를 두는 건가요(그러면 인증서 고정 문제가 생길 텐데)?
아니면 DNS 필터링인가요(그러면 에이전트가 안정적인 IP를 "외워 둘" 수도 있잖아요)?
인증서 고정: 문제 없습니다. 트래픽을 복호화하지 않고 그대로 통과시킵니다. 예외는 자격 증명을 지정해 준 호스트뿐인데, 그 경우에는 키를 넣어야 하니까요.
외워 둔 IP: 통하지 않습니다. VM은 허용된 이름의 DNS 조회에서 나온 IP로만 접속할 수 있습니다. 그 밖의 IP는 전부 차단됩니다.
약간의 "공동 책임" 철학이 작용하긴 하지만, 기본값은 좋게 잡으려고 노력합니다.
세밀한 네트워크 정책은 microsandbox가 지원합니다. 여러 기술 위에 추상화 계층을 만드는 일을 이미 열심히 해 온 프로젝트입니다. Microsandbox는 (유닉스에서는) libkrun(유닉스용 VM 추상화 계층) 위에 만들어져 있습니다. 저는 microsandbox 위에 쓰기 편한 실행기를 만들고 있습니다: https://github.com/runcontain/runcontain (지금 이름을 바꾸는 중입니다). 마이크로소프트가 지금 가장 크게 기여할 수 있는 건 Windows용 경량 격리 기술일 겁니다.
HTTP 프록시를 (비슷한 규칙을 적용하는 식으로) 번들로 넣을 수도 있겠죠. Claude식 문장을 읽어 내려가려면 좀 품이 들지만, "Egress confinement is enforced; using the proxy is cooperative"는 결국 프록시를 거치는 경로 말고는 네트워크 외부 송신이 없다는 뜻입니다.
물론 그건 HTTP만 제한할 뿐, 다른 형태의 네트워크 요청까지 막지는 못합니다.
이런 샌드박싱 솔루션 중에 권한을 부여하는 동적인 기능이 있는 게 있나요? 최소한의 샌드박스로 시작해서, 필요해질 때마다 비동기로 권한을 추가하는 식으로요. 하니스가 프로젝트 밖 폴더에 접근할 때 이런 걸 시도하긴 하지만, 엄격하게 강제되지는 않을 때가 많고 보통은 철회도 안 됩니다. 게다가 하니스는 결정이 날 때까지 에이전트 실행을 막아 버려서, 에이전트가 다른 방법으로 바로 진행할 수 있는 상황에서도 계속 지켜보고 있어야 일이 굴러갑니다.
실수로
rm -rf를 치는 것과 개인 데이터 유출을 막아 주는 최소한의 샌드박스라는 발상은 마음에 듭니다. 그런데 그런 설정은 정작 해야 할 작업에 걸림돌이 되는 일이 잦습니다. 이상적으로는 샌드박스가 차단된 접근을 모아서 별도의 TUI 대시보드에 보여 주고, 제가 거기서 접근을 허용할 수 있으면 좋겠습니다. 이때 실행 중인 에이전트를 멈춰 세우지는 않아야 합니다. 멈춰 세우면 "확인 누르기" 피로에 빠지기 쉬우니까요.이와 비슷한 게 이미 있나요?
제가 제대로 이해했다면 https://nono.sh/ 가 그쪽 방향일 수 있습니다. 샌드박스 안에서 돌린 명령이 끝난 뒤에, 어떤 차단이 있었는지를 바탕으로 권한을 추가할 수 있습니다. 다만 말씀하신 것처럼 실시간으로 되는 건 아닙니다.
권한을 개별 셸 명령에 한정한다는 건 아주 흥미로운 발상이네요. 사람들이 이런 접근을 실험하고 있다는 건 분명 좋은 일입니다. 결국 아이디어가 수렴해서 샌드박스 프로젝트를 100개씩 알고 있지 않아도 되면 좋겠습니다 :)
저는 거기서 cline TUI를 돌리지 못했어요. node가 임시 폴더로 뭔가 복잡한 걸 하는 모양인데, 아예 실행이 안 되더라고요.
쓸 만한 capability 기반 OS가 있었다면 좋았을 텐데요. 그러면 모든 프로세스가 말씀하신 성질을 갖게 되잖아요. 디스크에 쓰게 하려면 디스크 쓰기 capability를 의존성 주입해 주면 되고, 원격 호스트와 통신해야 하면 그 호스트 하나에 대한 핸들만 건네면 되죠.
그런 capability를 주고 싶지 않다고요? 아무것도 안 하면 됩니다. 그게 기본 상태니까요.
프로젝트와는 관계없지만 개발 과정을 계속 지켜보고 있는데, https://5bsd.org/ 가 좋은 답이 될 수 있습니다. Kory가 BSD 커널 위에서 Linux API에 대한 capability 강제를 추가하고 있습니다(다른 멋진 기능들도 있고요).
저도 그 프로젝트를 꼭 지켜봐야겠네요.
안타깝게도 capability 기반 OS나 대부분 안전한 시스템 프로그래밍 언어로 짠 OS는 시도가 없어서 안 된 게 아닙니다.
하지만 메인프레임이나 마이크로컴퓨터, 혹은 틈새 배포 환경을 벗어나면 채택이 쉽지 않았습니다.
iOS/macOS와 리눅스 모두 capability를 지원합니다. 물론 어느 경우든 그 capability의 깊이는 부족할 수 있지만, 사람들은 그 방향으로 나아가고 있습니다.
리눅스의 파일 시스템 접근을 예로 들어 봅시다. 권한이 없는 사용자로 실행할 수도 있고, apparmor/SELinux 같은 걸 설정해서 목록에 없는 일을 하려는 프로그램을 막을 수도 있고, 컨테이너로 프로그램이 볼 수 있는 제한된 세계를 만들 수도 있습니다...
그런데 이건 전부 좀 임시방편 아닌가요? 근본 전제가 제약 없는 capability이고, OS는 거기에 제한 옵션을 얹어 주는 구조입니다.
제가 잘못 이해했을 수도 있지만, capability는 이 모든 것의 정반대라고 생각합니다. 걸어야 하니 다리를 주고, 헤엄쳐야 하니 지느러미를 주는 식이죠. 지금은 오히려 "저기엔 못 가" 하면서 발목에 감시 장치를 채워 주는 쪽에 가깝습니다.
Windows도 그렇습니다. 다만 그렇다고 해서 실제로 제대로 쓰이고 있다는 뜻은 아닙니다.
Fuchsia가 "선택지"이긴 한데, 드라이버를 직접 짜지 않으면 지원하는 하드웨어가 많지 않아요.
익숙해진 작업 방식 때문에 잘못된 양자택일에 빠져 계신 건 아닐까 싶습니다. 제 추측입니다만, 열린 결말의 대화형 세션에서 작업하다 보면 조사와 프로토타이핑을 충분히 한 뒤 구현으로 넘어가는 경계가 있고, 그때는 권한 범위가 바뀌어야 합니다. 이렇게 하고 계신다면 처음 조사하는 부분과 자리를 비워 두고 자동으로 돌리는 부분을 분리하는 게 최선이라는 걸 깨닫게 되실 것 같습니다.
순수한 조사나 프로토타이핑 단계에서도 샌드박스가 너무 빡빡하거나 너무 느슨한 문제에 금방 부딪힙니다. 작업에 따라 GPU 접근, Docker/Nix 소켓 접근, 프로세스 ptrace(gdb), 웹 페치 같은 것들이 필요할 수 있습니다. "조사"용 샌드박스 프로필에서 이걸 전부 허용해 버리면 샌드박스가 아예 없는 것과 다를 바 없습니다.
대부분 Rust인 350,000 SLOC입니다 1 ... 그런데 업스트림 샌드박스를 벤더링해서 넣은 것도 아니에요!
저라면 제가 파악하고 이해할 수 있는 것 위에 만드는 쪽이 훨씬 더 안심이 될 것 같습니다. 2
파일들을 둘러보면 절반 이상은 주석이나 단위 테스트일 겁니다. 예를 들면 이런 파일이 있습니다.
https://ghloc.dev/microsoft/mxc?branch=main&locsPath=%5B%22src%22%2C%22mxc-sdk%22%2C%22src%22%2C%22core%22%2C%22mxc_common%22%2C%22filesystem_dacl.rs%22%5D
그 사이트는 이 파일을 2.9k sloc로 보는데, Rust 주석은 파싱하지 않는 것 같습니다. 실제로는 1,465 sloc에 테스트가 635 loc입니다.
350k sloc와는 거리가 멀어도 한참 멉니다.
--
말씀하신 sandbox-run 얘기를 하자면, 기여자가 한 명뿐인 프로젝트고, 테스트도 기본적인 스모크 테스트뿐인 것 같고, 크고 심각한 보안 문제가 몇 가지 있습니다.
_generate_seccomp_filter는 줄바꿈으로 구분된 syscall을 여러 줄짜리 차단 목록과 비교하기 때문에, 이 함수 전체가 아무것도 막지 못하는 사실상 no-op입니다.메인 스크립트가 파일 시스템 제한과 capability 제거를 하기 전에, 작업 디렉터리의 .env를 셸코드처럼 실행합니다. 공격자가 조작한 .env가 전체 권한으로 셸코드를 실행할 수 있습니다.
경쟁 상태(race condition)도 많은데, 직접 확인하지는 않았고 사실 별로 중요하지도 않습니다.
제가 PR을 올리고 싶지만, 애초에 최소 SLOC를 목표로 bash로 샌드박싱 시스템을 직접 만드는 게 좋은 생각 같지 않습니다. 그리고 HN에서 하신 댓글 대부분이 이 저장소 홍보인 것 같아서 조금 걱정되기도 합니다.