rshell

module
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2026 License: Apache-2.0

README

rshell logo

rshell - A Restricted Shell for AI Agents

CI License

A restricted shell interpreter for Go. Designed for AI agents that need to run shell commands safely.

Install

go get github.com/DataDog/rshell

Quick Start

package main

import (
	"context"
	"os"
	"strings"
	"time"

	"github.com/DataDog/rshell/interp"
	"mvdan.cc/sh/v3/syntax"
)

func main() {
	script := `echo "hello from rshell"`

	prog, _ := syntax.NewParser().Parse(strings.NewReader(script), "")

	runner, _ := interp.New(
		interp.StdIO(nil, os.Stdout, os.Stderr),
		interp.AllowedCommands([]string{"rshell:echo"}),
		interp.MaxExecutionTime(5*time.Second),
	)
	defer runner.Close()

	runner.Run(context.Background(), prog)
}

CLI usage also supports a whole-run timeout:

rshell --allow-all-commands --timeout 5s -c 'echo "hello from rshell"'

Security Model

Every access path is default-deny:

Resource Default Opt-in
Command execution All commands blocked (exit code 127) AllowedCommands with namespaced command list (e.g. rshell:cat)
External commands Blocked (exit code 127) Provide an ExecHandler
Filesystem access Blocked Configure AllowedPaths with directory list
Environment variables Empty (no host env inherited) Pass variables via the Env option
Output redirections Only /dev/null allowed (exit code 2 for other targets) >/dev/null, 2>/dev/null, &>/dev/null, 2>&1

AllowedCommands restricts which commands (builtins or external) the interpreter may execute. Commands must be specified with the rshell: namespace prefix (e.g. rshell:cat, rshell:echo). If not set, no commands are allowed.

AllowedPaths restricts all file operations to specified directories using Go's os.Root API (openat syscalls), making it immune to symlink traversal, TOCTOU races, and .. escape attacks.

Note: The ss and ip route builtins bypass AllowedPaths for their /proc/net/* reads. Both builtins open kernel pseudo-filesystem paths (e.g. /proc/net/tcp, /proc/net/route) directly with os.Open rather than going through the sandboxed opener. These paths are hardcoded in the implementation and are never derived from user input, so there is no sandbox-escape risk. However, operators cannot use AllowedPaths to block ss from enumerating local sockets or ip route from reading the routing table — these reads succeed regardless of the configured path policy.

ProcPath (Linux-only) overrides the proc filesystem root used by the ps builtin (default /proc). This is a privileged option set at runner construction time by trusted caller code — scripts cannot influence it. Access to the proc path is intentionally not subject to AllowedPaths restrictions, since proc is a read-only virtual filesystem that does not expose host data under the normal file hierarchy.

Shell Features

See SHELL_FEATURES.md for the complete list of supported and blocked features.

Platform Support

Linux, macOS, and Windows.

Testing

900+ YAML-driven test scenarios cover builtins, shell features, and security restrictions.

tests/scenarios/
├── cmd/          # builtin command tests (echo, cat, grep, head, tail, test, uniq, wc, ...)
└── shell/        # shell feature tests (pipes, variables, control flow, ...)

By default, each scenario is executed twice: once in rshell and once in a real bash shell, ensuring output parity with POSIX behavior. Scenarios that test rshell-specific restrictions (blocked commands, readonly enforcement, etc.) opt out of the bash comparison.

go test ./...

Publishing Changes

After merging changes to main create a release by:

  1. Navigate to the Releases page

  2. Click "Draft a new release"

  3. You can "Select a tag" using the dropdown or "Create a new tag"

    When creating a new tag, make sure to include the v prefix. For example, if the last release was v0.1.29, your release should be v0.1.30.

  4. The release title should be the same as the version tag

  5. Use "Generate release notes" to fill in the release description

  6. Click "Publish release"

    This will create a git tag that can now be referenced in other repos. This will trigger go-releaser that will add installable artifacts to the release.

License

Apache License 2.0

Directories

Path Synopsis
Package allowedpaths implements a filesystem sandbox that restricts access to a set of allowed directories using os.Root (Go 1.24+).
Package allowedpaths implements a filesystem sandbox that restricts access to a set of allowed directories using os.Root (Go 1.24+).
Package analysis provides a go/analysis.Analyzer that enforces symbol-level import restrictions on Go source files.
Package analysis provides a go/analysis.Analyzer that enforces symbol-level import restrictions on Go source files.
break
Package breakcmd implements the break builtin command.
Package breakcmd implements the break builtin command.
cat
Package cat implements the cat builtin command.
Package cat implements the cat builtin command.
continue
Package continuecmd implements the continue builtin command.
Package continuecmd implements the continue builtin command.
cut
Package cut implements the cut builtin command.
Package cut implements the cut builtin command.
echo
Package echo implements the echo builtin command.
Package echo implements the echo builtin command.
exit
Package exit implements the exit builtin command.
Package exit implements the exit builtin command.
false
Package falsecmd implements the false builtin command.
Package falsecmd implements the false builtin command.
find
Package find implements the find builtin command.
Package find implements the find builtin command.
grep
Package grep implements the grep builtin command.
Package grep implements the grep builtin command.
head
Package head implements the head builtin command.
Package head implements the head builtin command.
help
Package help implements the help builtin command.
Package help implements the help builtin command.
internal/procinfo
Package procinfo provides OS-specific process information for the ps builtin.
Package procinfo provides OS-specific process information for the ps builtin.
internal/procnetroute
Package procnetroute reads the Linux IPv4 routing table from /proc/net/route.
Package procnetroute reads the Linux IPv4 routing table from /proc/net/route.
internal/procnetsocket
Package procnetsocket reads Linux socket state from /proc/net/.
Package procnetsocket reads Linux socket state from /proc/net/.
internal/procpath
Package procpath provides the single canonical default path to the Linux proc filesystem.
Package procpath provides the single canonical default path to the Linux proc filesystem.
internal/procsyskernel
Package procsyskernel reads Linux kernel information from /proc/sys/kernel/.
Package procsyskernel reads Linux kernel information from /proc/sys/kernel/.
internal/winnet
Package winnet provides socket enumeration for Windows via iphlpapi.dll.
Package winnet provides socket enumeration for Windows via iphlpapi.dll.
ip
Package ip implements the ip builtin command.
Package ip implements the ip builtin command.
ls
Package ls implements the ls builtin command.
Package ls implements the ls builtin command.
ping
Package ping implements the ping builtin command.
Package ping implements the ping builtin command.
printf
Package printf implements the printf builtin command.
Package printf implements the printf builtin command.
ps
Package ps implements the ps builtin command.
Package ps implements the ps builtin command.
sed
Package sed implements the sed builtin command.
Package sed implements the sed builtin command.
sort
Package sort implements the sort builtin command.
Package sort implements the sort builtin command.
ss
Package ss implements the ss builtin command.
Package ss implements the ss builtin command.
strings_cmd
Package strings_cmd implements the strings builtin command.
Package strings_cmd implements the strings builtin command.
tail
Package tail implements the tail builtin command.
Package tail implements the tail builtin command.
testcmd
Package testcmd implements the POSIX test and [ builtin commands.
Package testcmd implements the POSIX test and [ builtin commands.
testutil
Package testutil provides shared test helpers for builtin command tests.
Package testutil provides shared test helpers for builtin command tests.
tr
Package tr implements the tr builtin command.
Package tr implements the tr builtin command.
true
Package truecmd implements the true builtin command.
Package truecmd implements the true builtin command.
uname
Package uname implements the uname builtin command.
Package uname implements the uname builtin command.
uniq
Package uniq implements the uniq builtin command.
Package uniq implements the uniq builtin command.
wc
Package wc implements the wc builtin command.
Package wc implements the wc builtin command.
cmd
rshell command
Package main provides the rshell CLI — a restricted shell interpreter.
Package main provides the rshell CLI — a restricted shell interpreter.
internal
interpoption
Package interpoption provides internal-only interpreter options that are not part of the public API.
Package interpoption provides internal-only interpreter options that are not part of the public API.
Package interp implements a restricted shell interpreter designed for safe, sandboxed execution.
Package interp implements a restricted shell interpreter designed for safe, sandboxed execution.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL