Observe file, network, and process capabilities used while installing or requiring Ruby gems.
Features · Installation · Quick Start · Commands · How It Works
Bonebed uses Linux seccomp user notifications to observe the files, network addresses, external commands, and thread creation syscalls touched by a Ruby gem. It subtracts normal Ruby and Bundler startup activity, then writes the remaining observations to a JSON capability manifest.
Warning
Bonebed is an observation tool, not a security boundary. Pointer arguments can change between inspection and syscall continuation (TOCTOU), so the manifest describes what was observed rather than guaranteeing what happened.
- Profile both
gem installandrequire - Observe
open/openat,connect,execve,clone, andclone3calls - Subtract cached Ruby and Bundler startup baselines
- Normalize project, home, gem, and temporary paths for comparable manifests
- Survey RubyGems rankings, gem lists, or Bundler lockfiles with resumable results
- Summarize failures, project file access, and commands by survey target as Markdown
Install Bonebed from RubyGems:
gem install bonebed- Linux 5.5 or newer on x86_64 or aarch64
- Ruby 3.2 or newer
- Permission to install a seccomp user-notification filter
Docker must run with --security-opt seccomp=unconfined. Bonebed does not run directly on macOS; use the included development container instead.
Run Bonebed in its Linux development container so the gem under observation is not executed directly on the host:
docker build -f Dockerfile.dev -t bonebed-dev .
bin/dev bundle install
bin/dev bundle exec exe/bonebed doctor
bin/dev bundle exec exe/bonebed dig jsonThe manifest is written to results/. The first observation also caches a matching startup baseline in .bonebed/baselines/.
| Command | Purpose |
|---|---|
bonebed doctor |
Check kernel, architecture, seccomp, and container support |
bonebed baseline [--refresh] |
Create or refresh the startup baseline |
bonebed dig GEM |
Observe a gem while it is required with only its runtime dependency closure visible; common load paths are inferred, or use --require PATH |
bonebed dig GEM --phase install |
Install and observe a gem in disposable home and gem directories |
bonebed survey --top N |
Observe up to 100 gems from RubyGems.org's all-time ranking |
bonebed survey --file FILE |
Observe gems listed as `NAME [VERSION |
bonebed survey --gemfile Gemfile.lock |
Observe gems from a Bundler lockfile |
bonebed report results --format md |
Summarize collected manifests as Markdown |
Use --offline with dig or survey to return ENETUNREACH for observed connections. This is a compatibility check, not a security sandbox. Existing successful survey results are skipped and failures are retried, so interrupted surveys can resume. Each survey entry runs in a fresh worker process so its memory and operating-system resources are released; a killed worker is recorded and the survey continues. A survey finishes every entry but exits with status 1 if any observation fails.
Use sinatra - sinatra/base in a survey file to set a require path without pinning a version. Require paths are ignored during install surveys.
dig still writes its manifest but exits with status 1 when the observed command fails.
- A seccomp filter sends
open/openat,connect,execve,clone, andclone3notifications to Bonebed. - Bonebed decodes and records each call, then allows it to continue unless offline mode rejects a connection.
- A matching empty-Ruby observation is subtracted as startup noise. Failed read probes for nonexistent paths are discarded; write and network attempts are retained because a notification arrives before the kernel result is known.
- Target stdout and stderr are streamed while the remaining file paths, network endpoints, commands, thread creation calls, installed gems, counts, timing, errors, and output are written as JSON. Relative paths are resolved from the target process and project paths are normalized to
$PWD; routine RubyGems cache writes stay in the file list but are excluded fromnotable.
Captured output is stored as UTF-8; invalid byte sequences are replaced so binary output cannot prevent manifest creation. Reports show network attempts by target and output emitted by successful require targets. Failure reports keep compact output previews in the table and the complete output in a folded section.
Implementation notes and measured notification overhead are recorded in NOTES.md.
bin/dev bundle exec rake
bin/dev bundle exec exe/bonebed doctorThe development image includes strace for cross-checking noteworthy observations.
Bug reports and pull requests are welcome at github.com/ydah/bonebed.
Bonebed is available as open source under the terms of the MIT License.