Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
capsule — AI 에이전트 작업을 샌드박싱하는 보안 런타임. 격리된 WebAssembly 환경에서 신뢰할 수 없는 코드를 실행합니다. | Kitploit
도구/GitHubGitHub/capsulerun/capsule
Container SecurityDynamic Analysis (Sandboxing)Scripting & AutomationServerless SecuritySecurity VirtualizationCloud SecurityUtilities & FrameworksAI Security
GitHubcapsulerun/capsule

capsule

AI 에이전트 작업을 샌드박싱하는 보안 런타임. 격리된 WebAssembly 환경에서 신뢰할 수 없는 코드를 실행합니다.

저장소 보기
294212개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
Capsule

Capsule

CI

시작하기 • 문서 • 이슈 • 기여하기


개요

Capsule은 신뢰할 수 없는 코드를 격리된 환경에서 실행하기 위한 런타임입니다. 각 태스크는 자체 WebAssembly 샌드박스 내에서 실행되며, 다음을 제공합니다:

  • 격리된 실행: 각 태스크가 호스트 시스템으로부터 격리되어 실행됩니다
  • 리소스 제한: 태스크별로 CPU, 메모리, 타임아웃 제한을 설정할 수 있습니다
  • 자동 재시도: 수동 개입 없이 실패를 처리합니다
  • 생명 주기 추적: 실행 중, 완료됨, 실패 상태를 모니터링할 수 있습니다

작동 방식

Python 사용 시

Python 함수를 @task 데코레이터로 간단히 주석 처리하세요:

root@kitploit:~
from capsule import task

@task(name="analyze_data", compute="MEDIUM", ram="512MB", timeout="30s", max_retries=1)
def analyze_data(dataset: list) -> dict:
    """Process data in an isolated, resource-controlled environment."""
    # Your code runs safely in a Wasm sandbox
    return {"processed": len(dataset), "status": "complete"}

TypeScript / JavaScript 사용 시

npm 생태계에 완전히 접근할 수 있는 task() 래퍼 함수를 사용하세요:

root@kitploit:~
import { task } from "@capsule-run/sdk";

export const analyzeData = task({
  name: "analyze_data",
  compute: "MEDIUM",
  ram: "512MB",
  timeout: "30s",
  maxRetries: 1
}, (dataset: number[]): object => {
  // Your code runs safely in a Wasm sandbox
  return { processed: dataset.length, status: "complete" };
});

[!NOTE] 런타임은 진입점으로 "main"이라는 이름의 태스크가 필요합니다. Python은 정의되지 않은 경우 자동으로 하나를 생성하지만, 명시적으로 설정하는 것이 좋습니다.

capsule run main.py (또는 main.ts)를 실행하면 코드가 WebAssembly 모듈로 컴파일되어 격리된 샌드박스에서 실행됩니다.

각 태스크는 구성 가능한 리소스 제한이 있는 자체 샌드박스 내에서 작동하여, 실패가 격리되고 워크플로의 다른 부분으로 전파되지 않습니다. 호스트 시스템은 Wasm 연료 측정을 통한 CPU 할당부터 메모리 제약 및 타임아웃 적용까지 실행의 모든 측면을 제어합니다.

시작하기

Python

root@kitploit:~
pip install capsule-run

hello.py 생성:

root@kitploit:~
from capsule import task

@task(name="main", compute="LOW", ram="64MB")
def main() -> str:
    return "Hello from Capsule!"

실행:

root@kitploit:~
capsule run hello.py

TypeScript / JavaScript

root@kitploit:~
npm install -g @capsule-run/cli
npm install @capsule-run/sdk

hello.ts 생성:

root@kitploit:~
import { task } from "@capsule-run/sdk";

export const main = task({
  name: "main",
  compute: "LOW",
  ram: "64MB"
}, (): string => {
  return "Hello from Capsule!";
});

실행:

root@kitploit:~
capsule run hello.ts

[!TIP] --verbose를 추가하면 실시간 태스크 실행 세부 정보를 볼 수 있습니다.

코드에서 실행

run() 함수를 사용하면 CLI 대신 코드에서 프로그래밍 방식으로 태스크를 실행할 수 있습니다. args는 자동으로 main 태스크의 매개변수로 전달됩니다.

Python

root@kitploit:~
from capsule import run

result = await run(
    file="./sandbox.py",
    args=["code to execute"]
)

sandbox.py 생성:

root@kitploit:~
from capsule import task

@task(name="main", compute="LOW", ram="64MB")
def main(code: str) -> str:
    return eval(code)

TypeScript / JavaScript

[!IMPORTANT] TypeScript에서 러너 함수를 사용하려면 의존성에 @capsule-run/cli가 필요합니다.

root@kitploit:~
import { run } from '@capsule-run/sdk/runner';

const result = await run({
  file: './sandbox.ts',
  args: ['code to execute']
});

sandbox.ts 생성:

root@kitploit:~
import { task } from "@capsule-run/sdk";

export const main = task({
  name: "main",
  compute: "LOW",
  ram: "64MB"
}, (code: string): string => {
  return eval(code);
});

[!TIP] 미리 구성된 바로 사용 가능한 솔루션을 찾고 있다면 Python 어댑터 또는 TypeScript 어댑터를 확인하세요.

문서

태스크 구성 옵션

다음 매개변수로 태스크를 구성하세요:

컴퓨트 수준

Capsule은 WebAssembly의 연료 메커니즘을 통해 CPU 사용량을 제어합니다. 이 메커니즘은 명령어 실행을 계량합니다. 컴퓨트 수준은 태스크가 받는 연료량을 결정합니다.

  • LOW는 가벼운 태스크를 위한 최소 할당을 제공합니다
  • MEDIUM은 일반적인 워크로드에 적합한 균형 잡힌 리소스를 제공합니다
  • HIGH는 계산 집약적인 작업을 위한 최대 연료를 부여합니다
  • CUSTOM은 정확한 연료 값을 지정하여 실행 제한을 세밀하게 제어할 수 있습니다 (예: compute="1000000")

응답 형식

모든 태스크는 결과와 실행 메타데이터를 모두 포함하는 구조화된 JSON 봉투를 반환합니다:

root@kitploit:~
{
  "success": true,
  "result": "Hello from Capsule!",
  "error": null,
  "execution": {
    "task_name": "data_processor",
    "duration_ms": 1523,
    "retries": 0,
    "fuel_consumed": 45000,
    "ram_used": 1200000,
    "host_requests": [{...}]
  }
}

응답 필드:

  • success — 태스크가 성공적으로 완료되었는지 나타내는 부울 값
  • result — 태스크의 실제 반환 값 (json, string, 실패 시 null 등)
  • error — 태스크 실패 시 오류 세부 정보 ({ error_type: string, message: string })
  • execution — 성능 메트릭:
    • task_name — 실행된 태스크의 이름
    • duration_ms — 실행 시간 (밀리초)
    • retries — 발생한 재시도 횟수
    • fuel_consumed — 사용된 CPU 리소스 (컴퓨트 수준 참조)
    • ram_used — 최대 사용 메모리 (바이트)
    • host_requests — 태스크가 수행한 호스트 요청 목록

네트워크 접근

태스크는 allowed_hosts에 지정된 도메인으로 HTTP 요청을 보낼 수 있습니다. 기본적으로 아웃바운드 요청은 허용되지 않습니다 ([]). 도메인을 허용 목록으로 제공하거나, ["*"]를 사용하여 모든 도메인을 허용할 수 있습니다.

Python

root@kitploit:~
import json
from capsule import task
from urllib.request import urlopen

@task(name="main", allowed_hosts=["api.openai.com", "*.anthropic.com"])
def main() -> dict:
    with urlopen("https://api.openai.com/v1/models") as response:
        return json.loads(response.read().decode("utf-8"))

TypeScript / JavaScript

root@kitploit:~
import { task } from "@capsule-run/sdk";

export const main = task({
    name: "main",
    allowedHosts: ["api.openai.com", "*.anthropic.com"]
}, async () => {
    const response = await fetch("https://api.openai.com/v1/models");
    return response.json();
});

파일 접근

태스크는 allowed_files에 지정된 디렉토리 내에서 파일을 읽고 쓸 수 있습니다. 이러한 디렉토리 외부의 파일에 접근하는 시도는 불가능합니다.

[!NOTE] allowed_files는 개별 파일이 아닌 디렉토리 경로만 지원합니다.

각 항목은 일반 경로 (기본적으로 읽기-쓰기) 또는 명시적인 mode가 있는 구조화된 객체일 수 있습니다:

  • "read-only" (또는 "ro")
  • "read-write" (또는 "rw")

Python

Python의 표준 파일 연산이 정상적으로 작동합니다. open(), os, pathlib 또는 파일 조작 라이브러리를 사용하세요.

root@kitploit:~
from capsule import task

@task(name="main", allowed_files=[
    {"path": "./data", "mode": "read-only"},
    {"path": "./output", "mode": "read-write"},
])
def main() -> str:
    with open("./data/input.txt") as f:
        content = f.read()
    with open("./output/result.txt", "w") as f:
        f.write(content)
    return content

일반 문자열도 허용됩니다: allowed_files=["./output"]는 기본적으로 읽기-쓰기로 처리됩니다.

TypeScript / JavaScript

일반적인 Node.js 내장 모듈을 사용할 수 있습니다. 표준 fs 모듈을 사용하세요:

root@kitploit:~
import { task } from "@capsule-run/sdk";
import fs from "fs/promises";

export const main = task({
    name: "main",
    allowedFiles: [
        { path: "./data", mode: "read-only" },
        { path: "./output", mode: "read-write" },
    ]
}, async () => {
    const content = await fs.readFile("./data/input.txt", "utf8");
    await fs.writeFile("./output/result.txt", content);
    return content;
});

일반 문자열도 허용됩니다: allowedFiles: ["./output"]는 기본적으로 읽기-쓰기로 처리됩니다.

동적 디렉토리 별칭 (--mount)

--mount 플래그 (CLI) 또는 mounts 매개변수 (SDK)는 호스트 디렉토리를 별칭으로 샌드박스에 마운트합니다. 마운트는 하위 태스크로 전파되며 새 경로에 대한 접근을 추가하지만, allowed_files에 이미 선언된 경로의 접근 모드를 변경하지는 않습니다.

형식: HOST_PATH[::GUEST_PATH][:ro|:rw]

CLI

root@kitploit:~
# 세션 작업 공간을 마운트하고 태스크 내에서 "workspace"로 노출
capsule run main.py --mount sessions/abc123_workspace::workspace

# 여러 디렉토리
capsule run main.py \
  --mount sessions/abc123_workspace::workspace \
  --mount sessions/bce456_workspace::workspace:ro

Python SDK

root@kitploit:~
from capsule import run

result = await run(
    file="main.py",
    mounts=[".capsule/sessions/abc123_workspace::workspace"],
)

TypeScript / JavaScript SDK

root@kitploit:~
import { run } from "@capsule-run/sdk";

const result = await run({
    file: "main.py",
    mounts: [".capsule/sessions/abc123_workspace::workspace"],
});

태스크 내부에서는 게스트 경로로 디렉토리에 접근합니다:

root@kitploit:~
# 태스크는 "workspace/"에서 접근하며, 전체 세션 경로가 아님
with open("workspace/output.txt", "w") as f:
    f.write("done")

[!NOTE] --mount 경로는 상대 경로여야 하며 프로젝트 루트를 벗어나면 안 됩니다. 절대 경로는 거부됩니다.

환경 변수

태스크는 환경 변수에 접근하여 구성, API 키 또는 기타 런타임 설정을 읽을 수 있습니다.

Python

Python의 표준 os.environ을 사용하여 환경 변수에 접근하세요:

root@kitploit:~
from capsule import task
import os

@task(name="main", env_variables=["API_KEY"])
def main() -> dict:
    api_key = os.environ.get("API_KEY")
    return {"api_key": api_key}

TypeScript / JavaScript

표준 process.env를 사용하여 환경 변수에 접근하세요:

root@kitploit:~
import { task } from "@capsule-run/sdk";

export const main = task({
    name: "main",
    envVariables: ["API_KEY"]
}, () => {
    const apiKey = process.env.API_KEY;
    return { apiKeySet: apiKey !== undefined };
});

프로젝트 구성 (선택 사항)

프로젝트 루트에 capsule.toml 파일을 생성하여 모든 태스크에 대한 기본 옵션을 설정하고 워크플로 메타데이터를 정의할 수 있습니다:

root@kitploit:~
# capsule.toml

[workflow]
name = "My Workflow"
version = "1.0.0"
entrypoint = "src/main.py"  # `capsule run` 실행 시 기본 파일

[tasks]
default_compute = "MEDIUM"
default_ram = "256MB"
default_timeout = "30s"
default_max_retries = 2

진입점이 정의되면 다음 명령만으로 실행할 수 있습니다:

root@kitploit:~
capsule run

태스크 수준 옵션은 지정된 경우 항상 이 기본값을 덮어씁니다.

캐시 관리

코드를 실행하면 Capsule이 프로젝트 루트에 .capsule 폴더를 생성합니다. 이것이 빌드 캐시입니다. 컴파일된 아티팩트를 저장하여 후속 실행을 빠르게 만듭니다 (몇 초에서 몇 밀리초로).

[!TIP] .capsule은 .gitignore에 추가해야 합니다. 캐시는 사용자 환경에 따라 다르며 자동으로 재생성됩니다.

root@kitploit:~
.capsule/
├── wasm/
│   ├── main_a1b2c3d4.wasm    # Compiled WebAssembly module
│   └── main_a1b2c3d4.cwasm   # Native precompiled cache
├── wit/                       # Interface definitions
└── trace.db                   # Execution logs

capsule build를 사용하여 미리 컴파일하면 첫 번째 실행 시 컴파일 비용을 건너뛸 수 있습니다:

root@kitploit:~
capsule build main.ts # 또는 `main.py`

프로덕션

소스 코드 (.py 또는 .ts)를 직접 실행하면 런타임에 파일을 평가하고 컴파일합니다. 개발에는 좋지만, 이 컴파일 단계는 첫 번째 호출에 몇 초의 지연 시간을 추가합니다. 서브초 지연 시간이 중요한 사용 사례의 경우 태스크를 미리 빌드해야 합니다.

root@kitploit:~
# 최적화된 hello.wasm 파일 생성
capsule build hello.py --export

# 컴파일된 아티팩트 직접 실행
capsule exec hello.wasm

[!NOTE] 또는 기존 코드에서:

root@kitploit:~
from capsule import run

result = await run(
   file="./hello.wasm", # 또는 `hello.py`
   args=[]
)

print(f"Task completed: {result['result']}")

.wasm 파일을 실행하면 컴파일러를 완전히 건너뛰어 초기화 시간을 밀리초로 줄이는 동시에 기본 최적화된 (.cwasm) 형식을 내부적으로 사용합니다.

호환성

[!NOTE] TypeScript/JavaScript는 네이티브 바인딩에 의존하지 않으므로 Python보다 더 넓은 호환성을 가집니다.

Python: 대부분의 표준 Python 라이브러리가 완벽하게 작동합니다. C 확장을 사용하는 패키지는 wasm32-wasi로 컴파일된 휠이 필요합니다. numpy 및 pandas와 같은 많은 인기 패키지는 아직 이를 제공하지 않으므로 샌드박스 내에서 작동하지 않습니다. 그러나 호스트 코드 (run() 사용)는 모든 pip 패키지 및 네이티브 확장을 포함한 전체 Python 생태계에 접근할 수 있습니다. 코드 내 사용 참조

TypeScript/JavaScript: npm 패키지와 ES 모듈이 작동합니다. 일반적인 Node.js 내장 모듈을 사용할 수 있습니다. 내장 모듈에 문제가 있으면 이슈를 열어 주시기 바랍니다.

기여하기

기여를 환영합니다!

개발 환경 설정

필수 사항: Rust (최신 안정 버전), Python 3.13+, Node.js 22+

root@kitploit:~
git clone https://github.com/capsulerun/capsule.git
cd capsule

# CLI 빌드 및 설치
cargo install --path crates/capsule-cli

# Python SDK (편집 가능한 설치)
pip install -e crates/capsule-sdk/python

# TypeScript SDK (로컬 개발용 링크)
cd crates/capsule-sdk/javascript
npm install && npm run build && npm link

# 프로젝트에서: npm link @capsule-run/sdk

기여 방법

  1. 저장소를 포크하세요
  2. 기능 브랜치를 생성하세요: git checkout -b feature/amazing-feature
  3. 테스트를 실행하세요: cargo test (crates/capsule-cli 또는 crates/capsule-core 수정 시에만 필요)
  4. 풀 리퀘스트를 열어주세요

도움이 필요하신가요? 이슈를 열어주세요

크레딧

Capsule은 다음 오픈 소스 프로젝트를 기반으로 합니다:

  • componentize-py – Python to WebAssembly Component compilation
  • jco – JavaScript toolchain for WebAssembly Components
  • wasmtime – WebAssembly runtime
  • WASI – WebAssembly System Interface

라이선스

이 프로젝트는 Apache License 2.0에 따라 라이선스가 부여됩니다. 자세한 내용은 LICENSE 파일을 참조하세요.

도구 다운로드
매개변수설명타입기본값예시
name태스크 식별자str함수 이름 (Python) / 필수 (TS)"process_data"
computeCPU 할당 수준: "LOW", "MEDIUM", 또는 "HIGH"str"MEDIUM""HIGH"
ram태스크의 메모리 제한str무제한"512MB", "2GB"
timeout최대 실행 시간str무제한"30s", "5m", "1h"
max_retries / maxRetries실패 시 재시도 횟수int03
allowed_files / allowedFiles샌드박스에서 접근 가능한 폴더 (선택적 접근 모드 포함)list[]["./data"], [{"path": "./data", "mode": "ro"}]
allowed_hosts / allowedHosts샌드박스에서 접근 가능한 도메인list[]["api.openai.com", "*.anthropic.com"]
env_variables / envVariables샌드박스에서 접근 가능한 환경 변수list[]["API_KEY"]
부분필수설명
HOST_PATH예호스트 머신의 경로 (cwd 기준, 프로젝트 루트 내에 있어야 함)
::GUEST_PATH아니오태스크가 샌드박스 내에서 보는 경로. 기본값은 HOST_PATH
:ro / :rw아니오접근 모드. 기본값은 읽기-쓰기