@nahisaho/katashiro-sandbox 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # @nahisaho/katashiro-sandbox
2
+
3
+ コード実行サンドボックスパッケージ。Docker/ローカル環境でbash, Python, JavaScript/TypeScriptを安全に実行します。
4
+
5
+ ## 概要
6
+
7
+ KATASHIRO v0.4.0で追加された、コード実行のための隔離環境を提供するパッケージです。
8
+
9
+ ### 主な機能
10
+
11
+ - **Docker実行**: Dockerコンテナ内での安全なコード実行
12
+ - **ローカル実行**: 開発/テスト用のローカル環境実行
13
+ - **複数言語サポート**: bash, Python, JavaScript, TypeScript
14
+ - **リソース制限**: メモリ、CPU、タイムアウト制限
15
+ - **セキュリティポリシー**: システムコール制限、ケーパビリティ削除
16
+
17
+ ## インストール
18
+
19
+ ```bash
20
+ npm install @nahisaho/katashiro-sandbox
21
+ ```
22
+
23
+ ## 基本的な使い方
24
+
25
+ ### 簡易関数
26
+
27
+ ```typescript
28
+ import { executePython, executeBash, executeJavaScript } from '@nahisaho/katashiro-sandbox';
29
+
30
+ // Pythonコード実行
31
+ const result = await executePython('print("Hello, World!")');
32
+ if (result.isOk()) {
33
+ console.log(result.value.stdout); // "Hello, World!\n"
34
+ }
35
+
36
+ // Bashスクリプト実行
37
+ const bashResult = await executeBash('echo "Hello from bash"');
38
+
39
+ // JavaScript実行
40
+ const jsResult = await executeJavaScript('console.log(1 + 2)');
41
+ ```
42
+
43
+ ### SandboxFactoryを使用
44
+
45
+ ```typescript
46
+ import { SandboxFactory } from '@nahisaho/katashiro-sandbox';
47
+
48
+ // Dockerサンドボックスを作成
49
+ const sandbox = SandboxFactory.create({ timeout: 60 }, 'docker');
50
+
51
+ // コード実行
52
+ const result = await sandbox.execute('print(sum(range(100)))', 'python');
53
+
54
+ // イベントリスナー
55
+ sandbox.on('execution:start', (event) => {
56
+ console.log(`開始: ${event.requestId}`);
57
+ });
58
+
59
+ sandbox.on('execution:complete', (event) => {
60
+ console.log(`完了: ${event.requestId}`);
61
+ });
62
+
63
+ // クリーンアップ
64
+ await sandbox.cleanup();
65
+ ```
66
+
67
+ ### 自動ランタイム検出
68
+
69
+ ```typescript
70
+ import { SandboxFactory } from '@nahisaho/katashiro-sandbox';
71
+
72
+ // Dockerが利用可能ならDocker、そうでなければローカル実行
73
+ const sandbox = await SandboxFactory.createAuto({ timeout: 30 });
74
+ ```
75
+
76
+ ## 設定
77
+
78
+ ### SandboxConfig
79
+
80
+ ```typescript
81
+ interface SandboxConfig {
82
+ runtime: 'docker' | 'local' | 'wasm'; // ランタイム
83
+ timeout: number; // タイムアウト(秒)
84
+ memoryLimit: number; // メモリ制限(バイト)
85
+ cpuLimit: number; // CPU制限(0.0-1.0)
86
+ workingDir: string; // 作業ディレクトリ
87
+ networkEnabled: boolean; // ネットワークアクセス
88
+ tmpfsSize: number; // 一時ファイルシステムサイズ
89
+ }
90
+ ```
91
+
92
+ ### デフォルト設定
93
+
94
+ ```typescript
95
+ const DEFAULT_SANDBOX_CONFIG = {
96
+ runtime: 'docker',
97
+ timeout: 30,
98
+ memoryLimit: 512 * 1024 * 1024, // 512MB
99
+ cpuLimit: 0.5,
100
+ workingDir: '/workspace',
101
+ networkEnabled: false,
102
+ tmpfsSize: 64 * 1024 * 1024, // 64MB
103
+ };
104
+ ```
105
+
106
+ ## Docker Executor
107
+
108
+ ### 特徴
109
+
110
+ - **完全な隔離**: コンテナ内でコードを実行
111
+ - **リソース制限**: メモリ・CPU制限を強制
112
+ - **セキュリティ**: ケーパビリティ削除、seccompプロファイル
113
+ - **自動クリーンアップ**: 実行後にコンテナを自動削除
114
+
115
+ ### 使用するDockerイメージ
116
+
117
+ | 言語 | デフォルトイメージ |
118
+ |------|-------------------|
119
+ | bash | alpine:3.19 |
120
+ | python | python:3.12-slim |
121
+ | javascript | node:22-slim |
122
+ | typescript | node:22-slim |
123
+
124
+ ### カスタムイメージの使用
125
+
126
+ ```typescript
127
+ import { DockerExecutor } from '@nahisaho/katashiro-sandbox';
128
+
129
+ const executor = new DockerExecutor(
130
+ { timeout: 60 },
131
+ {
132
+ images: {
133
+ bash: 'ubuntu:22.04',
134
+ python: 'python:3.11-alpine',
135
+ javascript: 'node:20-alpine',
136
+ typescript: 'node:20-alpine',
137
+ }
138
+ }
139
+ );
140
+ ```
141
+
142
+ ## Local Executor
143
+
144
+ ### 注意
145
+
146
+ Local Executorはホストシステムで直接コードを実行するため、**本番環境では使用しないでください**。開発とテスト目的専用です。
147
+
148
+ ```typescript
149
+ import { LocalExecutor } from '@nahisaho/katashiro-sandbox';
150
+
151
+ const executor = new LocalExecutor({ timeout: 10 });
152
+ const result = await executor.execute('console.log("test")', 'javascript');
153
+ ```
154
+
155
+ ## セキュリティポリシー
156
+
157
+ ```typescript
158
+ interface SecurityPolicy {
159
+ blockedSyscalls: string[]; // ブロックするシステムコール
160
+ readOnlyPaths: string[]; // 読み取り専用パス
161
+ writablePaths: string[]; // 書き込み可能パス
162
+ maxProcesses: number; // 最大プロセス数
163
+ maxOpenFiles: number; // 最大ファイルディスクリプタ数
164
+ }
165
+ ```
166
+
167
+ ### デフォルトポリシー
168
+
169
+ ```typescript
170
+ const DEFAULT_SECURITY_POLICY = {
171
+ blockedSyscalls: ['ptrace', 'mount', 'umount', 'reboot', 'swapon', 'swapoff'],
172
+ readOnlyPaths: ['/etc', '/usr', '/bin', '/lib'],
173
+ writablePaths: ['/workspace', '/tmp'],
174
+ maxProcesses: 10,
175
+ maxOpenFiles: 100,
176
+ };
177
+ ```
178
+
179
+ ## イベント
180
+
181
+ ```typescript
182
+ sandbox.on('execution:start', (event) => { ... });
183
+ sandbox.on('execution:output', (event) => { ... });
184
+ sandbox.on('execution:complete', (event) => { ... });
185
+ sandbox.on('execution:error', (event) => { ... });
186
+ sandbox.on('execution:timeout', (event) => { ... });
187
+ sandbox.on('container:create', (event) => { ... });
188
+ sandbox.on('container:start', (event) => { ... });
189
+ sandbox.on('container:stop', (event) => { ... });
190
+ sandbox.on('security:violation', (event) => { ... });
191
+ ```
192
+
193
+ ## ExecutionResult
194
+
195
+ ```typescript
196
+ interface ExecutionResult {
197
+ requestId: string; // リクエストID
198
+ status: ExecutionStatus; // 'completed' | 'failed' | 'timeout' | ...
199
+ exitCode: number; // 終了コード
200
+ stdout: string; // 標準出力
201
+ stderr: string; // 標準エラー出力
202
+ duration: number; // 実行時間(ミリ秒)
203
+ files: FileOutput[]; // 出力ファイル
204
+ memoryUsed?: number; // メモリ使用量
205
+ cpuTime?: number; // CPU使用時間
206
+ error?: ExecutionError; // エラー詳細
207
+ completedAt: string; // 完了日時
208
+ }
209
+ ```
210
+
211
+ ## ライセンス
212
+
213
+ MIT
@@ -0,0 +1,117 @@
1
+ /**
2
+ * KATASHIRO Sandbox - Docker Executor Implementation
3
+ *
4
+ * @fileoverview REQ-007: Dockerベースのコード実行サンドボックス
5
+ * @module @nahisaho/katashiro-sandbox
6
+ * @since 0.4.0
7
+ */
8
+ import { EventEmitter } from 'events';
9
+ import { type Result } from '@nahisaho/katashiro-core';
10
+ import type { SandboxConfig, DockerConfig, ExecutionRequest, ExecutionResult, SupportedLanguage, SecurityPolicy, SandboxEventType, SandboxEventListener, ContainerInfo, ResourceStats } from './types';
11
+ /**
12
+ * サンドボックスエラー
13
+ */
14
+ export declare class SandboxError extends Error {
15
+ readonly code: string;
16
+ readonly details?: Record<string, unknown> | undefined;
17
+ constructor(message: string, code: string, details?: Record<string, unknown> | undefined);
18
+ }
19
+ /**
20
+ * Docker Executor
21
+ *
22
+ * EARS Requirements:
23
+ * - Ubiquitous: The Sandbox shall execute code in an isolated Docker/VM environment
24
+ * - Ubiquitous: The Sandbox shall support bash, Python, and JavaScript/TypeScript execution
25
+ * - Event-Driven: When execution time exceeds timeout, the Sandbox shall terminate
26
+ * - State-Driven: While code is executing, the Sandbox shall enforce CPU and memory limits
27
+ * - Unwanted: If code attempts to access host system, the Sandbox shall block the access
28
+ */
29
+ export declare class DockerExecutor extends EventEmitter {
30
+ private readonly docker;
31
+ private readonly config;
32
+ private readonly dockerConfig;
33
+ private readonly securityPolicy;
34
+ private readonly activeContainers;
35
+ constructor(config?: Partial<SandboxConfig>, dockerConfig?: Partial<DockerConfig>, securityPolicy?: Partial<SecurityPolicy>);
36
+ /**
37
+ * 型安全なイベントリスナー登録
38
+ */
39
+ on(event: SandboxEventType, listener: SandboxEventListener): this;
40
+ /**
41
+ * イベント発火
42
+ */
43
+ private emitEvent;
44
+ /**
45
+ * コードを実行
46
+ *
47
+ * @param code 実行するコード
48
+ * @param language プログラミング言語
49
+ * @param options 追加オプション
50
+ */
51
+ execute(code: string, language: SupportedLanguage, options?: Partial<Pick<ExecutionRequest, 'stdin' | 'env' | 'timeout'>>): Promise<Result<ExecutionResult, SandboxError>>;
52
+ /**
53
+ * コンテナを作成
54
+ */
55
+ private createContainer;
56
+ /**
57
+ * 実行コマンドを構築
58
+ */
59
+ private buildCommand;
60
+ /**
61
+ * 言語に対応するファイル名を取得
62
+ */
63
+ private getCodeFileName;
64
+ /**
65
+ * 環境変数を構築
66
+ */
67
+ private buildEnv;
68
+ /**
69
+ * コードをコンテナにコピー
70
+ */
71
+ private copyCodeToContainer;
72
+ /**
73
+ * tarアーカイブを作成(簡易版)
74
+ */
75
+ private createTarArchive;
76
+ /**
77
+ * コンテナの完了を待機
78
+ */
79
+ private waitForCompletion;
80
+ /**
81
+ * Dockerログをパース
82
+ */
83
+ private parseLogs;
84
+ /**
85
+ * 出力ファイルを抽出
86
+ */
87
+ private extractOutputFiles;
88
+ /**
89
+ * コンテナをクリーンアップ
90
+ */
91
+ private cleanupContainer;
92
+ /**
93
+ * エラーをパース
94
+ */
95
+ private parseError;
96
+ /**
97
+ * アクティブなコンテナ数を取得
98
+ */
99
+ getActiveContainerCount(): number;
100
+ /**
101
+ * 指定した実行をキャンセル
102
+ */
103
+ cancel(requestId: string): Promise<boolean>;
104
+ /**
105
+ * 全アクティブコンテナをクリーンアップ
106
+ */
107
+ cleanup(): Promise<void>;
108
+ /**
109
+ * コンテナ情報を取得
110
+ */
111
+ getContainerInfo(requestId: string): Promise<ContainerInfo | null>;
112
+ /**
113
+ * リソース使用量を取得
114
+ */
115
+ getResourceStats(requestId: string): Promise<ResourceStats | null>;
116
+ }
117
+ //# sourceMappingURL=docker-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-executor.d.ts","sourceRoot":"","sources":["../src/docker-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAW,KAAK,MAAM,EAAc,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAGf,iBAAiB,EACjB,cAAc,EAEd,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,aAAa,EACd,MAAM,SAAS,CAAC;AAWjB;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;aAGnB,IAAI,EAAE,MAAM;aACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAFjD,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;CAKpD;AAMD;;;;;;;;;GASG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuC;gBAGtE,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,EACnC,YAAY,GAAE,OAAO,CAAC,YAAY,CAAM,EACxC,cAAc,GAAE,OAAO,CAAC,cAAc,CAAM;IAc9C;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAIjE;;OAEG;IACH,OAAO,CAAC,SAAS;IAYjB;;;;;;OAMG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC,CAAM,GACzE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IAqGjD;;OAEG;YACW,eAAe;IAwD7B;;OAEG;IACH,OAAO,CAAC,YAAY;IA+BpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAUhB;;OAEG;YACW,mBAAmB;IAajC;;OAEG;YACW,gBAAgB;IA0D9B;;OAEG;YACW,iBAAiB;IAmC/B;;OAEG;IACH,OAAO,CAAC,SAAS;IAoCjB;;OAEG;YACW,kBAAkB;IAQhC;;OAEG;YACW,gBAAgB;IAuB9B;;OAEG;IACH,OAAO,CAAC,UAAU;IAsBlB;;OAEG;IACH,uBAAuB,IAAI,MAAM;IAIjC;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAcjD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAoBxE;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;CAkEzE"}