Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:54:30.835Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

bwrap_smoke_test.sh

118 lines · 5.0 KB · shellscript
1#!/usr/bin/env bash
2# Ad-hoc smoke test for the static `bwrap` binary. Exercises filesystem
3# read/write isolation and network isolation by trying to "break out" of the
4# sandbox in ways that must fail, alongside controls that must succeed.
5#
6# Usage: bwrap_smoke_test.sh /path/to/bwrap
7set -u
8
9BWRAP=${1:?usage: bwrap_smoke_test.sh /path/to/bwrap}
10
11# Resolve real binaries (works on NixOS, where /bin is mostly empty).
12CAT=$(command -v cat)
13TOUCH=$(command -v touch)
14SH=$(command -v sh)
15PY=$(command -v python3)
16
17# Bind enough of the host (read-only) for dynamically-linked helpers to run.
18# On NixOS that means the closure under /nix/store; /usr/bin elsewhere.
19BASE=(--ro-bind /nix /nix --ro-bind /run /run --proc /proc --dev /dev --unshare-user)
20[ -d /usr ] && BASE+=(--ro-bind /usr /usr)
21[ -e /bin ] && BASE+=(--ro-bind /bin /bin)
22[ -e /lib ] && BASE+=(--ro-bind /lib /lib)
23[ -e /lib64 ] && BASE+=(--ro-bind /lib64 /lib64)
24[ -e /etc ] && BASE+=(--ro-bind /etc /etc)
25
26PASS=0
27FAIL=0
28ok()   { echo "PASS: $1"; PASS=$((PASS + 1)); }
29bad()  { echo "FAIL: $1"; FAIL=$((FAIL + 1)); }
30
31# expect_ok  <desc> <cmd...>   -> command must exit 0
32expect_ok() {
33  desc=$1; shift
34  if "$@"; then ok "$desc"; else bad "$desc (expected success, got exit $?)"; fi
35}
36# expect_fail <desc> <cmd...>  -> command must exit non-zero
37expect_fail() {
38  desc=$1; shift
39  if "$@"; then bad "$desc (expected failure, but it succeeded)"; else ok "$desc"; fi
40}
41
42# ---------------------------------------------------------------------------
43# Set up a host scratch tree:
44#   $ROOT/secret/secret.txt   -> must NOT be visible unless explicitly bound
45#   $ROOT/allowed/note.txt    -> bound read-only into the sandbox
46#   $ROOT/writable/           -> bound read-write into the sandbox
47# ---------------------------------------------------------------------------
48ROOT=$(mktemp -d /tmp/bwrap-smoke.XXXXXX)
49trap 'rm -rf "$ROOT"' EXIT
50mkdir -p "$ROOT/secret" "$ROOT/allowed" "$ROOT/writable"
51echo "TOP SECRET" > "$ROOT/secret/secret.txt"
52echo "you may read me" > "$ROOT/allowed/note.txt"
53
54echo "=================================================================="
55echo "bwrap: $BWRAP"
56"$BWRAP" --version
57echo "=================================================================="
58echo "## Filesystem isolation"
59
60# The host secret must be invisible: sandbox sees a fresh tmpfs at $ROOT,
61# so the secret path simply doesn't exist.
62expect_fail "host secret file is NOT readable from sandbox" \
63  "$BWRAP" "${BASE[@]}" --tmpfs "$ROOT" "$CAT" "$ROOT/secret/secret.txt"
64
65# Likewise nothing under /tmp leaks in by default (no bind for it).
66expect_fail "host /tmp is NOT visible from sandbox" \
67  "$BWRAP" "${BASE[@]}" --tmpfs /tmp "$CAT" "$ROOT/allowed/note.txt"
68
69# An explicitly read-only bind IS readable...
70expect_ok "explicitly ro-bound file IS readable" \
71  "$BWRAP" "${BASE[@]}" --ro-bind "$ROOT/allowed" /data "$CAT" /data/note.txt
72
73# ...but writing to a read-only bind must fail.
74expect_fail "writing to a ro-bound dir is denied" \
75  "$BWRAP" "${BASE[@]}" --ro-bind "$ROOT/allowed" /data "$TOUCH" /data/evil
76
77# Confirm the host file was not modified/created behind the sandbox's back.
78expect_fail "ro-bind write did not leak to host" test -e "$ROOT/allowed/evil"
79
80# A read-write bind allows writes...
81expect_ok "writing to a rw-bound dir succeeds" \
82  "$BWRAP" "${BASE[@]}" --bind "$ROOT/writable" /data "$TOUCH" /data/hello
83
84# ...and the write really lands on the host file (proves the bind, not a tmpfs).
85expect_ok "rw-bind write is visible on host" test -e "$ROOT/writable/hello"
86
87# Writing to a tmpfs overlay succeeds inside, but must NOT touch the host dir.
88expect_ok "writing into a tmpfs works inside sandbox" \
89  "$BWRAP" "${BASE[@]}" --tmpfs "$ROOT/writable" "$TOUCH" "$ROOT/writable/ephemeral"
90expect_fail "tmpfs write did not leak to host" test -e "$ROOT/writable/ephemeral"
91
92echo "------------------------------------------------------------------"
93echo "## Network isolation"
94
95NETCHECK='import socket; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.settimeout(5); s.connect(("1.1.1.1",53)); print("connected")'
96
97# With --unshare-net the sandbox has only loopback: outbound TCP must fail.
98expect_fail "outbound TCP is blocked with --unshare-net" \
99  "$BWRAP" "${BASE[@]}" --unshare-net "$PY" -c "$NETCHECK"
100
101# Loopback still exists inside the isolated netns.
102expect_ok "loopback is up inside --unshare-net" \
103  "$BWRAP" "${BASE[@]}" --unshare-net "$PY" -c \
104    'import socket; socket.socket().bind(("127.0.0.1",0)); print("lo ok")'
105
106# Without --unshare-net the host network is shared, so the same connect works
107# (skipped automatically if the host itself has no outbound connectivity).
108if timeout 6 "$PY" -c "$NETCHECK" >/dev/null 2>&1; then
109  expect_ok "outbound TCP works when network is shared" \
110    "$BWRAP" "${BASE[@]}" "$PY" -c "$NETCHECK"
111else
112  echo "SKIP: host has no outbound TCP; cannot test shared-network case"
113fi
114
115echo "=================================================================="
116echo "Summary: $PASS passed, $FAIL failed"
117[ "$FAIL" -eq 0 ]
118
Served at tenant.openagents/omega Member data and write actions are omitted.