Skip to content
GitHubOpen source
Product
Docs
Solutions
IndustriesAll industries
CompareCompare all AI data-leak tools
Benchmarks
GitHubApache-2.0

Installation

Shadow is a single static binary called shadow. It has no runtime dependencies: no OpenSSL, no Python, no Node. Building from source needs Rust 1.88 or newer.

Terminal window
curl -fsSL https://raw.githubusercontent.com/Tiny-Bubble-Company/shadow/main/packaging/install.sh | sh

The script:

  1. detects your platform (aarch64 or x86_64, apple-darwin or unknown-linux-gnu);
  2. downloads shadow-<target>.tar.gz from the latest GitHub release if one exists, otherwise builds from source with cargo install;
  3. installs the binary to ~/.local/bin/shadow (override with SHADOW_BIN_DIR);
  4. runs shadow init to create the persona, vault key and CA.

It never changes system settings. That is what shadow install --apply is for.

Terminal window
cargo install --locked --git https://github.com/Tiny-Bubble-Company/shadow shadow-cli
shadow init

Or from a clone:

Terminal window
git clone https://github.com/Tiny-Bubble-Company/shadow
cd shadow
cargo build --release -p shadow-cli
./target/release/shadow --version

The repository ships a two-stage Dockerfile that builds Shadow and runs it as an unprivileged user (UID 10001) with its data in /data.

Terminal window
docker build -f packaging/Dockerfile -t shadow .
docker run -d --name shadow \
-p 127.0.0.1:8877:8877 \
-v shadow-data:/data \
shadow

The container runs shadow run --listen 0.0.0.0:8877, has a health check based on shadow status --quiet, and keeps the persona, vault and CA in the /data volume. Keep that volume: it holds the mapping needed to restore responses. See Docker and Kubernetes for sidecar patterns.

shadow install sets Shadow up to start at login and trusts the local CA. It is a dry run by default: it prints every file it would write and every command it would run. Add --apply to perform the steps.

Terminal window
shadow install # show the plan
shadow install --apply # do it

What it does per platform:

PlatformServiceCA trust
macOSLaunchAgent ~/Library/LaunchAgents/dev.shadow.proxy.plist, loaded with launchctl bootstrap gui/<uid>security add-trusted-cert -r trustRoot into your login keychain
Linuxsystemd user unit ~/.config/systemd/user/shadow.service, systemctl --user enable --nowCopies the CA to /usr/local/share/ca-certificates and runs update-ca-certificates (Debian, Ubuntu), or to /etc/pki/ca-trust/source/anchors and runs update-ca-trust (Fedora, RHEL). Uses sudo.
WindowsScheduled Task Shadow that runs at logon with limited rightscertutil -user -addstore Root; also sets SHADOW_HOME for your user

With --apply, it also writes env.sh (or env.ps1 on Windows) to the data directory with the proxy variables for your shell profile.

To remove everything:

Terminal window
shadow uninstall # dry run
shadow uninstall --apply

The systemd unit is hardened (NoNewPrivileges, ProtectSystem=strict, write access only to the data directory). For a system-wide server install, copy packaging/linux/shadow.service to /etc/systemd/system/, add a User= line and point SHADOW_HOME at a directory that user owns. On Windows, packaging/windows/install-service.ps1 registers the same Scheduled Task from PowerShell; wrap shadow.exe run with NSSM or WinSW if you need a machine-wide Windows service.

Everything Shadow keeps lives in one directory:

OSDefault
macOS~/Library/Application Support/shadow
Linux~/.local/share/shadow
Windows%APPDATA%\shadow

Override it with SHADOW_HOME, --data-dir, or data_dir in shadow.toml.

FileContents
shadow.tomlConfiguration (reference)
persona.jsonThe fake identity of this machine
vault.binEncrypted real↔fake mapping
vault.key32-byte vault key, mode 0600
terms.jsonTerms added with shadow terms add
ca/ca.pem, ca/ca.keyLocal CA certificate and key (0600)
ca/bundle.pemSystem roots plus the Shadow CA, for runtimes that replace their trust store
Terminal window
shadow --version
shadow status

shadow status reports whether the proxy answers on its listen address, the persona, the vault size, the CA fingerprint, whether the model detector is on, and whether an upstream proxy is configured.

  • NER sidecar. Open-weight models (OpenAI Privacy Filter and GLiNER) or a small trainable PyTorch model in ml/ that find free-text names and addresses. See Detection.
  • Presidio. Microsoft’s PII analyzer as an extra detector. See Detection.