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

Safely Running Community Scrapers with Outrigger: Electric lime P1 vector CRT macro showing orbital vector loop sandboxed inside hexagonal containment cell with defensive perimeter rings

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 VectorDefault Host PrivilegeOutrigger Sandbox PolicyEnforcement Mechanism
Root FilesystemRead/Write access to diskRead-only (ro) mountDocker / OCI runtime flags
Host EnvironmentAmbient user credentials exposedEmpty environment arrayExplicit -e TARGET_DOMAIN=... only
Network AccessUnrestricted outbound WAN/LANEgress whitelisted to target domainiptables / Squid forward proxy
System CallsFull standard Linux syscallsBlocked ptrace, bpf, chrootCustom seccomp JSON filter
IPC / PIDsHost PID namespace visibilityIsolated private PID namespaceLinux 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