npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dongkseo/sandbox-server

v0.3.21

Published

**Stability: experimental** · `pnpm add @dongkseo/sandbox-server`

Readme

@dongkseo/sandbox-server

Stability: experimental · pnpm add @dongkseo/sandbox-server

Nexora sandbox wire 프로토콜의 참조 서버. 주입한 SandboxClient backend를 HTTP로 노출해, 원격 @dongkseo/sandbox-remote 클라이언트가 로컬처럼 구동하게 한다. 서버 자체는 격리를 소유하지 않지만(주입식 backend에 위임), 이 패키지는 조립용으로 batteries-included backend·세션 lifecycle· 네트워크 사이드카도 함께 export한다.

무엇인가 / 무엇이 아닌가

  • ✅ 담는 것(서버): createSandboxServer({ client, token?, archiveLimits?, lifecycle?, archiveStore?, rootAllowPrefixes? }) — Node http.Server를 만들어 세션 프로비저닝·원격 exec·파일 I/O(read/write/stat/readdir)·워크스페이스 persist/hydrate·reattach·delete 라우트를 제공. bearer 인증(constant-time), 요청당 경로 재검증, persist/hydrate는 하드닝된 writeTar/safeExtractTar(@dongkseo/contracts) 사용. SessionRegistry가 idle-archive/thaw/TTL sweep로 세션 lifecycle을 관리하고, shutdown()이 live 세션을 아카이브 후 닫는다.
  • ✅ 담는 것(조립 부품): 주입 가능한 OS-격리 backend(OverlayRootfsSandboxClient, GvisorSandboxClient), 아카이브 매체 (TarArchiveStore/DurableDirStore), 네트워크 사이드카(startEgressProxy/startAuthInjectingGateway). 아래 "함께 제공하는 조각" 참고.
  • ❌ 안 담는 것: 서버 라우트 층은 격리를 실행하지 않는다 — 주입식 SandboxClient에 위임한다(예: @dongkseo/coreAsrtSandboxClient, 또는 이 패키지의 OverlayRootfsSandboxClient/GvisorSandboxClient). 격리 backend를 주입해도 이 패키지의 런타임 의존성은 여전히 @dongkseo/contracts 하나뿐이다(bwrap/runsc/커널 기능은 런타임 호스트가 제공).

핵심 개념 — 라우트

| 라우트 | 용도 | |---|---| | POST /sessions | 세션 provision(manifest seed, optional rootDir) → { sessionId, root } | | POST /sessions/:id/exec | SandboxCommandResult 반환(버퍼링; SSE/PTY는 후속) | | GET·PUT /sessions/:id/fs?path= | 파일 read/write(경로 root-jail 재검증, 탈출은 403) | | GET /sessions/:id/stat?path= | { size, mtimeMs, isFile, isDirectory, mode }(lstat; 없으면 404) | | GET /sessions/:id/readdir?path= | [{ name, isDirectory }] | | POST /sessions/:id/persist | 워크스페이스를 tar bytes(octet-stream)로 반환 | | POST /sessions/:id/hydrate | tar 업로드 → 서버 root로 안전 추출(zip-slip/symlink/한도 거부) | | POST /sessions/:id/reattach | 세션 생존 여부 → { alive, root? }(죽은 세션도 관용) | | DELETE /sessions/:id | 세션/자원 해제 |

실패는 전부 { code, message, retryable } 정규화 envelope. 자격증명은 어떤 응답에도 실리지 않는다.

사용 레시피

import { createSandboxServer } from '@dongkseo/sandbox-server';
import { AsrtSandboxClient } from '@dongkseo/core'; // 서버 노드의 실제 OS 격리 backend

// createSandboxServer 는 { server, shutdown } 핸들을 반환한다(서버 인스턴스 아님).
const { server, shutdown } = createSandboxServer({
  client: new AsrtSandboxClient({ perRun: true, allowedDomains: [] }),
  token: process.env.SBX_TOKEN,
});
server.listen(8787);
// graceful stop: sweep 정지 → live 세션 아카이브 → close
process.on('SIGTERM', () => void shutdown());

이 패키지의 OverlayRootfsSandboxClientclient 로 주입하면 core 없이도 bwrap 기반 격리로 구동한다.

함께 제공하는 조각 (주입 / 조립용)

라우트 층과 별개로 export되는 부품들. createSandboxServer 가 자동 기동하지 않는다 — 필요에 따라 직접 주입/조립한다.

| export | 무엇 | 타입 읽기 | |---|---|---| | OverlayRootfsSandboxClient, buildBwrapArgs, OverlayRootfsOptions | bwrap overlay-rootfs 기반 OS-격리 SandboxClient. cap-drop, network none\|share\|proxy, read-only 마운트, 세션-프라이빗 home. 세션이 wrapCommand를 구현하므로 detached/background 실행도 격리된다(buildBwrapArgs가 순수 함수라 잽이 argv/env로 표현된다 — 호스트측 준비물이 없음). client 로 주입. | mode="signatures" | | GvisorSandboxClient, buildOciConfig, runscRunArgs, dropCapabilities, GvisorOptions, GvisorSpecBase | runsc(gVisor) 기반 OS-격리 SandboxClient — systrap 플랫폼(KVM 불필요), 실제 syscall 인터셉트 경계. 세션마다 baseRootfsDir를 복사한 전용 rootfs(--overlay2=none이라 설치물이 세션 수명 동안 영속). network none\|proxy(egress/auth는 bwrap과 동일하게 --host-uds 유닉스소켓 브릿지). runsc 바이너리 + privileged 컨테이너 필요; 구동 전 selfCheck()로 확인. wrapCommand 미구현run()이 exec마다 번들·마운트를 만들고 되돌리는데 {argv, env}엔 teardown 훅이 없다. 그래서 이 백엔드에서 run_in_background는 exec 툴이 거부한다. client 로 주입. | mode="signatures" | | SessionRegistry, SessionLifecycleOptions | 세션 lifecycle(acquire/release/reattach/sweep/archive). 서버가 내부 사용; 커스텀 조립 시 export. | mode="signatures" | | TarArchiveStore, DurableDirStore, ArchiveStore, TarArchiveStoreOptions | persist된 워크스페이스 아카이브 매체(tar 파일 / durable 디렉토리). archiveStore 옵션. | mode="signatures" | | startEgressProxy, isEgressAllowed, matchesDomainPattern, EgressProxyOptions, EgressProxyHandle | CONNECT egress 프록시 + 도메인 allow/deny. overlay client network:'proxy'egressSocketPath 뒤를 받치는 사이드카. | mode="signatures" | | startAuthInjectingGateway, AuthInjectingGatewayOptions, AuthInjectingGatewayHandle | 잽 안 요청에 auth 헤더를 주입하는 게이트웨이(ANTHROPIC_BASE_URL 리다이렉트). authGatewaySocketPath 뒤를 받치는 사이드카. | mode="signatures" |

rootAllowPrefixes (server 옵션)는 보안 게이트: CreateSessionRequest.rootDir 로 외부 root를 여는 걸 허용된 prefix로 제한한다. 미지정(기본)이면 외부-root 요청은 전부 403. 이 게이트를 통과한 세션은 non-archivable로 등록돼 idle sweep이 caller 소유 디렉토리를 tar하지 않고 cleanup도 삭제하지 않는다.

API 표면 (소스 안 열고 타입만)

ctx_read(path="packages/sandbox-server/src/index.ts",                mode="map")          # 전체 export 목록
ctx_read(path="packages/sandbox-server/src/server.ts",               mode="signatures")   # 라우트/옵션
ctx_read(path="packages/sandbox-server/src/overlay-rootfs-client.ts", mode="signatures")  # bwrap backend
ctx_read(path="packages/sandbox-server/src/gvisor-client.ts",         mode="signatures")  # runsc(gVisor) backend
ctx_read(path="packages/sandbox-server/src/session-registry.ts",     mode="signatures")   # lifecycle
ctx_read(path="packages/sandbox-server/src/egress-proxy.ts",         mode="signatures")   # egress 사이드카
ctx_read(path="packages/sandbox-server/src/auth-gateway.ts",         mode="signatures")   # auth 사이드카

유지보수 (drift 방지)

  • wire DTO 정본은 @dongkseo/contractssandbox-protocol.ts. 라우트 변경 시 클라이언트와 동시 갱신.
  • persist/hydrate 안전성은 contracts의 safe-archive.ts가 담보 — 서버는 그걸 호출만 한다.
  • OverlayRootfsSandboxClient/사이드카는 런타임 호스트에 bwrap·커널 기능·unix 소켓을 요구한다(패키지 의존성 아님). 구동 전 selfCheck()로 확인.
  • GvisorSandboxClient는 런타임 호스트에 runsc(gVisor) 바이너리와 privileged 컨테이너(nested systrap 요건)를 요구한다(패키지 의존성 아님). baseRootfsDir는 세션마다 통째로 복사되는 템플릿 rootfs — 설치 결과가 세션 수명 동안 영속하길 원하면 --overlay2=none 특성상 이 디렉토리 크기/복사 비용을 고려한다. egress/auth 주입은 overlay와 동일하게 --host-uds 유닉스소켓 브릿지로 이뤄진다. 구동 전 selfCheck()로 확인. (소비 앱에서 SANDBOX_BACKEND=gvisor 로 선택하는 배선은 각 앱의 몫 — 이 패키지는 backend를 스스로 선택하지 않는다.)

Tests

cd packages/sandbox-server && pnpm test

Part of the Nexora multi-tenant agent framework. · Package map