Skip to content
26 changes: 12 additions & 14 deletions docs/src/content/docs/reference/frontmatter-full.md
Original file line number Diff line number Diff line change
Expand Up @@ -900,37 +900,35 @@ network:
# example.com itself) and ecosystem names like 'python', 'node'.

# Sandbox configuration for AI engines. Controls agent sandbox (AWF or Sandbox
# Runtime) and MCP gateway.
# Runtime) and MCP gateway.
# Note: Top-level 'sandbox: false' is not supported. Use 'sandbox.agent: false' to disable the firewall.
# (optional)
# This field supports multiple formats (oneOf):

# Option 1: Set to false to completely disable sandbox features (firewall and
# gateway). Warning: This removes important security protections and should only
# be used in controlled environments. Not allowed in strict mode.
sandbox: true
# Option 1: Legacy string format for sandbox type: 'awf' for Agent Workflow
# Firewall (default), 'srt' for Anthropic Sandbox Runtime
sandbox: "awf"

# Option 2: Legacy string format for sandbox type: 'default' for no sandbox,
# 'sandbox-runtime' or 'srt' for Anthropic Sandbox Runtime, 'awf' for Agent
# Workflow Firewall
sandbox: "default"

# Option 3: Object format for full sandbox configuration with agent and mcp
# Option 2: Object format for full sandbox configuration with agent and mcp
# options
sandbox:
# Legacy sandbox type field (use agent instead)
# (optional)
type: "default"

# Agent sandbox type: 'awf' uses AWF (Agent Workflow Firewall), 'srt' uses
# Anthropic Sandbox Runtime. Defaults to 'awf' if not specified.
# Anthropic Sandbox Runtime. Set to false to disable the firewall. Defaults to 'awf' if not specified.
# (optional)
# This field supports multiple formats (oneOf):

# Option 1: Sandbox type: 'awf' for Agent Workflow Firewall, 'srt' for Sandbox
# Option 1: Disable the AWF firewall
agent: false

# Option 2: Sandbox type: 'awf' for Agent Workflow Firewall, 'srt' for Sandbox
# Runtime
agent: "awf"

# Option 2: Custom sandbox runtime configuration
# Option 3: Custom sandbox runtime configuration
agent:
# Agent identifier (replaces 'type' field in new format): 'awf' for Agent Workflow
# Firewall, 'srt' for Sandbox Runtime
Expand Down
11 changes: 6 additions & 5 deletions pkg/parser/schemas/main_workflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2154,10 +2154,6 @@
"sandbox": {
"description": "Sandbox configuration for AI engines. Controls agent sandbox (AWF or Sandbox Runtime) and MCP gateway.",
"oneOf": [
{
"type": "boolean",
"description": "Set to false to completely disable sandbox features (firewall and gateway). Warning: This removes important security protections and should only be used in controlled environments. Not allowed in strict mode."
},
{
"type": "string",
"enum": ["default", "sandbox-runtime", "awf", "srt"],
Expand All @@ -2173,9 +2169,14 @@
"description": "Legacy sandbox type field (use agent instead)"
},
"agent": {
"description": "Agent sandbox type: 'awf' uses AWF (Agent Workflow Firewall), 'srt' uses Anthropic Sandbox Runtime. Defaults to 'awf' if not specified.",
"description": "Agent sandbox type: 'awf' uses AWF (Agent Workflow Firewall), 'srt' uses Anthropic Sandbox Runtime. Set to false to disable the firewall. Defaults to 'awf' if not specified.",
"default": "awf",
"oneOf": [
{
"type": "boolean",
"const": false,
"description": "Set to false to disable the AWF firewall (sandbox.agent: false)"
},
{
"type": "string",
"enum": ["awf", "srt"],
Expand Down
5 changes: 5 additions & 0 deletions pkg/workflow/compiler_orchestrator_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ func (c *Compiler) ParseWorkflowFile(markdownPath string) (*WorkflowData, error)
return nil, err
}

// Validate unsupported sandbox syntaxes early
if err := validateUnsupportedSandboxSyntax(parseResult.frontmatterResult.Frontmatter); err != nil {
return nil, err
}

// Handle shared workflows
if parseResult.isSharedWorkflow {
return nil, &SharedWorkflowError{Path: parseResult.cleanPath}
Expand Down
52 changes: 52 additions & 0 deletions pkg/workflow/sandbox_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,58 @@ import (

var sandboxValidationLog = logger.New("workflow:sandbox_validation")

// validateUnsupportedSandboxSyntax validates that unsupported sandbox syntaxes are not used
// This function only rejects:
// - sandbox: false (top-level boolean false)
// - sandbox.gateway: false (gateway cannot be disabled)
// - sandbox.mcp: false (MCP gateway cannot be disabled)
// Note: sandbox.agent: false IS SUPPORTED and disables the AWF firewall
func validateUnsupportedSandboxSyntax(frontmatter map[string]any) error {
sandbox, exists := frontmatter["sandbox"]
if !exists {
return nil
}

// Check for sandbox: false (top-level boolean false is NOT supported)
if sandboxBool, ok := sandbox.(bool); ok && !sandboxBool {
return NewConfigurationError(
"sandbox",
"false",
"'sandbox: false' (top-level) is not supported. Use 'sandbox.agent: false' to disable the firewall instead.",
"Replace 'sandbox: false' with:\nsandbox:\n agent: false # Disables AWF firewall",
)
}

// Check for sandbox.gateway: false or sandbox.mcp: false (MCP gateway cannot be disabled)
if sandboxObj, ok := sandbox.(map[string]any); ok {
// Check for sandbox.gateway: false (this field doesn't exist, but users might try it)
if gatewayVal, hasGateway := sandboxObj["gateway"]; hasGateway {
if gatewayBool, ok := gatewayVal.(bool); ok && !gatewayBool {
return NewConfigurationError(
"sandbox.gateway",
"false",
"'sandbox.gateway: false' is not supported. The MCP gateway cannot be disabled.",
"Remove the 'sandbox.gateway: false' line. The MCP gateway is automatically configured.",
)
}
}

// Check for sandbox.mcp: false (MCP gateway cannot be disabled)
if mcpVal, hasMCP := sandboxObj["mcp"]; hasMCP {
if mcpBool, ok := mcpVal.(bool); ok && !mcpBool {
return NewConfigurationError(
"sandbox.mcp",
"false",
"'sandbox.mcp: false' is not supported. The MCP gateway cannot be disabled.",
"Remove the 'sandbox.mcp: false' line. The MCP gateway is automatically configured.",
)
}
}
}

return nil
}

// validateMountsSyntax validates that mount strings follow the correct syntax
// Expected format: "source:destination:mode" where mode is either "ro" or "rw"
func validateMountsSyntax(mounts []string) error {
Expand Down
Loading