Problem
You're deploying into an airgapped network. The curl | bash installer needs internet, the Python scanner SDKs pull from PyPI, the OTel exporters want to reach SaaS endpoints. None of that is available to you.
Solution
DefenseClaw is airgap-friendly by design: binaries are statically linked, scanners are optional, and the default sinks write to local disk. This is the operator checklist.
Step 1: Build or download artifacts on an internet host
# on an internet-connected host
make dist
# artifacts land in dist/
Copy into the airgap:
dist/defenseclaw-<ver>-linux-amd64.tar.gzdist/defenseclaw-<ver>.whldist/defenseclaw-plugin-<ver>.tgz- SHA-256 sums
Step 2: Mirror the Python SDKs (optional)
If you want skill-scanner and mcp-scanner available:
# on internet host
pip download skill-scanner mcpscanner -d /tmp/defenseclaw-wheels
Transfer /tmp/defenseclaw-wheels into the airgap. On the target:
pip install --no-index --find-links=/path/to/wheels skill-scanner mcpscanner
Step 3: Install on the target
tar -xzf defenseclaw-<ver>-linux-amd64.tar.gz
sudo install defenseclaw-gateway /usr/local/bin/
pip install --no-index defenseclaw-<ver>.whl
defenseclaw init --skip-install # --skip-install avoids PyPI probes
The --skip-install flag tells init not to attempt SDK auto-install. If you mirrored the wheels in Step 2, the SDKs are already importable; if you didn't, the dependent scanners remain inactive and the sidecar runs without them.
Step 4: Point at local-only sinks
Disable SaaS sinks and rely on the local SQLite audit DB at ~/.defenseclaw/audit.db.
Or forward to an internal Splunk/OTLP endpoint:
defenseclaw setup observability add splunk-hec \
--host splunk.internal \
--port 8088 \
--token $HEC_TOKEN \
--index defenseclaw \
--non-interactive
Step 5: Disable the LLM judge (or use an internal one)
The default judge config points at an external LLM. In airgap, either:
- Disable judge calls by using
defenseclaw setup guardrail --detection-strategy regex_only --non-interactive. - Point at an internal judge with
--judge-api-base,--judge-model, and--judge-api-key-env, then keep--detection-strategy regex_judge.
Step 6: Disable outbound DefenseClaw updates
DefenseClaw has no auto-update by default. Keep hosts airgapped by avoiding installer scripts that fetch from GitHub or PyPI and by mirroring every wheel or release archive explicitly.
Upgrades
Same flow: download on an internet host, transport, install:
tar -xzf defenseclaw-<newver>-linux-amd64.tar.gz
sudo install defenseclaw-gateway /usr/local/bin/
pip install --no-index defenseclaw-<newver>.whl
defenseclaw-gateway restart
The on-disk state (~/.defenseclaw/) is preserved across upgrades — policies, audit DB, overlays all carry over.
Verification
defenseclaw doctor
Expect passes on: binary paths, config, audit DB, device key, scanner import (if you mirrored wheels), sink connectivity. Expect failures on: external update check (turned off above), external judge (unless you wired an internal one).
Caveats
- Time sync matters. Airgapped hosts often drift; if your sinks reject old timestamps, you'll see
sink.rejectedevents. Runchronyorntpagainst an internal time source. - Monitor CVE disclosures out-of-band. The curl installer has no phone-home, which means you're responsible for noticing when to upgrade.
- Scanner SDK versions must match the sidecar. Re-mirror wheels whenever you upgrade DefenseClaw.