DeepSeek Harness: サンドボックスと承認
最終更新:2026-08-31
Agent の力は操作を実行できることにありますが、「実行できる」≠「実行すべき」です。承認ポリシーは Agent のブレーキ、サンドボックスは Agent のフェンスです。この2つがあれば、Agent は安全な境界内で自由に行動できます。
📋 前提知識:13-effect.md と 22-capability.md の完了
1. 学習内容
- 承認ポリシー
- パーミッションプリセット
- 危険操作の承認ポップアップ
- サンドボックスバックエンド登録
- ctx.sandbox と ctx.shell
- リモートサンドボックス設定
2. 承認ポリシー
(1) ポリシーモード
DSH は4つの承認モードを提供:
| モード | 動作 | 最適な用途 |
|---|---|---|
always |
常に許可、ポップアップなし | 安全な操作(読取、検索) |
ask |
承認が必要、ポップアップ確認 | 危険な操作(作成、編集、shell) |
ask_with_confirm |
二重確認ポップアップ | 極めて危険な操作(削除、sudo) |
deny |
自動拒否 | 絶対に実行してはいけない操作(rm -rf /) |
▶ サンプル 2:
# dsh.config.yaml
approval:
default:ask
tools:
file_edit:
read:always
create:ask
edit:ask
delete:ask_with_confirm
shell:
safe:always
moderate:ask
dangerous:ask_with_confirm
forbidden:deny
search:
default:always
sandbox:
default:ask
▶ サンプル 3:
approval:
tools:
file_edit:
# パスホワイトリスト自動許可
auto_allow_paths:
- /tmp/**
- /workspace/**
# パスブラックリスト自動拒否
auto_deny_paths:
- /etc/**
- /var/**
shell:
# コマンドホワイトリスト
auto_allow_commands:
- ls
- cat
- grep
- head
- wc
- git status
- git log
# コマンドブラックリスト
auto_deny_commands:
- rm -rf /*
- mkfs
- dd if=*
▶ サンプル 4:
import { defineTool } from '@deepseek-ai/dsh'
export default defineTool({
name:'db_query',
description:'Execute SQL query',
parameters:{ /* ... */ },
approval:{
level:'ask',
rules:[
{ match:{ query:/^SELECT/i }, level:'always' },
{ match:{ query:/^DROP/i }, level:'deny' },
{ match:{ query:/^INSERT|^UPDATE|^DELETE/i }, level:'ask_with_confirm' }
]
},
async execute({ query }, ctx) {
return await ctx.database.query(query)
}
})
3. パーミッションプリセット
(1) 組み込みプリセット
DSH は3つのパーミッションプリセットを提供:
| プリセット | 説明 | 典型的な用途 |
|---|---|---|
| trusted | 信頼モード、ほとんどの操作を自動許可 | 個人開発環境 |
| standard | 標準モード、危険操作は承認が必要 | デフォルト設定 |
| restricted | 制限モード、厳格な承認 | 本番環境 |
(2) プリセットの比較
# trusted — 信頼モード
approval:
tools:
file_edit:always
shell:always
search:always
# standard — 標準モード
approval:
tools:
file_edit:
read:always
create:ask
edit:ask
delete:ask_with_confirm
shell:ask
# restricted — 制限モード
approval:
tools:
file_edit:ask_with_confirm
shell:deny
search:ask
(3) プリセットの選択
# 起動時にプリセットを選択
pnpm dsh web --preset trusted
pnpm dsh web --preset standard
pnpm dsh web --preset restricted
(4) カスタムプリセット
# dsh.config.yaml
approval:
presets:
my-team:
tools:
file_edit:
read:always
create:ask
edit:ask
delete:deny
shell:ask
4. 危険操作の承認ポップアップ
(1) ポップアップ機構
ツール呼び出しが承認を必要とする場合、DSH は実行を一時停止し承認ポップアップを表示:
⚠️ Approval Required:Execute shell command
Command:npm install bcryptjs
Working directory:/home/alice/project
Risk level:MODERATE
[Allow] [Always for npm] [Deny]
(2) 承認オプション
| オプション | 説明 |
|---|---|
| Allow | この操作を許可 |
| Always | このタイプの操作を常に許可(以降ポップアップなし) |
| Always for X | 特定ルールにマッチする操作を常に許可 |
| Deny | この操作を拒否 |
(3) バッチ承認
複数操作を一括承認可能:
⚠️ Batch Approval Required:3 operations
1. file_edit:create src/utils.ts
2. file_edit:edit src/app.ts
3. shell:npm install bcryptjs
[Allow All] [Review Each] [Deny All]
(4) 承認ログ
すべての承認決定が記録されます:
[approval] ALLOWED:file_edit(read, src/config.ts) — policy:always
[approval] ASKED:file_edit(create, src/utils.ts) — user:allowed
[approval] DENIED:shell(rm -rf /tmp/test) — policy:deny
5. サンドボックスバックエンド登録
(1) サンドボックスの概念
サンドボックスはツール実行の隔離環境——Agent の操作はサンドボックス内で実行され、ホストシステムに影響しません:
graph LR
AGENT[Agent] -->|calls tools| SANDBOX[Sandbox environment]
SANDBOX -->|isolated execution| FS[Sandbox filesystem]
SANDBOX -->|isolated execution| SHELL[Sandbox Shell]
SANDBOX -->|isolated network| NET[Sandbox network]
SANDBOX -.->|not allowed| HOST[Host system]
(2) サンドボックスバックエンドインターフェース
interface SandboxBackend {
name:string
execute(command:string, options:ShellOptions):Promise<ShellResult>
readFile(path:string):Promise<string>
writeFile(path:string, content:string):Promise<void>
stat(path:string):Promise<FileStat>
readdir(path:string):Promise<DirEntry[]>
}
(3) サンドボックスバックエンドの登録
import { Service, Context } from '@deepseek-ai/cordis'
export default class DockerSandboxBackend extends Service {
constructor(ctx:Context) {
super(ctx, 'sandbox')
ctx.implement(SandboxCapability, {
name:'docker-sandbox',
async execute(command, options) {
const container = await this.getContainer()
const result = await container.exec(command, options)
return result
},
async readFile(path) {
const container = await this.getContainer()
return await container.readFile(path)
},
async writeFile(path, content) {
const container = await this.getContainer()
await container.writeFile(path, content)
},
// ...
})
}
}
(4) サンドボックスの設定
# dsh.config.yaml
sandbox:
backend:docker
config:
image:dsh-sandbox:latest
workdir:/workspace
memory:512m
cpus:1
timeout:30000
network:none
6. ctx.sandbox と ctx.shell
(1) ctx.sandbox
ctx.sandbox はサンドボックス化されたファイル操作を提供:
export const inject = ['sandbox']
export function apply(ctx:Context) {
ctx.tools.register(defineTool({
name:'sandbox_read',
description:'Read file in sandbox',
parameters:{
type:'object',
properties:{
path:{ type:'string', description:'File path in sandbox' }
},
required:['path']
},
async execute({ path }, ctx) {
const content = await ctx.sandbox.readFile(path)
return { content }
}
}))
}
(2) ctx.shell
ctx.shell はサンドボックス内でコマンドを実行:
export const inject = ['shell']
export function apply(ctx:Context) {
ctx.tools.register(defineTool({
name:'sandbox_exec',
description:'Execute command in sandbox',
parameters:{
type:'object',
properties:{
command:{ type:'string', description:'Command to execute' }
},
required:['command']
},
async execute({ command }, ctx) {
const result = await ctx.shell.execute(command, {
cwd:'/workspace',
timeout:30000
})
return {
stdout:result.stdout,
stderr:result.stderr,
exitCode:result.exitCode
}
}
}))
}
(3) sandbox と直接 fs の比較
| 操作 | 直接 fs | ctx.sandbox |
|---|---|---|
| ファイルパス | ホストシステムのパス | サンドボックス内部のパス |
| パーミッション | ホストユーザー権限 | サンドボックスユーザー権限 |
| 隔離 | なし | 完全隔離 |
| パフォーマンス | 高速 | やや低速(サンドボックス層経由) |
(4) 安全な使用原則
// ❌ ホストファイルシステムに直接アクセス
import { readFileSync } from 'fs'
const content = readFileSync('/etc/passwd')
// ✅ サンドボックス経由
const content = await ctx.sandbox.readFile('/etc/passwd')
// → サンドボックスにファイルシステム隔離があれば、この呼び出しは制限される
7. リモートサンドボックス設定
(1) リモートサンドボックスアーキテクチャ
graph TB
DSH[DSH Agent] -->|HTTP API| API[Sandbox API Server]
API -->|manages| CONTAINER1[Container 1<br/>Agent A]
API -->|manages| CONTAINER2[Container 2<br/>Agent B]
CONTAINER1 --> FS1[Isolated filesystem 1]
CONTAINER2 --> FS2[Isolated filesystem 2]
(2) リモートサンドボックスの設定
# dsh.config.yaml
sandbox:
backend:remote
config:
endpoint:http://sandbox-server:8080
apiKey:sk-sandbox-xxx
defaultImage:dsh-sandbox:latest
maxContainers:10
containerTimeout:3600
allowedImages:
- dsh-sandbox:latest
- dsh-sandbox-python:latest
(3) リモートサンドボックスバックエンドの実装
export default class RemoteSandboxBackend extends Service {
private endpoint:string
private apiKey:string
constructor(ctx:Context) {
super(ctx, 'sandbox')
this.endpoint = ctx.config.endpoint
this.apiKey = ctx.config.apiKey
}
async execute(command:string, options:ShellOptions):Promise<ShellResult> {
const response = await fetch(`${this.endpoint}/execute`, {
method:'POST',
headers:{
'Content-Type':'application/json',
'Authorization':`Bearer ${this.apiKey}`
},
body:JSON.stringify({ command, ...options })
})
return await response.json()
}
async readFile(path:string):Promise<string> {
const response = await fetch(`${this.endpoint}/read`, {
method:'POST',
headers:{ 'Authorization':`Bearer ${this.apiKey}` },
body:JSON.stringify({ path })
})
const data = await response.json()
return data.content
}
// ...
}
(4) サンドボックスのライフサイクル
1. Agent セッション作成 → サンドボックスコンテナをリクエスト
2. Sandbox API がコンテナ作成 → コンテナ ID を返却
3. Agent の操作がコンテナ内で実行
4. Agent セッション破棄 → コンテナ破棄をリクエスト
5. Sandbox API がコンテナ破棄 → リソース解放
❓ よくある質問
--preset trusted を使用するとほとんどの操作が自動許可されます。ただし本番環境では推奨されません。📖 まとめ
- 承認ポリシー4モード:always/ask/ask_with_confirm/deny
- パーミッションプリセット:trusted(自動許可)、standard(承認必要)、restricted(厳格承認)
- 承認ポップアップは Agent 実行を一時停止し、ユーザーの決定を待つ
- サンドボックスバックエンドは SandboxCapability インターフェースで登録、Docker/リモート/カスタム実装をサポート
- ctx.sandbox と ctx.shell はサンドボックス内で操作を実行、ホストシステムから隔離
- リモートサンドボックスは HTTP API で管理、マルチコンテナ隔離をサポート
📝 練習問題
1. ⭐ 基礎:DSH を standard プリセットで設定し、Agent に ls(自動許可)と rm(承認必要)を実行させ、承認ポップアップの動作を観察。
2. ⭐⭐ 応用:カスタムツールに承認ルールを追加——SELECT クエリは自動許可、INSERT/UPDATE/DELETE は承認必要、DROP は自動拒否。各 SQL タイプの承認動作をテスト。
3. ⭐⭐⭐ チャレンジ:シンプルなサンドボックスバックエンド(サブプロセス隔離を使用)を実装し、DSH に登録してください。Agent にサンドボックス内でコマンドを実行させ、以下を確認:1) ファイル操作がサンドボックスディレクトリに制限される;2) ネットワークリクエストがブロックされる;3) サンドボックス破棄後のファイルクリーンアップ。