/** * Internal platform-profile builders for the local sandbox provider. * * @module @deepseek-ai/dsh-sandbox-local/profiles */ import { realpathSync } from 'node:fs' import { tmpdir } from 'node:os' import { grantArgs as landlockGrantArgs } from 'node-addon-landlock-run' import type { SandboxPolicy } from '@deepseek-ai/dsh-sandbox' /** * Build the bwrap profile arguments for one file-effect policy. * @param policy - file-effect policy to express as bwrap mounts. * @returns profile arguments before the trailing separator and command argv. */ export function bwrapProfileArgs(policy: SandboxPolicy): string[] { const args = ['--ro-bind', '/', '/', '--dev', '/dev', '--proc', '/proc', '--die-with-parent'] if (policy.mode === 'workspace-write') { args.push('--tmpfs', '/tmp') args.push('--bind', policy.workspaceRoot, policy.workspaceRoot) } return args } /** * Build the Landlock launcher grants for one file-effect policy. * @param policy - file-effect policy to express as Landlock allow-list grants. * @returns launcher grant arguments before the trailing separator and command argv. */ export function landlockProfileArgs(policy: SandboxPolicy): string[] { const readWrite = ['/dev/null'] if (policy.mode === 'workspace-write') { readWrite.push('/tmp', policy.workspaceRoot) } return landlockGrantArgs({ readOnly: ['/'], readWrite }) } /** Resolve a granted root to the canonical path the Seatbelt kernel sees. */ function canonicalPath(path: string): string { try { return realpathSync(path) } catch { // Missing or unreadable roots stay as spelled; an unresolved root grants // nothing until it exists, which is the conservative outcome. return path } } /** Quote one path as an SBPL string literal. */ function sbplString(path: string): string { return `"${path.replaceAll('\\', String.raw`\\`).replaceAll('"', String.raw`\"`)}"` } /** * Build the sandbox-exec arguments and SBPL profile for one policy. * @param policy - file-effect policy to express as an SBPL profile. * @returns sandbox-exec arguments before the trailing separator and command argv. */ export function seatbeltProfileArgs(policy: SandboxPolicy): string[] { const forms = ['(version 1)', '(allow default)', '(deny file-write*)', `(allow file-write* (literal ${sbplString('/dev/null')}))`] if (policy.mode === 'workspace-write') { const roots = [...new Set([policy.workspaceRoot, '/tmp', tmpdir()].map(canonicalPath))] forms.push(`(allow file-write* ${roots.map(root => `(subpath ${sbplString(root)})`).join(' ')})`) } return ['-p', forms.join(' ')] }