/ entrypoints / sandboxTypes.ts
sandboxTypes.ts
  1  /**
  2   * Sandbox types for the Claude Code Agent SDK
  3   *
  4   * This file is the single source of truth for sandbox configuration types.
  5   * Both the SDK and the settings validation import from here.
  6   */
  7  
  8  import { z } from 'zod/v4'
  9  import { lazySchema } from '../utils/lazySchema.js'
 10  
 11  /**
 12   * Network configuration schema for sandbox.
 13   */
 14  export const SandboxNetworkConfigSchema = lazySchema(() =>
 15    z
 16      .object({
 17        allowedDomains: z.array(z.string()).optional(),
 18        allowManagedDomainsOnly: z
 19          .boolean()
 20          .optional()
 21          .describe(
 22            'When true (and set in managed settings), only allowedDomains and WebFetch(domain:...) allow rules from managed settings are respected. ' +
 23              'User, project, local, and flag settings domains are ignored. Denied domains are still respected from all sources.',
 24          ),
 25        allowUnixSockets: z
 26          .array(z.string())
 27          .optional()
 28          .describe(
 29            'macOS only: Unix socket paths to allow. Ignored on Linux (seccomp cannot filter by path).',
 30          ),
 31        allowAllUnixSockets: z
 32          .boolean()
 33          .optional()
 34          .describe(
 35            'If true, allow all Unix sockets (disables blocking on both platforms).',
 36          ),
 37        allowLocalBinding: z.boolean().optional(),
 38        httpProxyPort: z.number().optional(),
 39        socksProxyPort: z.number().optional(),
 40      })
 41      .optional(),
 42  )
 43  
 44  /**
 45   * Filesystem configuration schema for sandbox.
 46   */
 47  export const SandboxFilesystemConfigSchema = lazySchema(() =>
 48    z
 49      .object({
 50        allowWrite: z
 51          .array(z.string())
 52          .optional()
 53          .describe(
 54            'Additional paths to allow writing within the sandbox. ' +
 55              'Merged with paths from Edit(...) allow permission rules.',
 56          ),
 57        denyWrite: z
 58          .array(z.string())
 59          .optional()
 60          .describe(
 61            'Additional paths to deny writing within the sandbox. ' +
 62              'Merged with paths from Edit(...) deny permission rules.',
 63          ),
 64        denyRead: z
 65          .array(z.string())
 66          .optional()
 67          .describe(
 68            'Additional paths to deny reading within the sandbox. ' +
 69              'Merged with paths from Read(...) deny permission rules.',
 70          ),
 71        allowRead: z
 72          .array(z.string())
 73          .optional()
 74          .describe(
 75            'Paths to re-allow reading within denyRead regions. ' +
 76              'Takes precedence over denyRead for matching paths.',
 77          ),
 78        allowManagedReadPathsOnly: z
 79          .boolean()
 80          .optional()
 81          .describe(
 82            'When true (set in managed settings), only allowRead paths from policySettings are used.',
 83          ),
 84      })
 85      .optional(),
 86  )
 87  
 88  /**
 89   * Sandbox settings schema.
 90   */
 91  export const SandboxSettingsSchema = lazySchema(() =>
 92    z
 93      .object({
 94        enabled: z.boolean().optional(),
 95        failIfUnavailable: z
 96          .boolean()
 97          .optional()
 98          .describe(
 99            'Exit with an error at startup if sandbox.enabled is true but the sandbox cannot start ' +
100              '(missing dependencies, unsupported platform, or platform not in enabledPlatforms). ' +
101              'When false (default), a warning is shown and commands run unsandboxed. ' +
102              'Intended for managed-settings deployments that require sandboxing as a hard gate.',
103          ),
104        // Note: enabledPlatforms is an undocumented setting read via .passthrough()
105        // It restricts sandboxing to specific platforms (e.g., ["macos"]).
106        //
107        // Added to unblock NVIDIA enterprise rollout: they want to enable
108        // autoAllowBashIfSandboxed but only on macOS initially, since Linux/WSL
109        // sandbox support is newer and less battle-tested. This allows them to
110        // set enabledPlatforms: ["macos"] to disable sandbox (and auto-allow)
111        // on other platforms until they're ready to expand.
112        autoAllowBashIfSandboxed: z.boolean().optional(),
113        allowUnsandboxedCommands: z
114          .boolean()
115          .optional()
116          .describe(
117            'Allow commands to run outside the sandbox via the dangerouslyDisableSandbox parameter. ' +
118              'When false, the dangerouslyDisableSandbox parameter is completely ignored and all commands must run sandboxed. ' +
119              'Default: true.',
120          ),
121        network: SandboxNetworkConfigSchema(),
122        filesystem: SandboxFilesystemConfigSchema(),
123        ignoreViolations: z.record(z.string(), z.array(z.string())).optional(),
124        enableWeakerNestedSandbox: z.boolean().optional(),
125        enableWeakerNetworkIsolation: z
126          .boolean()
127          .optional()
128          .describe(
129            'macOS only: Allow access to com.apple.trustd.agent in the sandbox. ' +
130              'Needed for Go-based CLI tools (gh, gcloud, terraform, etc.) to verify TLS certificates ' +
131              'when using httpProxyPort with a MITM proxy and custom CA. ' +
132              '**Reduces security** — opens a potential data exfiltration vector through the trustd service. Default: false',
133          ),
134        excludedCommands: z.array(z.string()).optional(),
135        ripgrep: z
136          .object({
137            command: z.string(),
138            args: z.array(z.string()).optional(),
139          })
140          .optional()
141          .describe('Custom ripgrep configuration for bundled ripgrep support'),
142      })
143      .passthrough(),
144  )
145  
146  // Inferred types from schemas
147  export type SandboxSettings = z.infer<ReturnType<typeof SandboxSettingsSchema>>
148  export type SandboxNetworkConfig = NonNullable<
149    z.infer<ReturnType<typeof SandboxNetworkConfigSchema>>
150  >
151  export type SandboxFilesystemConfig = NonNullable<
152    z.infer<ReturnType<typeof SandboxFilesystemConfigSchema>>
153  >
154  export type SandboxIgnoreViolations = NonNullable<
155    SandboxSettings['ignoreViolations']
156  >