第十章:安全沙箱与隔离 本章目标 :帮助你理解 dsh 的沙箱隔离机制——Landlock/Seatbelt/bwrap 三种后端、进程树隔离、权限提升(Escalation)流程、以及与 Guard 机制的配合。阅读本章后,你应该能回答"Agent 执行的命令是如何被隔离的"以及"如何配置沙箱策略"。
10.1 沙箱架构概览 10.1.1 为什么需要沙箱Agent 可能执行任意命令(Bash、文件写入、网络请求等)。沙箱确保:
最小权限 :Agent 只能访问授权的资源
故障隔离 :一个 Agent 的失败不影响其他 Agent
审计追踪 :所有操作可被记录和审查
10.1.2 架构 10.2 沙箱服务定义 10.2.1 SandboxService 接口
interface SandboxService {
confine ( command: string , options: SandboxOptions) : Promise < SandboxResult>
isAvailable ( ) : boolean
getType ( ) : SandboxType
}
type SandboxType = 'landlock' | 'seatbelt' | 'bwrap' | 'none'
interface SandboxOptions {
cwd? : string
env? : Record< string , string >
timeout? : number
restrictions: SandboxRestrictions
}
interface SandboxRestrictions {
allowedPaths? : string [ ]
deniedPaths? : string [ ]
allowedNetwork? : boolean
allowedProcessSpawn? : boolean
maxMemory? : number
maxCpuTime? : number
}
10.2.2 SandboxResult
interface SandboxResult {
exitCode: number
stdout: string
stderr: string
confined: boolean
confinementReason? : string
}
10.3 三种平台后端 10.3.1 Landlock(Linux)Landlock 是 Linux 内核提供的沙箱机制,无需 root 权限。
class LandlockSandbox implements SandboxBackend {
async createRules ( restrictions: SandboxRestrictions) : Promise < LandlockRuleset> {
const ruleset = new LandlockRuleset ( {
handledAccess: [
'file_read' ,
'file_write' ,
'file_execute' ,
'directory_read'
]
} )
for ( const path of restrictions. allowedPaths ?? [ ] ) {
ruleset. addRule ( {
type: 'path_beneath' ,
path,
access: [ 'file_read' , 'file_write' ]
} )
}
return ruleset
}
async exec ( command: string , ruleset: LandlockRuleset) : Promise < ProcessResult> {
await ruleset . apply ( )
return exec ( command)
}
}
优势 :
无需 root 权限
内核级别隔离
细粒度文件系统控制
10.3.2 Seatbelt(macOS)Seatbelt 是 macOS 的沙箱机制(sandbox-exec)。
class SeatbeltSandbox implements SandboxBackend {
generateProfile ( restrictions: SandboxRestrictions) : string {
return `
(version 1)
(allow default)
${ restrictions. deniedPaths?. map ( p => ` (deny file-read-data (regex " ${ p} ")) ` ) . join ( '\n' ) }
${ restrictions. deniedPaths?. map ( p => ` (deny file-write-data (regex " ${ p} ")) ` ) . join ( '\n' ) }
${ ! restrictions. allowedNetwork ? '(deny network*)' : '' }
`
}
async exec ( command: string , profile: string ) : Promise < ProcessResult> {
return exec ( ` sandbox-exec -f ${ profile} ${ command} ` )
}
}
优势 :
macOS 原生支持
基于 Scheme 的策略语言
细粒度权限控制
10.3.3 bwrap(Bubblewrap)Bubblewrap 是一个用户空间沙箱工具。
class BwrapSandbox implements SandboxBackend {
buildCommand ( restrictions: SandboxRestrictions) : string [ ] {
const args = [ 'bwrap' ]
for ( const path of restrictions. allowedPaths ?? [ ] ) {
args. push ( '--ro-bind' , path, path)
}
if ( ! restrictions. allowedNetwork) {
args. push ( '--unshare-net' )
}
args. push ( '--tmpfs' , '/tmp' )
args. push ( '--' , 'sh' , '-c' , command)
return args
}
}
优势 :
10.4 LocalSandboxProvider 10.4.1 实现
class LocalSandboxProvider implements SandboxProvider {
private backend: SandboxBackend
constructor ( private ctx: Context) {
this . backend = this . detectBackend ( )
}
private detectBackend ( ) : SandboxBackend {
if ( process. platform === 'linux' ) {
if ( this . isLandlockAvailable ( ) ) {
return new LandlockSandbox ( )
}
return new BwrapSandbox ( )
}
if ( process. platform === 'darwin' ) {
return new SeatbeltSandbox ( )
}
return new NoopSandbox ( )
}
async confine ( command: string , options: SandboxOptions) : Promise < SandboxResult> {
const escalation = await this . checkEscalation ( options. restrictions)
if ( ! escalation. approved) {
return { exitCode: 1 , stdout: '' , stderr: 'Permission denied' , confined: true }
}
const result = await this . backend. exec ( command, options)
await this . auditLog ( command, options, result)
return result
}
private async checkEscalation ( restrictions: SandboxRestrictions) : Promise < EscalationResult> {
if ( this . needsEscalation ( restrictions) ) {
return this . ctx. escalation. request ( {
permissions: this . getRequiredPermissions ( restrictions) ,
reason: 'Command execution requires elevated permissions' ,
risk: 'medium'
} )
}
return { approved: true , granted: [ ] }
}
}
10.5 Escalation(权限提升) 10.5.1 流程 10.5.2 EscalationApprover
interface EscalationApprover {
request ( options: EscalationRequest) : Promise < EscalationResult>
}
interface EscalationRequest {
permissions: string [ ]
reason: string
risk: 'low' | 'medium' | 'high'
}
interface EscalationResult {
approved: boolean
granted: string [ ]
}
10.5.3 权限类型
type Permission =
| 'file:read'
| 'file:write'
| 'file:execute'
| 'network:outbound'
| 'network:inbound'
| 'process:spawn'
| 'memory:unlimited'
10.6 进程树隔离 10.6.1 概念每个 Agent 的执行都在独立的进程树中,确保:
信号隔离 :一个 Agent 的 SIGTERM 不影响其他 Agent
资源隔离 :每个进程树有独立的资源限制
清理隔离 :进程树结束时,所有子进程被清理
10.6.2 进程组管理
class LocalSubprocessProvider {
async spawnGroup ( command: string , options: SpawnOptions) : Promise < RunningProcessGroup> {
const group = new ProcessGroup ( )
const mainProcess = spawn ( command, {
... options,
detached: true ,
stdio: [ 'pipe' , 'pipe' , 'pipe' ]
} )
group. add ( mainProcess)
mainProcess. on ( 'spawn' , ( child) => {
group. add ( child)
} )
return {
main: mainProcess,
group,
async kill ( signal = 'SIGTERM' ) {
group. killAll ( signal)
}
}
}
}
10.7 与 Guard 机制的配合 10.7.1 Guard 检查点 10.7.2 集成示例
async function executeWithGuardAndSandbox (
ctx: Context,
command: string ,
options: ExecutionOptions
) : Promise < ExecutionResult> {
const guardResult = await ctx. guard. check ( command, options)
if ( ! guardResult. allowed) {
return { error: guardResult. reason }
}
const sandboxResult = await ctx. sandbox. confine ( command, {
... options,
restrictions: options. restrictions
} )
await ctx. audit. log ( {
command,
options,
result: sandboxResult,
timestamp: new Date ( )
} )
return sandboxResult
}
10.8 配置 10.8.1 沙箱配置
- id : sandbox
config :
type : 'auto'
defaults :
allowedPaths :
- '/tmp'
- '/workspace'
deniedPaths :
- '/etc/shadow'
- '/root'
allowedNetwork : false
allowedProcessSpawn : true
maxMemory : 536870912
maxCpuTime : 30000
overrides :
'bash' :
allowedPaths :
- '/tmp'
- '/workspace'
- '/usr'
allowedNetwork : true
10.8.2 Escalation 配置
- id : escalation
config :
mode : 'interactive'
autoApprove :
- 'file:read'
autoDeny :
- 'network:inbound'
- 'memory:unlimited'
10.9 小结
概念 一句话解释 SandboxService 沙箱服务接口 Landlock Linux 内核级沙箱 Seatbelt macOS 沙箱机制 bwrap 用户空间沙箱工具 Escalation 权限提升审批机制 进程树隔离 每个 Agent 独立的进程树 Guard 循环卫生检查
下一步 :第十一章:Session 日志深度解析 ——深入理解 JSONL 格式、事件序列、投影算法和日志重放。