Skip to main content

Run fully offline (air-gap)

Surfaces used: Python / Node SDK in Local mode, self-hosted gateway Modes supported: Local Tiers: Free (baseline), Self-Hosted enterprise for full air-gap deployment Status: Local-mode SDK is GA. Self-Hosted air-gap deployment is PRIVATE PREVIEW.

What you'll do

Run Control Zero with zero outbound calls. Policy lives in a local YAML or JSON file on disk (both use the identical schema). Audit writes to a local file (or your own internal log sink). No telemetry, no dashboard calls, no license check-ins.

Why this is the right path for you

  • If your environment is disconnected (classified, regulated, or just offline by policy) and you cannot call api.controlzero.ai, this is for you.
  • For a single developer or a small offline workload, the SDK in Local mode is enough.
  • For an organization running air-gapped, you want the Self-Hosted deployment: the dashboard, audit store, and signing infrastructure, all inside your boundary.

When NOT to use this approach

caution

If you have internet egress and just want privacy, you do not need air-gap. Hosted mode already keeps prompts in-memory and only stores redacted audit metadata. Air-gap is for environments where outbound is not allowed, not just not preferred.

5-minute setup (single developer, Local mode)

pip install controlzero

Create policy.yaml:

rules:
- id: block-shell-execute
deny: 'shell:execute'
reason: 'Destructive shell commands are not allowed.'
- id: allow-everything-else
allow: '*'
reason: 'Default-allow for everything else.'

# DLP rules scan tool args for sensitive data. Built-in patterns
# (AWS keys, GitHub tokens, SSNs, etc.) are always active. Add custom
# patterns here.
dlp_rules:
- id: block-internal-codes
pattern: 'PROJ-[A-Z]{3}-\d{6}'
category: custom
action: block
reason: 'Internal project codes must not leave the agent.'

Use it:

from controlzero import Client

cz = Client(policy_file="./policy.yaml")

decision = cz.guard(tool="shell", args={"command": "rm -rf /"})
assert not decision.allowed

Audit writes to ./controlzero.log (override with log_path=).

Verify no network calls

# Block egress as a smoke test
sudo pfctl -e # or your firewall of choice
python your_app.py

The SDK should continue to work: policy is local, audit is local, nothing reaches out.

Self-Managed air-gap deployment PRIVATE PREVIEW

For an organization running fully air-gapped, Self-Managed gives you the full experience: dashboard, policy signing, and audit store, all inside your boundary, with offline (signed-manifest) license validation and no outbound calls.

Self-Managed is delivered under a PRIVATE PREVIEW license. You receive a signed install package, a private install runbook, and a named support contact. The install steps ship with that package rather than being published here.

To pilot, see Self-Managed or contact us.

Verifying it's working

  1. With egress blocked, run the SDK smoke test above. Policy evaluation and audit must continue.
  2. For Self-Managed: follow the verification steps in the install runbook delivered with your package; all components should report ok with no outbound attempts.
  3. Confirm the audit file (Local mode) or dashboard (Self-Hosted) grows as traffic flows.

Common follow-ups

Reference