Skip to content

Add lightweight OS-level sandboxing for tool execution via sandlock #5150

@congwang-mk

Description

@congwang-mk

Problem

CrewAI's code execution tools have multiple unsandboxed pathways:

  • CodeInterpreterTool unsafe mode: exec() and os.system(f"pip install {library}") with no restrictions
  • SandboxPython: the code itself documents that it "does NOT provide real security isolation and is vulnerable to sandbox escape attacks via Python object introspection"
  • Template eval(): crewai create ships a Calculator example using eval(expression) on unsanitized LLM input ([Security] crewai create ships template with eval() on unsanitized LLM input #5056)
  • No framework-level sandboxing: tools run in the host process by default

Docker isolation via CodeInterpreterTool is available but optional and adds ~200ms+ startup overhead per execution. When Docker is unavailable, there is no fallback with real isolation.

Proposal

Add sandlock as a lightweight sandboxing backend for tool execution. Sandlock is a Linux process sandbox using Landlock, seccomp-bpf, and user namespaces.

What sandlock provides

Layer Protection
Landlock Filesystem path whitelisting (read-only / read-write), network domain + port restrictions
seccomp-bpf Syscall filtering at kernel level: blocks ptrace, mount, unshare, kexec_load, bpf, etc.
User namespaces Privilege escalation prevention without root
Resource limits Memory, process count, CPU, open file caps (no cgroups needed)

Why this fits CrewAI

  • ~20ms startup vs ~200ms for Docker. Viable as a default, not just an opt-in.
  • No root, no daemon. Unlike Docker, just pip install sandlock.
  • Kernel-enforced. Python object introspection escapes (the acknowledged weakness of SandboxPython) are irrelevant when seccomp blocks dangerous syscalls at the kernel level. Even if eval() reaches os.system(), the syscall is denied.
  • Self-hosted. No cloud account needed.
  • Fallback when Docker is unavailable. Sandlock could serve as the middle ground between "no isolation" and "full Docker container."
  • Linux primary. Works on CrewAI's Linux deployments; macOS/Windows users can continue using Docker.

Integration points

  1. CodeInterpreterTool: add sandlock as an execution backend alongside docker and unsafe
  2. Tool execution framework: wrap tool calls in a sandbox with per-tool filesystem + network policy
  3. CLI scaffolding: default new projects to sandboxed execution instead of shipping eval() examples

Example usage

from crewai_tools import CodeInterpreterTool

# Sandlock as execution backend (between Docker and unsafe mode)
tool = CodeInterpreterTool(
    execution_backend="sandlock",
    sandbox_fs_read=["/usr/lib/python3", "/workspace"],
    sandbox_fs_write=["/workspace/output"],
    sandbox_max_memory_mb=512,
)

Relation to existing issues

Alternatives considered

  • Hardening SandboxPython: acknowledged by maintainers as not viable (Python introspection is too powerful)
  • Docker-only: adds overhead and complexity; not available in all environments
  • firejail: requires root or setuid binary
  • bubblewrap (bwrap): lower-level, no Python API, no resource limits without cgroups

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions