rshell

module
v0.0.21 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 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 in read-only mode (exit code 2 for other targets); file-target redirects enabled in remediation mode, gated by AllowedPaths >/dev/null, 2>/dev/null, &>/dev/null, 2>&1; in remediation mode: >FILE, >>FILE, 2>FILE, &>FILE, &>>FILE

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).

  • Sandbox mechanism: Both reads and writes go through the same openat-based sandbox, making it immune to symlink traversal, TOCTOU races, and .. escape attacks. Files outside the allowlist cannot be opened, created, truncated, or appended to.
  • Symlink policy: A symlink pointing outside its os.Root is followed for reads but never for writes, eliminating the TOCTOU window where a malicious link target could be swapped between resolution and open.
  • Output redirections by mode:
    • Read-only mode (default): file-target output redirections (>, >>, 2>, &>, &>>) are rejected at parse time (exit 2).
    • Remediation mode: those redirections open through the same sandbox — writes inside the allowlist succeed; targets outside fail with permission denied (exit 1).
  • Special targets: The literal target /dev/null is always short-circuited to a discarded sink without going through the sandbox. <> (read-write open) is blocked in all modes.
  • Diagnostic messages: Configured directories that cannot be opened (missing, not a directory, no permission) are skipped with a warning flushed once to the runner's stderr at construction time. Silence them or redirect them programmatically with WarningsWriter(io.Writer) or Runner.Warnings().

Note: The ss, ip route, and df builtins bypass AllowedPaths for their kernel-state reads. ss and ip route open /proc/net/* paths directly; df reads /proc/self/mountinfo (Linux) or calls getfsstat(2) (macOS), then issues unix.Statfs(2) against every kernel-reported mount point. These paths are hardcoded — never derived from user input — and Statfs returns metadata only (block / inode counts, filesystem type, block size). There is no sandbox-escape risk, but operators cannot use AllowedPaths to block ss from enumerating local sockets, ip route from reading the routing table, or df from reporting mount-table capacity — 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. To avoid leaking secrets passed as CLI arguments, ps does not read /proc/<pid>/cmdline; the CMD column reports only the process comm/executable name.

RemediationMode opts the runner into host-remediation mode, enabling file-target output redirections (>, >>, 2>, &>, &>>) within the configured AllowedPaths. Targets outside the allowlist are rejected with permission denied (exit 1); /dev/null is always accepted. <> (read-write open) remains blocked in all modes. CLI flag: --mode remediation (default: --mode read-only).

Shell Features

Inside rshell, run help to list supported feature categories, a concise unsupported-feature summary, enabled commands, and the configured AllowedPaths sandbox roots (or a notice when none are configured). Use help <feature|command> for details about a specific rshell feature or command.

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

Platform Support

Linux, macOS, and Windows.

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.
cd
Package cd implements the cd builtin command.
Package cd implements the cd 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.
df
Package df implements the df builtin command.
Package df implements the df builtin command.
du
Package du implements the du builtin command.
Package du implements the du 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/diskstats
Package diskstats reads mounted-filesystem usage information from the kernel and presents it as a normalised cross-platform Mount struct.
Package diskstats reads mounted-filesystem usage information from the kernel and presents it as a normalised cross-platform Mount struct.
internal/flagparser
Package flagparser bridges between pflag and the GNU-getopt wording that rshell builtins are expected to match.
Package flagparser bridges between pflag and the GNU-getopt wording that rshell builtins are expected to match.
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.
internal/winpoll
Package winpoll provides a non-consuming readability probe for Windows file handles.
Package winpoll provides a non-consuming readability probe for Windows file handles.
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.
pwd
Package pwd implements the pwd builtin command.
Package pwd implements the pwd builtin command.
read
Package read implements the read builtin command.
Package read implements the read 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.
truncate
Package truncate implements the truncate builtin command.
Package truncate implements the truncate 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.
xargs
Package xargs implements the xargs builtin command.
Package xargs implements the xargs 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.
version
Package version exposes the build version of rshell.
Package version exposes the build version of rshell.
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