Living Document Notice
Published 2026-09-18. The evolving architecture, revisions, and connected notes for this dispatch live in the Stax Digital Garden.
Safely Running Community Scrapers with Outrigger
Summary
Sandboxing third-party extractors inside Outrigger Protocol CLI runtimes with strict filesystem and network egress filters.
This technical dispatch explores the underlying architecture, data structures, and concrete implementation boundaries required for local-first data sovereignty.
The Threat Vector of Untrusted Scraper Recipes
When a user wants to liberate data from a fitness tracker, an academic portal, or an obscure banking platform, writing a custom scraper from scratch is time-consuming. Community repositories provide pre-built recipes that automate login flows, handle pagination, and parse target HTML tables.
However, executing a script downloaded from a public repository exposes the local system to critical vulnerabilities:
Attacker Script Execution Risks:
├── Environment variable harvesting (AWS_ACCESS_KEY, GITHUB_TOKEN)
├── Browser session cookie exfiltration (~/.config/google-chrome/Default/Cookies)
├── SSH private key harvesting (~/.ssh/id_rsa)
└── Malicious lateral network scanning over local subnet (192.168.1.0/24)
A malicious scraper can perform the promised data extraction while quietly reading local configuration files and transmitting private tokens to a remote endpoint. Running scrapers with standard user privileges is an unacceptable security posture.
The Outrigger Sandboxing Model
Outrigger isolates untrusted scraping execution using lightweight container primitives configured with zero-trust defaults. Instead of granting the scraper ambient access to the host workstation, Outrigger enforces strict process boundaries:
Host Workstation
┌────────────────────────────────────────────────────────┐
│ Outrigger Runner │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Ephemeral Sandbox Container │ │
│ │ ├── Read-Only Root Filesystem (/) │ │
│ │ ├── Ephemeral RAM Mount (/tmp, tmpfs 64MB) │ │
│ │ ├── Stripped Environment (No host ENV vars) │ │
│ │ ├── Seccomp Filter (Blocks ptrace, keyctl) │ │
│ │ └── Egress Proxy (Allowed domains: target-site) │ │
│ └─────────────────────────┬──────────────────────────┘ │
│ │ Output Pipe (stdout only) │
│ ┌─────────────────────────▼──────────────────────────┐ │
│ │ Host Sanitizer: Validates JSONL payload schema │ │
│ └────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────┘
The container boots from a minimal scratch image containing only the headless browser runtime and interpreter dependencies. The host user directory is never mounted into the container.
Egress Whitelisting and Network Isolation
The most critical containment barrier is restricting outbound network traffic. A scraper requires HTTP access to the specific target domain it is designed to extract, but it has no legitimate reason to establish connections to arbitrary IP addresses or local subnet hosts.
The table below details the security controls applied to each execution run:
| Isolation Vector | Default Host Privilege | Outrigger Sandbox Policy | Enforcement Mechanism |
|---|---|---|---|
| Root Filesystem | Read/Write access to disk | Read-only (ro) mount | Docker / OCI runtime flags |
| Host Environment | Ambient user credentials exposed | Empty environment array | Explicit -e TARGET_DOMAIN=... only |
| Network Access | Unrestricted outbound WAN/LAN | Egress whitelisted to target domain | iptables / Squid forward proxy |
| System Calls | Full standard Linux syscalls | Blocked ptrace, bpf, chroot | Custom seccomp JSON filter |
| IPC / PIDs | Host PID namespace visibility | Isolated private PID namespace | Linux namespace isolation |
Outrigger Execution Specification
The following execution snippet illustrates how Outrigger launches a community Python scraper inside an isolated container boundary:
# Launch Outrigger isolated sandbox run
outrigger run --name "scraper-sandbox-$(date +%s)" --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m --cap-drop ALL --security-opt no-new-privileges:true --security-opt seccomp=/etc/outrigger/seccomp-strict.json --network outrigger-isolated-net --env-file /dev/null --env TARGET_URL="https://target-service.com/records" --volume "${PWD}/output:/workspace/output:rw" community-recipe:vendor-extractor
# Verify output integrity before passing to vault
jq -e . "${PWD}/output/export.json" > /dev/null && echo "Extraction validated: JSON payload structurally sound."- Directus Target: freemydata
- Garden Source Reference: OUT-1001 - Zero Dependency Sandboxing for Autonomous Coding Agents, DAT-1005 - Digging Through Desktop App Caches, MOC - Data Liberation Workbenches, MOC - The Plain-Text Longevity Standard, MOC - Bosun PKM Tools, MOC - Outrigger Protocol