A virtual jailed shell environment for Go apps backed by a virtual filesystem.
xeiaso.net/blog/2026/dancing-mad-sandboxing/
shell
agents
terrible-idea
sandbox
1package main
2
3import (
4 "context"
5 "errors"
6 "fmt"
7 "io/fs"
8 "log"
9 "os"
10 "strconv"
11
12 "github.com/spf13/pflag"
13 "github.com/tigrisdata/storage-go"
14 "tangled.org/xeiaso.net/kefka/s3fs"
15 "tangled.org/xeiaso.net/kefka/s3fs/unixmeta"
16
17 _ "github.com/joho/godotenv/autoload"
18)
19
20var (
21 bucket = pflag.String("bucket", os.Getenv("BUCKET_NAME"), "bucket to operate on")
22
23 fsUnixMetadata = pflag.Bool("fs-unix-metadata", false, "store/read POSIX file attributes as S3 user metadata")
24 fsUser = pflag.String("fs-user", "0", "owner (name or numeric uid) for written files")
25 fsGroup = pflag.String("fs-group", "0", "group (name or numeric gid) for written files")
26 fsUmask = pflag.String("fs-umask", "022", "octal umask applied to new files")
27)
28
29func main() {
30 pflag.Parse()
31 fmt.Println("bucket:", *bucket)
32
33 client, err := storage.New(context.Background())
34 if err != nil {
35 log.Fatal(fmt.Errorf("can't make storage client: %w", err))
36 }
37
38 var opts []s3fs.Option
39 if *fsUnixMetadata {
40 uid, err := unixmeta.LookupUID(*fsUser)
41 if err != nil {
42 log.Fatal(fmt.Errorf("--fs-user %q: %w", *fsUser, err))
43 }
44 gid, err := unixmeta.LookupGID(*fsGroup)
45 if err != nil {
46 log.Fatal(fmt.Errorf("--fs-group %q: %w", *fsGroup, err))
47 }
48 umask, err := strconv.ParseUint(*fsUmask, 8, 32)
49 if err != nil {
50 log.Fatal(fmt.Errorf("--fs-umask %q: must be octal: %w", *fsUmask, err))
51 }
52 opts = append(opts, s3fs.WithUnixMetadata(uid, gid, os.FileMode(umask)))
53 }
54
55 fsys, err := s3fs.NewS3FS(client, *bucket, opts...)
56 if err != nil {
57 panic(err)
58 }
59
60 stat := func(p string) {
61 info, err := fsys.Stat(p)
62 if err != nil {
63 fmt.Printf("Stat(%q) -> err: %v (is fs.ErrNotExist=%v)\n", p, err, errors.Is(err, fs.ErrNotExist))
64 return
65 }
66 owner := ""
67 if st, ok := info.Sys().(*s3fs.FileStat); ok {
68 owner = fmt.Sprintf(" uid=%d gid=%d", st.UID, st.GID)
69 }
70 fmt.Printf("Stat(%q) -> name=%q dir=%v mode=%s size=%d mtime=%s%s\n",
71 p, info.Name(), info.IsDir(), info.Mode(), info.Size(), info.ModTime().Format("2006-01-02T15:04:05"), owner)
72 }
73
74 readdir := func(p string) {
75 entries, err := fsys.ReadDir(p)
76 if err != nil {
77 fmt.Printf("ReadDir(%q) -> err: %v\n", p, err)
78 return
79 }
80 fmt.Printf("ReadDir(%q) -> %d entries:\n", p, len(entries))
81 for _, e := range entries {
82 fmt.Printf(" %s (dir=%v size=%d)\n", e.Name(), e.IsDir(), e.Size())
83 }
84 }
85
86 stat(".")
87 stat("etc")
88 stat("moby-dick.txt")
89 stat("etc/motd")
90 stat("does-not-exist")
91
92 readdir(".")
93 readdir("etc")
94}