Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# log
logs/
log/
# editor config
.idea/
.vscode/
Expand All @@ -10,4 +11,6 @@ logs/
env
main

*.gen.dockerfile
*.gen.dockerfile
.menv/
coverage.out
102 changes: 102 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
version: 2

run:
timeout: 5m
tests: true
skip-dirs:
- vendor
- tests
- testdata

linters:
default: none
enable:
- govet
- errcheck
- staticcheck
- unused
- ineffassign
- misspell
- gocyclo
- goconst
- unconvert
- prealloc
- gocritic
- revive
- copyloopvar
- nilerr
- noctx
- gosec

formatters:
enable:
- goimports

linters-settings:
govet:
check-shadowing: true

errcheck:
check-type-assertions: true
check-blank: false

gocyclo:
min-complexity: 15

goconst:
min-len: 2
min-occurrences: 3

goimports:
local-prefixes: github.com/langgenius/dify-sandbox

revive:
confidence: 0.8
rules:
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: empty-block
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: redefines-builtin-id

gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style

issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
exclude:
- "cmd/test/"
exclude-rules:
- path: _test\.go
linters:
- gocyclo
- errcheck
- goconst
- govet

36 changes: 36 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-case-conflict
- id: check-merge-conflict
- id: check-json
- id: check-toml
- id: detect-private-key
- id: mixed-line-ending

- repo: https://github.com/golangci/golangci-lint
rev: v1.62.0
hooks:
- id: golangci-lint
args:
- --config=.golangci.yml
entry: golangci-lint run --fix
pass_filenames: false

- repo: local
hooks:
- id: go-test
name: go test
entry: go test -v ./...
language: system
pass_filenames: false
- id: go-mod-tidy
name: go mod tidy
entry: go mod tidy
language: system
pass_filenames: false
96 changes: 96 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.PHONY: help run test lint lint-fix fmt vet install-deps clean build pre-commit-install

# Variables
BINARY_NAME=main
GO=go
GOFLAGS=-v
DOCKER_REGISTRY=ghcr.io/agent-infra/sandbox
SANDBOX_PORT=10000

help: ## Show this help message
@echo "Usage: make [target]"
@echo ""
@echo "Available targets:"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-15s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

run: ## Run the server
@echo "Starting server..."
@$(GO) run cmd/server/main.go

build: ## Build the server binary
@echo "Building $(BINARY_NAME)..."
@$(GO) build $(GOFLAGS) -o $(BINARY_NAME) cmd/server/main.go

test: ## Run all tests
@echo "Running tests..."
@$(GO) test -v -race -coverprofile=coverage.out -covermode=atomic ./...
@$(GO) tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated: coverage.html"

test-unit: ## Run unit tests only (exclude integration tests)
@echo "Running unit tests..."
@$(GO) test -v -short ./...

test-integration: ## Run integration tests
@echo "Running integration tests..."
@$(GO) test -v ./tests/integration_tests/...

lint: ## Run golangci-lint
@echo "Running linters..."
@golangci-lint run --config=.golangci.yml

lint-fix: ## Run golangci-lint with auto-fix
@echo "Running linters with auto-fix..."
@golangci-lint run --config=.golangci.yml --fix

fmt: ## Run gofmt
@echo "Formatting code..."
@gofmt -s -w .
@$(GO) fmt ./...

vet: ## Run go vet
@echo "Running go vet..."
@$(GO) vet ./...

install-deps: ## Install development dependencies
@echo "Installing dependencies..."
@$(GO) mod download
@$(GO) mod tidy
@echo "Installing golangci-lint..."
@which golangci-lint || (go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest)
@echo "Installing pre-commit..."
@which pre-commit || (brew install pre-commit || pip install pre-commit)

pre-commit-install: ## Install pre-commit hooks
@echo "Installing pre-commit hooks..."
@pre-commit install

pre-commit-run: ## Run pre-commit hooks manually
@echo "Running pre-commit hooks..."
@pre-commit run --all-files

mod-tidy: ## Tidy go.mod
@echo "Tidying go.mod..."
@$(GO) mod tidy

mod-verify: ## Verify dependencies
@echo "Verifying dependencies..."
@$(GO) mod verify

sandbox-start: ## Start sandbox server (agent-infra/sandbox)
@echo "Starting sandbox server on port $(SANDBOX_PORT)..."
@docker run --security-opt seccomp=unconfined --rm -it -p $(SANDBOX_PORT):8080 $(DOCKER_REGISTRY):latest

sandbox-start-cn: ## Start sandbox server for China users
@echo "Starting sandbox server (China) on port $(SANDBOX_PORT)..."
@docker run --security-opt seccomp=unconfined --rm -it -p $(SANDBOX_PORT):8080 enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest

clean: ## Clean build artifacts
@echo "Cleaning..."
@rm -f $(BINARY_NAME)
@rm -f coverage.out coverage.html
@rm -rf logs/*.log

all: fmt vet lint test ## Run fmt, vet, lint and test

.DEFAULT_GOAL := help
74 changes: 66 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,78 @@
## Introduction
Dify-Sandbox offers a simple way to run untrusted code in a secure environment. It is designed to be used in a multi-tenant environment, where multiple users can submit code to be executed. The code is executed in a sandboxed environment, which restricts the resources and system calls that the code can access.

## Features
- **Multi-backend Support**: Supports both native Linux sandbox (chroot + seccomp) and agent-infra/sandbox for cross-platform isolation
- **Cross-platform**: When using agent-infra/sandbox backend, works on macOS, Linux, and Windows
- **Multiple Languages**: Supports Python 3 and Node.js code execution
- **Secure Isolation**: Hardware or OS-level isolation for secure code execution
- **Flexible Configuration**: Easy configuration via YAML file

## Use
### Requirements
DifySandbox currently only supports Linux, as it's designed for docker containers. It requires the following dependencies:

### Native Backend (Linux Only)
The native backend uses Linux chroot and seccomp for isolation.

#### Requirements
- Linux operating system
- libseccomp
- pkg-config
- gcc
- golang 1.20.6
- golang 1.25.4 or higher

### Steps
#### Steps
1. Clone the repository using `git clone https://github.com/langgenius/dify-sandbox` and navigate to the project directory.
2. Run ./install.sh to install the necessary dependencies.
3. Run ./build/build_[amd64|arm64].sh to build the sandbox binary.
4. Run ./main to start the server.
2. Run `./install.sh` to install the necessary dependencies.
3. Run `./build/build_[amd64|arm64].sh` to build the sandbox binary.
4. Edit `conf/config.yaml` and set `sandbox_backend: "native"` (default).
5. Run `./main` to start the server.

### agent-infra/sandbox Backend (Cross-platform)
The sandbox backend uses [agent-infra/sandbox](https://github.com/agent-infra/sandbox) for cross-platform isolation.

#### Requirements
- Docker
- golang 1.25.4 or higher

#### Installation
Run the sandbox server using Docker:

**Default (global):**
```bash
docker run --security-opt seccomp=unconfined --rm -it -p 10000:8080 ghcr.io/agent-infra/sandbox:latest
```

**For users in mainland China:**
```bash
docker run --security-opt seccomp=unconfined --rm -it -p 10000:8080 enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest
```

**Use a specific version** (format: `1.0.0.${version}`):
```bash
docker run --security-opt seccomp=unconfined --rm -it -p 10000:8080 ghcr.io/agent-infra/sandbox:1.0.0.150
```

Note: The command maps port 8080 in the container to port 10000 on the host to match the default configuration.

#### Configuration
Edit `conf/config.yaml`:
```yaml
# Use sandbox backend
sandbox_backend: "microsandbox"

microsandbox:
enabled: true
server_address: "http://127.0.0.1:10000" # sandbox server address
```

#### Steps
1. Clone the repository: `git clone https://github.com/langgenius/dify-sandbox`
2. Navigate to the project directory
3. Build the Go binary: `go build -o main ./cmd/server`
4. Configure `conf/config.yaml` with sandbox settings
5. Run `./main` to start the server

### Debugging
If you want to debug the server, firstly use build script to build the sandbox library binaries, then debug as you want with your IDE.


Expand All @@ -25,4 +83,4 @@ Refer to the [FAQ document](FAQ.md)


## Workflow
![workflow](workflow.png)
![workflow](workflow.png)
2 changes: 2 additions & 0 deletions cmd/lib/nodejs/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux

package main

import "github.com/langgenius/dify-sandbox/internal/core/lib/nodejs"
Expand Down
2 changes: 2 additions & 0 deletions cmd/lib/python/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux

package main

import (
Expand Down
3 changes: 3 additions & 0 deletions cmd/test/fuzz_nodejs/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build linux
// +build linux

package main

import (
Expand Down
2 changes: 2 additions & 0 deletions cmd/test/fuzz_nodejs_amd64/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux && amd64

package main

import (
Expand Down
3 changes: 3 additions & 0 deletions cmd/test/fuzz_python/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build linux
// +build linux

package main

import (
Expand Down
2 changes: 2 additions & 0 deletions cmd/test/fuzz_python_amd64/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux && amd64

package main

import (
Expand Down
2 changes: 2 additions & 0 deletions cmd/test/permission/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux

package main

import (
Expand Down
2 changes: 2 additions & 0 deletions cmd/test/python/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux

package main

import (
Expand Down
Loading
Loading