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​