Workflow tool script sandbox does not expose globalThis.crypto

Open 💬 0 comments Opened Jul 4, 2026 by csmedeiros

Description

The Workflow tool executes workflow scripts inside a restricted JS context (stack trace shows vm.runInContext, via Bun). That context does not expose globalThis.crypto at all, even though crypto is fully available in a normal Bun process on the same machine.

Environment

  • Claude Code version: 2.1.201 (also latest on npm: @anthropic-ai/claude-code@2.1.201)
  • Bun version: 1.3.13
  • OS: macOS (Darwin 25.4.0)

Reproduction

Outside the sandbox, in a plain Bun process:

$ bun -e 'console.log(typeof globalThis.crypto, typeof globalThis.crypto?.randomUUID)'
object function

Inside a Workflow script (via the Workflow tool), a minimal probe script:

export const meta = { name: 'crypto-probe', description: 'probe', phases: [{ title: 'Probe' }] }
phase('Probe')
const g = globalThis
log(JSON.stringify({
  hasCrypto: typeof g.crypto,
  hasRandomUUID: typeof g.crypto?.randomUUID,
  hasGetRandomValues: typeof g.crypto?.getRandomValues,
}))
return {}

returns:

{"hasCrypto":"undefined","hasRandomUUID":"undefined","hasGetRandomValues":"undefined"}

Impact

Any workflow script that needs a cryptographically secure nonce/UUID (e.g. to build an unforgeable fence delimiter around untrusted text before handing it to a subagent — a legitimate anti-prompt-injection pattern) cannot get one inside the sandbox. A script that correctly fails closed rather than falling back to a predictable/deterministic nonce (the secure choice, since a predictable delimiter is forgeable by attacker-controlled content) will always throw:

Error: <name>: crypto API unavailable; cannot generate a secure nonce for the prompt fence.
    at _nonce (workflow.js:30:9)
    at <anonymous> (workflow.js:32:17)
    at workflow.js:148:1275
    at runInContext (native)

This makes the Workflow tool unusable for any script relying on this (correct, security-motivated) pattern, on this environment/version.

Expected behavior

The workflow script sandbox should expose globalThis.crypto (at least randomUUID and getRandomValues), matching what's available in a normal Bun process, so scripts can generate secure nonces/UUIDs without a security regression as the only workaround.

View original on GitHub ↗