본문으로 건너뛰기
5분 AI.
TRENDSHIFT DAILY #14 딥다이브 · 2026-10-23 분석

OpenShell 딥다이브
— AI에게 일을 맡기되, 권한은 경계 안에

샌드박스 런타임

빠른 판단

무엇
에이전트를 샌드박스에서 실행하고 파일·네트워크·자격증명 접근을 정책으로 제한하는 Rust 런타임
이럴 때
에이전트에 명령 실행과 외부 API 사용을 맡기면서 허용 범위와 비밀키 전달을 실행 계층에서 통제할 때
AI가 파일을 고치고 API를 호출하기 시작하면, 좋은 프롬프트만큼 실행 환경의 설계가 중요해집니다. NVIDIA/OpenShell은 에이전트를 격리하고 파일·네트워크·자격증명 사용을 정책으로 통제하는 런타임입니다. Rust 38개 crate, 여러 언어의 SDK, Linux 보안 기능과 Kubernetes 배포를 연결하면서 “신뢰할 수 없는 프로그램을 어떻게 실행시킬 것인가”를 배울 수 있습니다. 구현 설명은 커밋 9a85667 기준입니다. 스타 18,034 · 포크 1,843 · Apache-2.0 · 2026-10-23 GitHub 기준.
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

에이전트의 지능보다, 에이전트가 행사할 권한을 관리한다

OpenShell은 자율 AI 에이전트를 위한 정책 기반 실행 환경입니다. 에이전트 프로그램을 샌드박스 안에서 실행하고, 허용된 파일과 외부 서비스만 사용하도록 경계를 세웁니다. 모델을 학습시키는 라이브러리나 대화를 만드는 프레임워크와는 역할이 다릅니다.

이 저장소의 핵심은 에이전트가 잘 판단한다고 가정하지 않고, 실행 환경이 권한을 제한하도록 만드는 것입니다. 에이전트가 실수하거나 외부 문서의 악성 지시를 따라도, 그 행동이 통과해야 하는 별도의 통제 지점을 둡니다.

용어 이해
런타임과 샌드박스
런타임은 프로그램을 실제로 실행하고 관리하는 환경입니다. 샌드박스는 그 안에서 프로그램이 만질 수 있는 자원을 제한하는 구역입니다. OpenShell에서는 openshell-sandbox라는 실행 파일도 있으므로, 제품 전체의 “샌드박스”와 작업 프로세스를 관리하는 이 구성 요소를 구분해야 합니다.
한 문장 비유

인턴에게 회사 일을 맡기되, 출입증과 법인카드는 관리실이 통제합니다

에이전트는 일을 하는 인턴, 정책은 출입 가능한 방과 구매 가능한 품목의 목록입니다. sandbox는 작업실에서 누가 무엇을 요청했는지 전달하고, supervisor는 작업실 밖에서 허용 여부를 판단합니다.

실제 서비스 키는 관리실이 보관합니다. 인턴은 대리 표식을 사용해 요청하고, 허용된 목적지로 보낼 때만 관리실이 실제 키를 붙입니다. 비유의 핵심은 “인턴에게 조심하라고 말하기”보다 출입과 결제 절차를 설계하기에 있습니다.

1-1. 세 구성 요소만 먼저 기억하기

구성 요소책임첫 번째 읽을 소스
gateway사용자 인증, 샌드박스 생성·상태, 정책·provider 전달crates/openshell-server/src/lib.rs
supervisor신뢰 영역에서 정책 평가, 외부 연결, 자격증명 처리crates/openshell-supervisor/src/lib.rs
sandbox작업 프로세스 실행·식별, 커널 통제 적용, TCP·DNS 중계crates/openshell-sandbox/src/boundary_server.rs

사용자는 CLI나 SDK로 gateway에 요청합니다. compute driver가 실행 자원을 준비하고, supervisor가 경계를 확인한 뒤 에이전트를 시작합니다. 모델 API를 이용한다면 승인된 요청은 외부 모델 서비스까지 나갑니다. 제품 설명의 “private”를 모든 추론과 데이터가 자동으로 내 컴퓨터에만 남는다는 뜻으로 읽으면 안 됩니다.

학습 목표
한 번의 API 요청에서 운영체제와 분산 시스템까지 연결하기

이 글을 끝낸 뒤에는 “이 요청을 누가 식별하고, 누가 허용하며, 누가 실제 연결을 여는가”를 파일 경로와 함께 설명할 수 있는 것을 목표로 합니다. Rust 코드 약 65만 줄을 순서대로 읽을 필요는 없습니다.

2왜 주목받는가

트렌딩 선정 사실과, 소스에서 읽어낼 수 있는 관심 요인을 구분한다

선정 근거는 TrendShift Daily #14이며 분석일은 2026-10-23입니다. 2026-10-23 GitHub 기준 스타 18,034개, 포크 1,843개입니다. 이 숫자는 관심의 규모를 보여주지만, 하루 증가량이나 채택 기업 수, 실제 운영 안정성을 뜻하지는 않습니다.

2-1. 주목할 만한 세 가지 변화

  1. 도구 호출이 실제 권한 문제가 됐습니다. 파일 수정과 네트워크 호출을 하는 에이전트에는 파일 경계·목적지 제한·비밀키 관리가 함께 필요합니다. OpenShell은 이들을 하나의 제품 흐름에 연결합니다.
  2. 거절 다음 단계까지 설계합니다. 정책 advisor가 필요한 접근을 제안하고, prover가 기존 정책 대비 새 위험을 검사하는 경로가 있습니다. 단순한 허용 목록을 사람이 처음부터 완벽히 작성해야 하는 부담을 줄이려는 접근입니다.
  3. 로컬과 클러스터를 같은 계약으로 묶습니다. Docker·Podman·Kubernetes·VM 드라이버가 있고, HEAD는 Kubernetes의 공유 supervisor 배치를 추가합니다. 보안 경계와 자원 배치를 나누는 사례입니다.

위 항목은 README와 실제 구현을 바탕으로 한 관심 요인에 대한 해석입니다. 트렌딩 순위만으로 특정 발표나 기능이 관심 증가의 원인이라고 단정할 수는 없습니다. 2026-10-23 GitHub 기준 최신 릴리스는 v0.1.5(2026-10-20)이며, 분석 소스는 그 뒤의 개발 커밋입니다.

2-2. 경쟁·대체 접근과 비교하면 무엇이 다른가

접근중심 역할OpenShell에서 배울 차별점
일반 Docker 구성컨테이너 실행과 자원·네트워크 배치여기에 에이전트별 정책, 실행 파일 식별, 목적지별 자격증명 중계를 제품 기능으로 결합합니다.
gVisor사용자 공간의 application kernel과 OCI 런타임 runsc로 호스트를 격리OpenShell의 중심은 에이전트 권한·provider·정책 변경 절차입니다. 커널 대체 구조의 우열 비교와는 질문이 다릅니다.
FirecrackerKVM 기반 microVM을 만드는 VMM과 제어 APIOpenShell은 정책·SDK·운영 제어를 묶습니다. 이 커밋의 VM 드라이버는 libkrun 기반이며 Firecracker 기반이라고 쓰면 틀립니다.
OpenShell실행 격리와 에이전트 행동 통제를 연결하는 런타임격리 구역 안에 비밀키를 직접 주지 않는 구조, L7 검사, 정책 제안 검증을 함께 추적할 수 있습니다.

gVisor와 Firecracker의 역할 설명은 각각 gVisor 공식 개요와 Firecracker 공식 문서를 확인했습니다. 이 표는 역할과 구현 범위 비교이며 처리량·부팅 시간·격리 강도의 실측 순위가 아닙니다. Docker 관련 비교는 이 저장소의 Docker 드라이버가 추가하는 통제 기능을 기준으로 했습니다.

OpenShell의 장점은 격리 기술 하나의 발명보다, 실행 경계·권한 정책·자격증명·운영 API를 연결한 설계에 있습니다.

README를 읽을 때의 주의점
“형식 검증”은 제품 전체의 무결점 증명이 아닙니다

README는 커널 통제와 형식 검증을 강조합니다. 실제로는 파일 접근은 Landlock, 특정 시스템 호출은 seccomp, 네트워크 의미는 supervisor에서 나누어 다룹니다. prover도 모델에 포함된 정책 의미만 검사합니다. 이 구분은 4장에서 소스 함수로 확인합니다.

3기술 스택 전체 지도

버전 선언, 잠금 파일, 개발 도구 버전을 따로 읽는다

루트 Cargo.toml은 members = ["crates/*"]인 Rust workspace입니다. edition은 2024, 최소 Rust 버전 선언은 1.94입니다. 반면 rust-toolchain.toml과 mise.toml이 선택한 개발 도구는 1.95.0입니다. 최소 지원 버전과 팀이 사용하는 컴파일러는 서로 다른 정보입니다.

용어 이해
manifest와 lockfile
Cargo.toml은 허용하는 의존성 범위를 선언하고, Cargo.lock은 이 체크아웃이 해석한 구체적 버전을 기록합니다. 예를 들어 tokio = "1.43"은 정확히 1.43만 사용한다는 뜻이 아닙니다. 아래 표는 선언과 실제 잠금 버전을 함께 적었습니다.

3-1. 백엔드: 비동기 통신과 정책 엔진

기술선언 → 잠금 버전실제 쓰임새
Tokio1.43 → 1.52.1비동기 작업, 소켓, 채널과 상태 변경 알림
Tonic / Prost0.14 / 0.14 → 0.14.6 / 0.14.3gRPC 서비스와 Protocol Buffers 메시지
Axum0.8 → 0.8.9HTTP·WebSocket 서버 구성; 사용자용 SPA가 있다는 뜻은 아닙니다.
Rustls0.23 → 0.23.46TLS 연결. 암호 연산은 openshell-crypto가 AWS-LC 구현을 감쌉니다.
Regorus0.9 → 0.9.1supervisor 안에서 Rego 정책 평가; 별도 OPA 서버가 필수인 구조가 아닙니다.
Z3 바인딩0.21 → 0.21.0정책 위험·포함 관계 검사. 이 번호는 Rust crate 버전입니다.
SQLx0.9 → 0.9.0SQLite·PostgreSQL 저장소와 마이그레이션
Kube0.99 → 0.99.0Kubernetes API 클라이언트·리소스 감시
Landlock 바인딩잠금 0.4.4Linux 파일시스템 제한. crate 버전과 커널 ABI 버전은 별개입니다.

공통 버전의 근거는 Cargo.toml과 Cargo.lock입니다. Regorus 선언은 crates/openshell-supervisor-network/Cargo.toml에 있습니다. 공통 설정에는 k8s-openapi = "0.24"의 v1_29 기능과 opentelemetry = "0.32", metrics = "0.24"도 포함됩니다.

3-2. 프론트엔드·클라이언트: 브라우저 화면보다 터미널과 SDK

주요 사용자 접점은 CLI와 TUI입니다. CLI에는 clap = "4.5", TUI에는 ratatui = "0.30.2"와 crossterm = "0.28"을 선언합니다. crates/openshell-tui/src/lib.rs의 run()은 터미널 raw mode와 alternate screen을 열고 gRPC 클라이언트를 화면 상태에 연결합니다.

클라이언트실제 의존성·버전읽는 관점
Python SDKPython >=3.11, grpcio>=1.60, httpx>=0.27, protobuf>=4.25, cloudpickle>=3.0pyproject.toml의 하한 조건입니다. 이 표는 설치된 버전을 뜻하지 않습니다.
TypeScript SDKNode >=20.3, @bufbuild/protobuf ^2.2.3, Connect·connect-node ^2.0.0sdk/typescript/package.json. TypeScript ^6.0.3, Vitest ^4.1.11은 개발 의존성입니다.
Go SDKgo 1.25.13, gRPC v1.83.2, protobuf v1.36.11sdk/go/go.mod. 도메인 자료형과 wire 변환 경계를 살펴봅니다.
Rust SDKcrates/openshell-sdk, workspace 공통 통신 의존성CLI 등에서 공유하는 비동기 gateway 클라이언트입니다.

sdk/typescript/src/client.ts는 생성된 protobuf 타입 위에 SandboxClient 같은 사용하기 쉬운 API를 얹습니다. sdk/typescript/src/transport.ts는 연결·인증, sdk/typescript/src/errors.ts는 오류 분류를 맡습니다. ./raw export는 저수준 접근을 위한 별도 진입점입니다.

fern/와 docs/의 TSX·MDX는 문서 사이트 구성입니다. fern/docs.yml에는 테마·메뉴·문서 버전 설정이 있습니다. TypeScript와 TSX가 보인다는 이유만으로 React 기반 제품 대시보드가 있다고 소개해서는 안 됩니다.

3-3. 인프라·빌드: 실행 파일을 먼저 만들고 이미지에 넣기

gateway·supervisor Dockerfile의 기본 베이스 이미지에는 digest가 고정되어 있습니다. deploy/helm/openshell/Chart.yaml의 version과 appVersion은 0.0.0이며 주석상 CI가 릴리스 버전으로 바꿉니다. Rust workspace·TypeScript 패키지의 0.0.0도 2026-10-23 GitHub 기준 최신 릴리스 v0.1.5와 혼동하지 않아야 합니다.

3-4. CI에서 보는 제품의 품질 기준

.github/workflows/branch-checks.yml은 protobuf 호환성 검사, cargo fmt, cargo clippy --locked --workspace --all-targets -- -D warnings, cargo nextest, PostgreSQL 테스트, Python·Go·TypeScript 검사를 나눕니다. --locked는 CI에서 의존성 해석이 예기치 않게 바뀌지 않도록 합니다. 검사 항목의 정의와 개별 CI 실행의 성공 여부는 별개입니다.

기술 스택을 읽을 때는 언어 이름보다, 각 의존성이 어느 신뢰 경계와 사용자 접점을 담당하는지 연결하는 것이 중요합니다.

4아키텍처 심화 분석

구조도에서 경계를 찾고, 함수에서 실패 동작을 확인한다

4-1. 전체 흐름: 관리 요청과 실제 작업 트래픽

아래 그림의 위쪽은 관리 흐름, 아래쪽은 에이전트의 작업 흐름입니다. gateway가 정책을 관리한다고 해서 모든 외부 API 트래픽을 gateway가 직접 프록시한다는 뜻은 아닙니다. 허용된 upstream 연결을 여는 책임은 supervisor에 있습니다.

[사용자 CLI / TUI / Python·Go·TypeScript·Rust SDK] | | 인증된 관리 API / gRPC v +---------------------------------------------------------+ | gateway: 인증 · 정책 버전 · provider · 생명주기 · 저장소 | | openshell-server SQLite 또는 PostgreSQL | +---------------------------------------------------------+ | compute driver ^ | 자원 배치·경계 구성 | 세션·설정·로그 v | [Docker / Podman / Kubernetes / libkrun VM] | | | | 신뢰 영역 | | +---------------------------------------------+ | | supervisor: 정책 평가 · DNS · 실제 자격증명 | | | 허용 시 upstream 연결 생성 | | +---------------------------------------------+ | ^ | | | 인증된 HTTP/2 채널 v | | [승인된 외부 API] | 격리 경계 안 | +---------------------------------------------+ +-->| openshell-sandbox: 프로세스·식별·I/O 중계 | | ^ Landlock / seccomp user notification | | | | | [에이전트와 자식 프로세스] | +---------------------------------------------+ 직접 외부 통신은 driver의 바깥 울타리가 차단

Docker·Podman은 driver 소유 볼륨의 Unix socket, Kubernetes는 사설 TCP 경로와 mTLS, VM은 vsock를 사용합니다. 논리적으로 같은 Sandbox Protocol을 서로 다른 전송 방식을 사용하는 구조입니다. HTTP/2의 독립 스트림은 하나의 느린 전송 때문에 DNS나 프로세스 제어까지 대기하는 일을 줄이도록 설계되어 있습니다. 이는 docs/about/architecture.mdx가 설명하는 계약이며 성능 수치를 측정한 결과는 아닙니다.

4-2. 패턴 ① 권한 분리와 교체 가능한 실행 백엔드

핵심 질문: 신뢰할 수 없는 프로그램과 비밀키·정책 결정을 같은 곳에 둘 필요가 있을까요? 이 설계는 sandbox를 작업 경계 안에 두고 supervisor를 그 밖에 둡니다. sandbox는 요청 주체를 관찰하고 전달하지만 외부 서비스 접근을 최종 승인하지 않습니다.

crates/openshell-server/src/compute/mod.rs의 SharedComputeDriver는 다음처럼 공통 계약 뒤에 실제 드라이버를 감춥니다.

// 원본의 타입 별칭. 여러 구현을 공통 인터페이스로 다룹니다.
pub type SharedComputeDriver =
    Arc<dyn ComputeDriver<WatchSandboxesStream = DriverWatchStream> + Send + Sync>;

Arc는 여러 비동기 작업이 드라이버를 공동 소유하게 하고, dyn ComputeDriver는 Docker인지 Kubernetes인지 몰라도 같은 API를 호출하게 합니다. Send + Sync는 스레드를 넘나들며 사용할 수 있는 자료형인지 컴파일러가 확인할 조건입니다. 초보자는 우선 “공통 리모컨에 여러 제조사의 장치를 연결한다”는 정도로 이해해도 됩니다.

드라이버의 책임은 추상화만으로 끝나지 않습니다. Docker의 crates/openshell-driver-docker/src/lib.rs에는 validate_docker_outer_fence()가 있고 workload 생성 설정에 network_mode: Some("none".to_string())을 넣습니다. crates/openshell-driver-docker/src/isolation.rs의 DockerOuterFenceEvidence::project()는 컨테이너 ID, 네트워크 모드, 예상 밖 네트워크를 확인해 세대에 묶인 경계 증거를 만듭니다.

설계 비유

관리실의 승인 규칙은 같아도 작업실 문은 컨테이너, Pod, VM마다 다릅니다. driver는 각 건물에 맞는 문과 통로를 만들고, supervisor는 그 통로를 건너온 요청에 같은 규칙을 적용합니다. 인터페이스의 목적은 차이를 없애는 것이 아니라 차이를 책임질 위치를 정하는 것입니다.

4-3. 패턴 ② 커널 중개와 실패 시 차단

핵심 질문: 에이전트가 프록시 환경변수를 무시하고 직접 소켓을 열면 어떻게 될까요? Linux 구현은 자식에게 상속되는 seccomp 필터와 driver의 네트워크 울타리를 결합합니다. 프록시를 잘 사용해 주리라는 약속에만 기대지 않습니다.

  1. crates/openshell-sandbox/src/linux/workload_launcher.rs의 start()가 전용 launch 스레드를 만들고 install_workload_listener()를 설치합니다. 작업 큐는 sync_channel(64)입니다.
  2. WorkloadLauncher::execute()로 fork/exec 작업을 그 스레드에 모읍니다. 자식은 필터를 상속하지만 sandbox의 중개·생명주기 스레드는 같은 필터에 묶이지 않습니다.
  3. crates/openshell-sandbox/src/linux/seccomp_notify.rs의 install_workload_listener()가 socket, connect, setsockopt 등 정해진 호출을 다룹니다. crates/openshell-sandbox/src/network_broker.rs의 dispatch_notification(), connect_socket()을 따라가면 중개 경로가 보입니다.
  4. probe_notification_api()는 실제 user notification 왕복과 SECCOMP_ADDFD_FLAG_SEND 동작을 검사합니다. 커널 버전 문자열만 보고 필요한 기능이 있다고 가정하지 않습니다.

파일 경계는 crates/openshell-sandbox/src/sandbox/linux/landlock.rs에서 봅니다. require_abi()는 최소 ABI 3을 요구하고, prepare_capability_free_baseline()은 비공개 /.openshell 계층을 제외하는 필수 기본 규칙을 만듭니다.

// 필수 기본 규칙 생성 과정에서 발췌
require_abi()?;
let abi = ABI::V3;
let access = AccessFs::from_all(abi);
let mut ruleset = Ruleset::default()
    .set_compatibility(CompatLevel::HardRequirement)
    .handle_access(access)

위 코드는 이어지는 규칙 생성 중 앞부분입니다. ?는 오류가 나면 호출자에게 전파한다는 Rust 문법입니다. “기능이 없으면 조용히 제한을 생략”하는 방향으로 흐르지 않도록 합니다. 선택적 파일 정책의 best_effort 설정도 이 필수 기본 경계를 해제하지 않습니다.

용어 이해
실패 시 차단 (fail closed)
검사를 수행할 수 없거나 제어 연결을 잃으면 진행을 허용하지 않는 설계입니다. crates/openshell-sandbox/src/boundary_server.rs에는 연결 종료 처리에서 작업을 freeze()하는 경로도 있습니다. 기능 정상 동작 때뿐 아니라 인증 실패·채널 단절·지원 기능 부재 때의 행동을 함께 읽어야 합니다.

4-4. 패턴 ③ 요청별 승인과 자격증명 결합

핵심 질문: 인터넷 접속을 허용했다는 이유만으로 그곳에 API 키도 보낼 수 있어야 할까요? 소스는 네트워크 허용과 자격증명의 목적지 결합을 나누어 검사합니다.

crates/openshell-supervisor-network/src/opa.rs의 authorize_egress()는 현재 정책 세대와 함께 egress_authorization을 평가합니다. crates/openshell-supervisor-network/data/sandbox-policy.rego는 기본값을 default allow_network = false로 둡니다. 허용 규칙에는 endpoint와 binary 조건이 함께 등장합니다.

# 네트워크 정책의 핵심 규칙 발췌
network_policy_for_request if {
    some name
    data.network_policies[name]
    endpoint_allowed(data.network_policies[name], input.network)
    binary_allowed(data.network_policies[name], input.exec)
}

여기서 binary는 에이전트가 말로 신고한 이름이 아닙니다. crates/openshell-binary-identity/src/lib.rs의 ProcfsIdentityResolver가 신뢰할 수 있는 procfs 관찰을 공유합니다. 심볼릭 링크로 실행한 Python의 실제 경로가 정책에 적은 경로와 달라 거절될 수 있다는 점도 Rego의 거절 진단문에 명시되어 있습니다.

crates/openshell-supervisor-network/src/l7/relay.rs의 scoped_context_for_request()는 resolver_and_body_classifier_for_endpoint()로 host·port·path에 맞는 resolver를 고릅니다. 요청 authority가 없을 때는 static credential resolver를 지우는 분기도 있습니다. prepare_inspected_request()는 동적 grant를 다루고, 대기 중 정책·credential 세대가 바뀌었는지도 확인합니다.

에이전트 환경: 실제 API 키 대신 대리 표식 | v 연결 목적지 + 실행 파일 승인 | v L7 설정이 있으면 메서드·경로·프로토콜 검사 | v 자격증명 binding의 host·port·path 확인 | v 전달 직전 실제 자격증명 해석·주입 --> upstream 어느 단계든 조건 불충족 --> 거절 또는 오류 반환

L7 검사는 설정한 프로토콜과 강제 모드의 범위에서 적용됩니다. 단순 L4 TCP 허용은 “그 연결 안의 모든 API 동작이 안전하다”는 뜻이 아닙니다. TLS 내용을 검사하는 경로에서는 supervisor가 TLS를 종단하고 검사하므로, 클라이언트의 인증서 신뢰 설정과 프로토콜 호환성도 운영 고려 사항이 됩니다.

4-5. 패턴 ④ 버전이 있는 상태 변경과 제한된 정책 증명

핵심 질문: 내가 검토한 상태와 실제 적용할 상태가 그사이 달라지면 어떻게 할까요? 최신 Kubernetes 변경과 정책 제안 처리에서 이 문제를 서로 다른 수준으로 다룹니다.

crates/openshell-driver-kubernetes/src/shared_supervisor.rs의 supervisor_placement()는 시작 세대에 기록된 annotation을 읽습니다. 기록이 없으면 Dedicated, gateway와 유효한 route가 있으면 Shared { route }를 반환합니다. 모르는 값이나 불완전한 기록은 오류입니다. 전역 설정을 바꿨다고 기존 세대의 배치를 다르게 해석하지 않게 합니다.

crates/openshell-supervisor-control/src/controller.rs의 replace_assignments()는 목록을 읽었던 baseline과 현재 revision을 비교합니다.

// replace_assignments()의 초기화 이후 충돌 검사 발췌
if desired.initialized && desired.revision != baseline {
    return Err(AssignmentError::Conflict {
        baseline,
        current: desired.revision,
    });
}

그사이 누군가 배정을 바꿨다면 오래된 전체 목록으로 덮어쓰지 않습니다. 같은 파일의 MAX_ASSIGNED_INSTANCES = 256은 공유 host의 구현상 상한입니다. 이는 장비당 권장 동시 실행 수나 성능 보장이 아닙니다.

정책 쪽은 crates/openshell-server/src/grpc/policy.rs의 evaluate_proposal_candidate(), proposal_prover_result(), run_prover_findings()를 읽습니다. 현재 유효 정책과 후보 정책에서 각각 발견 항목을 구한 뒤 finding_delta()로 새 위험을 가려냅니다.

crates/openshell-prover/src/containment.rs의 check_within_boundary()는 별도의 질문, 즉 후보 정책이 상위 경계를 넘는지 검사합니다. 네트워크에서는 개념적으로 후보가 허용함 ∧ 경계가 거절함인 행동을 찾습니다. 그런 반례가 있으면 포함 관계가 깨집니다. 지원하지 않는 형태와 시간 초과도 결과로 구분합니다.

보안 설계는 정상 요청의 허용 조건뿐 아니라, 오래된 상태·모르는 입력·검사 불능을 처리하는 방식에서 드러납니다.

두 검사를 구분하기
“새 위험 없음”과 “상위 경계 안에 있음”은 같은 판정이 아닙니다

제안 위험 검사는 기존 정책과 비교하고, boundary 검사는 별도로 작성한 최대 허용 정책과 비교합니다. 한쪽을 통과해도 다른 쪽을 통과한다는 뜻이 아닙니다. boundary 모델은 파일·프로세스·Landlock·L4 TCP·REST 등을 다루며 GraphQL·MCP 규칙은 현재 지원 범위 밖으로 보고합니다. 모델 통과가 커널·프록시·외부 API의 모든 버그 부재를 증명하지는 않습니다.

5디렉토리 구조 해부

폴더를 기능 목록 대신, 책임과 읽기 순서로 정리하기

아래는 저장소 루트 기준의 축약 트리입니다. crates/는 제품 구현, proto/는 통신 계약을 담으며, 다른 폴더는 클라이언트·배포·검증을 지원합니다.

OpenShell/ ├── Cargo.toml / Cargo.lock Rust workspace·의존성 ├── rust-toolchain.toml 컴파일러 선택 ├── mise.toml / tasks/ 도구 버전·개발 작업 ├── crates/ 38개 Rust crate │ ├── openshell-cli/ 명령 해석과 사용자 흐름 │ ├── openshell-tui/ 터미널 화면 │ ├── openshell-sdk/ 공통 Rust 클라이언트 │ ├── openshell-gateway/ 서버와 선택한 driver 조립 │ ├── openshell-server/ API·인증·저장소·생명주기 │ ├── openshell-supervisor/ 신뢰 영역의 런타임 │ ├── openshell-supervisor-control/ 공유 host 배정·복구 │ ├── openshell-supervisor-network/ Rego·프록시·L7 │ ├── openshell-supervisor-process/ 프로세스 감시 │ ├── openshell-supervisor-middleware/ 처리 체인 │ ├── openshell-sandbox/ 작업 실행·커널 중개 │ ├── openshell-sandbox-backend/ RPC·인증된 채널 │ ├── openshell-isolation-interface/ 공통 격리 계약 │ ├── openshell-binary-identity/ 실행 파일 식별 │ ├── openshell-policy-schema/ YAML 표현·순수 검증 │ ├── openshell-policy/ 정책 변환·병합·조합 │ ├── openshell-prover/ 정책 모델·증명 질의 │ ├── openshell-driver-*/ 실행·자격증명 저장 backend │ └── openshell-crypto/ · openshell-ocsf/ · openshell-otel/ ├── proto/ 서비스·자료형 계약 ├── python/openshell/ Python SDK ├── sdk/go/ · sdk/typescript/ 언어별 SDK ├── providers/ provider 프로필 ├── deploy/ 이미지·Helm·배포 자료 ├── tests/ · e2e/ 테스트 지원·통합 시나리오 ├── examples/ 확장·정책·연동 예제 ├── docs/ · fern/ 문서 내용과 사이트 구성 ├── rfc/ 설계 제안과 배경 ├── skills/ 사용자용 에이전트 스킬 └── .github/workflows/ 검사·패키징·릴리스

5-1. 비슷한 이름의 폴더가 나뉜 이유

구분분리한 책임학습할 점
gateway / server바이너리 조립과 서버 로직배포별 기능 선택을 핵심 서버 코드와 분리합니다.
policy-schema / policy작성 언어의 순수 의미와 런타임·protobuf 연결파서·검증기를 무거운 실행 환경 없이 재사용하게 합니다.
sandbox / supervisor작업 안쪽의 중개와 바깥쪽의 결정·비밀 관리폴더 경계가 신뢰 경계를 반영합니다.
proto / SDK전송 계약과 언어 사용자를 위한 편의 API모든 생성 타입을 그대로 사용자가 다루게 하지 않습니다.
tests / e2e지원 라이브러리·계약 시나리오와 실제 환경 통합순수 함수 테스트와 런타임 환경 검증을 나눕니다.

예를 들어 crates/openshell-policy-schema/src/yaml.rs는 DuplicateKeyPolicy::Error를 지정하고 객체 위치의 null을 검사합니다. 이런 규칙은 CLI·서버·prover가 제각각 YAML을 해석하는 문제를 줄입니다. “설정 파일도 외부 입력”이라는 관점을 배우기 좋은 진입점입니다.

5-2. 처음 읽을 때의 추천 경로

  1. docs/about/architecture.mdx로 구성 요소 이름과 신뢰 경계를 익힙니다.
  2. proto/sandbox.proto와 crates/openshell-policy-schema/src/lib.rs로 데이터 모양을 봅니다.
  3. crates/openshell-supervisor-network/src/opa.rs와 crates/openshell-supervisor-network/data/sandbox-policy.rego에서 허용 판단을 찾습니다.
  4. crates/openshell-sandbox/src/linux/workload_launcher.rs와 crates/openshell-sandbox/src/network_broker.rs로 요청이 중개되는 이유를 확인합니다.
  5. crates/openshell-server/src/grpc/policy.rs와 crates/openshell-supervisor-control/src/controller.rs에서 변경·충돌 처리를 읽습니다.

제품 구현 파일은 crates/ 아래에 있으며, 경로는 모두 저장소 루트 기준입니다. 파일이 크면 처음부터 끝까지 읽기보다 함수명 검색 → 호출자 → 관련 테스트 순으로 이동하세요. 테스트는 함수가 약속하는 실패 조건을 설명하는 또 하나의 문서입니다.

6학습 포인트 (기술별)

한 저장소에서 서로 다른 기술의 역할을 연결해 보는 여섯 가지 관찰

6-1. Rust: 소유권을 “누가 책임지는가”로 읽기

Arc는 공유 소유, Mutex는 동시 변경 제한, Result는 실패를 반환값으로 드러내는 장치입니다. crates/openshell-supervisor-control/src/controller.rs에서 이 세 요소가 배정 목록을 지키는 방식을 보세요. 문법을 외우기 전에 “어떤 상태를 누가 바꿀 수 있나”를 메모하면 구조가 보입니다.

실습 아이디어: assign()와 unassign()에서 잠금 획득, 상태 변경, revision 증가, watch 알림을 서로 다른 색으로 표시해 보세요. 동일한 값의 재배정과 실제 변경이 어떻게 구분되는지 설명하면 됩니다.

6-2. 비동기·동시성: 채널은 작업 큐와 상태 알림이 다르다

WorkloadLauncher의 sync_channel은 실행할 작업을 전달합니다. controller의 Tokio watch는 revision 같은 최신 상태 변경을 알립니다. 같은 “채널”이어도 모든 작업을 처리할 큐와 최신 상태를 따라잡을 알림은 요구사항이 다릅니다.

용어 이해
역압력 (backpressure)
받는 쪽이 처리할 수 없을 때 보내는 쪽도 무한히 밀어 넣지 못하게 하는 제어입니다. 유한 큐·동시 처리 제한·스트림 흐름 제어가 대표적인 수단입니다. 큐 크기 64와 host 배정 상한 256은 서로 다른 자원을 제한하므로 합쳐서 해석하면 안 됩니다.

실습 아이디어: 네트워크가 느려진 상황에서 작업 큐, HTTP/2 스트림, host 상태 알림이 각각 어떤 자원을 보호하는지 표로 적어 보세요. 제한값을 키우기 전에 메모리·파일 디스크립터·대기 시간 중 무엇이 증가하는지 생각합니다.

6-3. gRPC·SDK: 전송 자료형과 사용자 API를 나누기

proto/sandbox.proto는 SandboxPolicy에 filesystem, process, network 정책을 넣는 계약을 정의합니다. 필드 번호는 wire 호환성의 일부입니다. 이름이 같아 보여도 번호를 임의 재사용하면 이전 데이터 해석이 달라질 수 있습니다.

// proto/sandbox.proto의 SandboxPolicy 필드 발췌
uint32 version = 1;
FilesystemPolicy filesystem = 2;
LandlockPolicy landlock = 3;
ProcessPolicy process = 4;
map<string, NetworkPolicyRule> network_policies = 5;

실습 아이디어: TypeScript의 durationFromSeconds()가 음수·무한대 입력을 왜 거절하는지 살펴보고, SDK의 친숙한 초 단위 값이 protobuf duration으로 바뀌는 과정을 적어 보세요. 자동 생성 코드와 사용성 개선 코드를 나누는 이유를 배울 수 있습니다.

6-4. 정책 언어: 설정도 작은 프로그래밍 언어다

아래는 공식 네트워크 정책 튜토리얼의 규칙에 버전·파일 영역을 붙인 학습용 예시입니다. 정책 구조를 설명하는 예시이며, 실제 실행에는 적절한 workload 이미지와 실행 환경이 필요합니다.

version: 1
filesystem_policy:
  include_workdir: true
  read_only: [/usr, /etc]
  read_write: [/tmp]
network_policies:
  github_api:
    endpoints:
      - host: api.github.com
        port: 443
        protocol: rest
        enforcement: enforce
        access: read-only
    binaries:
      - path: /usr/bin/curl

read-only는 이 REST 설정에서 GET, HEAD, OPTIONS를 허용하는 접근 프리셋입니다. 애플리케이션이 GET에 부작용을 구현했다면 그 의미까지 바꿔 주지는 않습니다. 실습 아이디어: host·binary·메서드 중 하나만 바꾼 요청을 만들고 어떤 검사에서 거절할지 적으세요.

6-5. 운영체제 보안: 다층 통제의 담당 범위

Landlock은 파일 접근, seccomp는 지정 시스템 호출의 통제·중개, 바깥 네트워크 울타리는 직접 유출 경로, supervisor는 목적지와 요청 의미를 다룹니다. crates/openshell-sandbox/src/linux/socket_confinement.rs의 confine_to_loopback()과 probe_loopback_confinement()도 함께 읽어 보세요.

실습 아이디어: “파일 읽기”, “DNS 질의”, “TCP 연결”, “허용 API에 POST”라는 네 행동을 어느 구성 요소가 관찰·차단하는지 배치하세요. 모든 통제를 막연히 Docker 한 단어로 묶지 않는 연습입니다.

6-6. 관측성·증명: 판단을 설명 가능한 자료로 남기기

openshell-ocsf는 보안 사건을 구조화하고, openshell-otel은 서비스 경계의 trace를 연결합니다. crates/openshell-server/src/compute/mod.rs의 TracedDriver::call()은 드라이버 호출을 span에 넣고 gRPC 결과를 기록합니다. 보안 거절과 내부 연결 오류를 다른 종류의 사건으로 볼 수 있습니다.

실습 아이디어: 같은 실패를 사용자 메시지, 운영 trace, 보안 이벤트로 각각 표현해 보세요. 운영자가 원인을 찾는 데 필요한 필드와 비밀값이 섞이면 안 되는 필드를 나누는 것이 목표입니다.

배울 것은 라이브러리 목록이 아니라, 권한·동시성·오류·관측성을 하나의 요청 흐름에 묶는 방법입니다.

7하드웨어 / 시스템 요구사항

소스 읽기, 제품 실행, 전체 개발 환경의 요구량을 분리한다

요구사항의 1차 근거는 이 커밋의 docs/about/support-matrix.mdx입니다. 코드만 읽는 학습에는 Docker·Kubernetes·GPU가 필요하지 않습니다. 실행을 준비한다면 아래의 지원 조건과 선택한 드라이버를 먼저 확인해야 합니다.

항목문서·소스에서 확인한 조건초보자 해석
LinuxDebian/Ubuntu 계열 x86_64·aarch64 지원실제 workload 커널의 보안 기능 지원이 필요합니다.
macOSApple Silicon과 Docker Desktop 지원Landlock·seccomp는 macOS 커널이 아니라 내부 Linux VM에서 작동합니다.
Windowsx86_64 WSL 2 + Docker Desktop은 실험적Windows 전용 crate의 존재와 이 지원 상태를 혼동하지 않습니다.
컨테이너Docker 28.0 이상 또는 Podman 5.x선택한 driver의 API socket·네트워크 조건도 충족해야 합니다.
Kubernetes1.29 이상, Helm 3.x 이상, NetworkPolicy를 강제하는 CNINetworkPolicy YAML이 생성되는 것과 실제 차단되는 것은 다릅니다.
MicroVMLinux KVM 또는 macOS Hypervisor.framework가상화 사용 가능 여부와 중첩 가상화 환경을 확인합니다.
Linux gatewaystandalone GNU 바이너리는 glibc 2.28 이상정적 musl CLI·sandbox 바이너리와 요구 조건이 다릅니다.

7-1. 커널은 버전보다 기능 검사가 중요하다

배포판 backport와 보안 프로필 때문에 “Linux 6.2 이상” 한 줄만으로 지원 여부가 확정되지 않습니다. 소스의 probe는 실제 부모·자식 실행 형태에서 필요한 연산을 확인합니다. cap_drop: ALL과 no-new-privileges:true도 Docker workload 생성 코드에서 확인됩니다.

7-2. CPU·메모리·GPU는 어느 정도인가

목적학습 환경 제안근거·한계
소스 읽기일반 개발 노트북과 편집기코드를 읽고 정리하는 데 별도 런타임은 필요하지 않습니다.
단일 샌드박스 체험4코어·RAM 8GB 이상을 출발점으로 고려작성자의 여유 예산 제안이며 공식 최소 사양이나 실측값은 아닙니다.
전체 Rust 개발RAM 16~32GB와 빌드 캐시용 여유 디스크를 고려워크스페이스 규모를 고려한 제안입니다. 이미지·동시 빌드 수에 따라 달라집니다.
GPU필수 아님; GPU workload를 선택할 때 별도 준비일반 API 기반 에이전트 실행과 GPU 전달 기능을 구분합니다.

deploy/helm/openshell/values.yaml의 gateway 자원 기본값은 resources: {}입니다. 이것을 “메모리를 거의 안 쓴다”로 해석할 수는 없습니다. 에이전트 이미지, 빌드 작업, 브라우저, 동시 실행 수가 실제 자원 사용량을 좌우합니다.

시작 순서

첫 학습은 GPU와 클러스터 없이 정책·요청 경로를 읽는 것으로 충분합니다. 이후 독립된 실습 환경에서 지원 커널·단일 driver·버전이 맞는 CLI와 gateway를 준비하고 범위를 넓히세요.

8직접 해볼 수 있는 실습 과제

실행 없이도 설계 이해를 검증할 수 있는 다섯 가지 과제

아래 과제는 저장소 수정·설치·서비스 실행 없이 할 수 있는 소스 읽기 중심 실습입니다. 명령 예시는 저장소 루트에서 파일을 읽고 검색하는 용도입니다. YAML·요청 예시는 사고 실험이며, 외부 API로 보내지 않습니다.

과제 1

세 구성 요소의 책임 지도 만들기 입문 · 20분

목표: CLI, gateway, supervisor, sandbox를 연결하는 A4 한 장짜리 지도를 만듭니다.

진행: 아래 파일 목록에서 각 구성 요소의 진입점과 데이터 계약을 찾고, “정책 판단”, “실제 키”, “에이전트 자식”이 각각 어디에 있는지 표시하세요.

# 파일을 나열하고 문서와 함수 위치만 읽습니다.
rg --files crates/openshell-cli/src crates/openshell-server/src
rg --files crates/openshell-supervisor/src crates/openshell-sandbox/src
rg -n 'authorize_egress|prepare_inspected_request' crates/openshell-supervisor-network/src
rg -n 'message SandboxPolicy' proto/sandbox.proto

완료 기준: “gateway가 죽으면 관리 흐름에, supervisor 연결이 끊기면 작업 통제에 어떤 문제가 생기는가”를 구분해서 설명합니다. 복구 정책의 세부 시간값은 읽은 소스에서만 인용하세요.

과제 2

모호한 YAML 찾기 입문 · 30분

목표: 사람이 헷갈리는 설정을 왜 파서가 거절해야 하는지 이해합니다.

# 의도적으로 중복 키를 넣은 잘못된 학습용 입력
version: 1
network_policies: {}
network_policies:
  unexpected_rule:
    endpoints: []

진행: crates/openshell-policy-schema/src/yaml.rs의 from_str_with_object_paths()와 reject_null_objects()를 읽으세요. 중복 키와 filesystem_policy: null이 왜 다른 오류인지 설명합니다.

완료 기준: “마지막 키가 이긴다”는 관대한 해석이 보안 정책에서 만들 혼란을 적고, 입력 오류를 사용자가 고칠 수 있게 경로와 함께 알려주는 메시지를 한국어로 작성합니다.

과제 3

요청 승인 표를 손으로 평가하기 중급 · 45분

목표: 6장의 github_api 규칙만 있을 때 연결 승인과 L7 승인을 나눕니다. provider와 추가 허용 규칙은 없고 실행 파일 식별이 요구된다고 가정합니다.

요청예상 판정찾아야 할 근거
curl → api.github.com:443 GET정책상 허용 후보endpoint·binary 일치와 REST read-only. 실제 응답 성공은 별개입니다.
curl → api.github.com:443 POSTL7 거절연결 허용 후 메서드 검사
다른 binary → 같은 host연결 거절binary_allowed 조건
curl → 다른 host:443 GET연결 거절endpoint_allowed 조건

진행: crates/openshell-supervisor-network/data/sandbox-policy.rego와 crates/openshell-supervisor-network/src/l7/relay.rs에서 근거를 찾으세요. “다른 규칙도 추가된다면 결과가 같은가”를 추가 질문으로 남깁니다.

완료 기준: HTTP 403 하나만 보고 L4·L7·인증 중 어느 단계인지 단정할 수 없는 이유를 쓰고, 필요한 로그 필드를 목적지·binary·policy·reason으로 정리합니다.

과제 4

정책 경계와 반례 설명하기 중급 · 45분

목표: boundary와 candidate의 허용 집합을 비교합니다. 아래 두 문서는 서로 다른 학습용 파일이라고 가정하고 읽기만 합니다.

# boundary.yaml: 최대 허용 범위
version: 1
filesystem_policy:
  read_only: [/usr, /etc]

# candidate.yaml: 이 범위 안에 있는지 확인할 정책
version: 1
filesystem_policy:
  read_only: [/usr]
  read_write: [/tmp]

진행: docs/how-it-works/policies/prover.mdx의 boundary 예시와 crates/openshell-prover/src/containment.rs의 check_within_boundary()를 읽습니다. 후보가 허용하지만 boundary가 허용하지 않는 행동 하나를 찾으세요.

완료 기준: /tmp 쓰기를 반례로 설명하고, within_boundary, exceeds_boundary, unsupported, inconclusive를 한국어로 구분합니다. 확인 불능을 통과로 취급하지 않아야 합니다.

과제 5

공유 supervisor의 오래된 목록 덮어쓰기 막기 고급 · 60분

목표: HEAD 변경을 분산 상태 관리 문제로 이해합니다.

  1. A 작업이 revision 7에서 전체 목록을 읽기 시작합니다.
  2. B 작업이 새 sandbox를 배정해 revision이 8이 됩니다.
  3. A가 오래된 목록으로 replace_assignments(7, ...)를 호출합니다.
  4. 충돌 후 A가 어떤 정보를 다시 읽고 재시도해야 할지 적습니다.

진행: crates/openshell-supervisor-control/src/controller.rs의 full_resyncs_initialize_once_and_then_compare_and_replace()와 sessions_fence_stale_streams_epochs_and_acks() 테스트를 읽으세요. 첫 초기화 전 pending 변경과 초기화 후 revision 검사가 다른 이유도 찾습니다.

완료 기준: 재연결·오래된 ACK·용량 초과 중 두 경우를 골라 예상 결과와 지켜야 할 상태를 표로 씁니다. 테스트를 실행하지 않아도 assertion이 그 계약을 어떻게 표현하는지 설명할 수 있어야 합니다.

9관련 기술 심화 학습 로드맵

6주 동안 한 경계를 이해하고, 다음 경계로 확장한다

주당 3~5시간의 읽기와 정리를 가정한 제안입니다. Rust가 처음이면 1주차를 더 길게 잡아도 좋습니다. 매주 “내가 그린 설명이 어떤 소스와 연결되는가”를 남기는 것이 목표입니다.

주차배울 주제와 읽을 곳완료 산출물
1주차Rust의 소유권·Result·trait. crates/openshell-sandbox/src/linux/workload_launcher.rs의 자료형과 execute()공유하는 값, 이동하는 값, 실패 지점을 표시한 함수 해설
2주차Tokio와 채널·상태 버전. crates/openshell-supervisor-control/src/controller.rsrevision 충돌 타임라인과 재시도 절차
3주차gRPC·protobuf·SDK 경계. proto/sandbox.proto, sdk/typescript/src/client.tsYAML → 내부 타입 → protobuf → SDK 타입의 대응표
4주차Linux 권한·Landlock·seccomp. crates/openshell-sandbox/src/linux/와 crates/openshell-sandbox/src/sandbox/linux/landlock.rs파일·프로세스·소켓별 통제 담당표
5주차HTTP·TLS·Rego·자격증명. crates/openshell-supervisor-network/src/opa.rs, crates/openshell-supervisor-network/src/l7/relay.rs허용·거절·키 해석 실패를 포함한 요청 승인 표
6주차Kubernetes·저장소·SMT. crates/openshell-driver-kubernetes/src/shared_supervisor.rs, crates/openshell-server/src/persistence/, crates/openshell-prover/src/containment.rs단일 gateway에서 공유 supervisor로 확장할 때의 운영 설계 설명

모든 단계를 구현하려고 서두르기보다 각 주의 산출물을 다른 사람에게 설명해 보세요. 이해가 막히면 용어를 더 찾기 전에 입력·출력·실패 세 가지만 다시 적으면 됩니다. 독립 실행 실험은 지원 환경과 버전 준비를 마친 뒤 별도의 학습 단계로 진행할 수 있습니다.

학습 비유

큰 공장을 배울 때 모든 설비 매뉴얼을 처음부터 읽지는 않습니다. 원료 하나가 입고되어 출하될 때까지 따라가면, 각 설비가 왜 필요한지 이해할 수 있습니다. 여기서는 “에이전트의 API 요청 하나”가 그 원료입니다.

한 요청의 입력·권한 판단·실제 I/O·실패 기록을 끝까지 따라갈 수 있으면, 큰 저장소도 학습 가능한 크기로 나눌 수 있습니다.

10핵심 키워드 사전

본문을 다시 읽을 때 옆에 두는 용어 지도
용어쉬운 설명
자율 에이전트모델의 판단에 따라 도구를 호출하고 여러 작업을 이어가는 프로그램입니다.
런타임프로그램을 시작하고 연결·상태·종료를 관리하는 실행 환경입니다.
샌드박스프로그램이 접근할 수 있는 자원과 행동을 제한하는 실행 구역입니다.
신뢰 경계어느 쪽의 입력·프로세스를 어느 수준까지 믿을 것인지 나누는 선입니다.
gateway사용자 관리 API, 인증, 정책과 샌드박스 생명주기를 담당하는 제어 중심입니다.
supervisor경계 밖에서 요청을 승인하고 실제 외부 연결·자격증명을 처리하는 구성 요소입니다.
compute driver같은 생성·시작·종료 계약을 Docker·Kubernetes·VM 등에 맞게 구현하는 부품입니다.
제어 영역무엇을 실행하고 어떤 정책을 줄지 결정·관리하는 흐름입니다.
데이터 영역에이전트의 실제 네트워크 요청과 응답이 흐르는 경로입니다.
OCI 이미지컨테이너 실행 도구들이 공유하는 형식의 파일시스템·실행 설정 묶음입니다.
LandlockLinux에서 프로세스의 파일 접근 권한을 더 좁히는 보안 기능입니다.
seccomp user notification특정 시스템 호출을 커널에서 멈추고 사용자 공간 중개자에게 처리를 넘기는 방식입니다.
capabilityLinux의 root 권한을 세분화한 권한 단위입니다. 이 구현의 workload는 이를 제거하고 실행합니다.
procfs/proc 아래에서 프로세스·실행 파일 등의 상태를 관찰하는 Linux 인터페이스입니다.
L4 / L7L4는 TCP 연결 같은 전송 수준, L7은 HTTP 메서드·경로 같은 응용 요청 수준입니다.
provider외부 서비스 자격증명과 관련 설정을 관리하는 OpenShell 객체입니다.
대리 표식실제 비밀키 대신 에이전트에 주는 값입니다. 승인된 경로에서 실제 값으로 해석합니다.
credential binding어느 host·port·path에 자격증명을 사용할 수 있는지 묶어 두는 조건입니다.
mTLS양쪽이 인증서를 제시해 서로를 확인하는 TLS 인증 방식입니다.
JWT / generationJWT는 서명된 주장 묶음이고, generation은 특정 실행 세대입니다. 토큰을 세대에 묶어 재사용 범위를 제한합니다.
Rego / RegorusRego는 정책 표현 언어, Regorus는 이 저장소가 사용하는 Rust 평가 엔진입니다.
SMT / Z3논리 조건을 만족하는 사례가 있는지 찾는 기법과 solver입니다. 정책을 벗어나는 반례 탐색에 씁니다.
boundary / candidateboundary는 최대 허용 정책, candidate는 그 안에 들어오는지 검사할 후보 정책입니다.
낙관적 동시성 제어읽은 뒤 값이 바뀌지 않았는지 버전으로 확인하고, 바뀌었으면 충돌로 처리하는 방식입니다.
fail closed정상적으로 확인할 수 없을 때 접근·실행을 허용하지 않는 동작 원칙입니다.
OCSF / OpenTelemetry각각 보안 사건의 공통 형식과 분산 실행 흐름을 관찰하는 데 쓰는 표준·도구 체계입니다.
TUI터미널 안에서 표·상태·메뉴를 보여 주는 화면형 사용자 인터페이스입니다.
shallow clone전체 이력 대신 제한된 깊이의 커밋만 받은 복제입니다. 과거 변경 추적에는 한계가 있습니다.

비슷한 이름이 가장 위험한 혼동을 만듭니다. sandbox와 supervisor, 정책 형식의 version과 실행 상태의 revision, Rust crate 버전과 Linux ABI 버전은 각각 다른 의미입니다. 메모할 때 “무엇의 버전인가”까지 함께 적으세요.

11참고 링크

배울 주제별 공식 자료와 구현·수치의 기준을 정리한다

11-1. 프로젝트와 주요 소스

11-2. 관련 기술을 더 공부할 공식 문서

11-3. 현재 상태 (2026-10-23 확인)

GitHub 수치는 2026-10-23 GitHub API 기준입니다. 구현·버전·코드 규모의 기준 커밋은 9a85667입니다. 릴리스와 개발 커밋의 구현에는 차이가 있을 수 있습니다.

항목확인 내용
저장소NVIDIA/OpenShell · 주 언어 Rust
선정 근거TrendShift Daily #14 · 분석일 2026-10-23
스타 / 포크18,034 / 1,843
생성일2026-02-24
최근 push2026-10-23 · 2026-10-23 GitHub 기준
최신 릴리스v0.1.5 · 2026-10-20 · 2026-10-23 GitHub 기준
분석 HEAD9a85667d0d87e8131b64351ec1fc4eb26e7bb865
최근 커밋2026-10-22 22:20:02 UTC · feat(kubernetes): host sandboxes on the shared supervisor (#4702) · 한국 시각은 10월 23일입니다.
추적 파일 / crate2,106개 / crates/*/Cargo.toml 38개
라이선스Apache-2.0 · 루트 LICENSE 확인

11-4. 언어별 코드 규모

언어·형식파일 수줄 수
Rust (.rs)745651,126줄 · 약 65.1만
Go (.go)21671,640줄 · 약 7.2만
Python (.py)6720,651줄 · 약 2.1만
TypeScript (.ts)166,233줄
TSX (.tsx)3218줄
Protocol Buffers157,346줄
Shell (.sh)12629,805줄
YAML (.yaml / .yml)31926,993줄

집계는 git ls-files -z로 얻은 추적 파일 중 일반 파일을 대상으로 확장자별 개행 수를 더한 것입니다. 빈 줄·주석·테스트·예제·추적된 생성 코드를 포함하며 .git, 빌드 산출물, 외부 의존성 원본은 포함하지 않습니다. 따라서 “직접 작성한 제품 로직의 양”이나 프로젝트 간 생산성 지표로 사용하면 안 됩니다.

특히 Go에는 *.pb.go 5개, 29,508줄의 생성 코드가 포함됩니다. crates/ 아래 Rust는 609,616줄이고 나머지 Rust 집계에는 e2e·예제·테스트 등이 들어갑니다. 파일별 AST를 해석하는 도구로 실행문만 센 수치가 아닙니다.

수치와 기능 설명에 기준 날짜·커밋·집계 방법을 함께 남겨야, 빠르게 바뀌는 저장소도 다시 확인하며 공부할 수 있습니다.

사용 전에 확인
운영 환경에 적용할 때의 한계

구현 설명은 커밋 9a85667의 소스·설정·문서 기준입니다. 격리 강도·성능·배포 성공 여부는 실제 환경에서 별도로 검증해야 합니다. 개별 보안 경로의 독립 감사나 제품 전체의 안전 인증을 대신하지 않습니다.

분석 HEAD는 v0.1.5 태그 자체가 아닙니다. 공유 supervisor 등 개발 커밋의 구현을 릴리스 바이너리의 동작으로 그대로 일반화할 수 없습니다. 공식 latest 문서도 이후 바뀔 수 있으므로 본문의 고정 커밋 링크와 선택한 릴리스 문서를 대조하세요.

스타·포크·릴리스 날짜는 2026-10-23 GitHub 기준입니다. 트렌딩 관심 요인은 해석이며, 하드웨어 여유 예산은 학습 환경 제안입니다. 정책 통과는 모델 범위 안의 판단이고, 허용된 서비스로의 데이터 전송 자체를 없애 주지는 않습니다.