Air-Gap Deployment
Air-gap mode deploys the Arbitex Outpost in an environment with no network access to the Arbitex Platform management plane. All configuration — policy bundles, DLP models, and GeoIP databases — is provisioned via local filesystem volumes rather than downloaded at runtime.
Air-gap deployments are used for:
- Classified or air-gapped government networks
- Healthcare environments with strict outbound network controls
- Financial institutions with network segmentation requirements
- Environments where SEC 17a-4 WORM compliance requires isolation from external systems
Enabling Air-Gap Mode
Section titled “Enabling Air-Gap Mode”Set the OUTPOST_AIRGAP environment variable to true:
OUTPOST_AIRGAP=trueWhen air-gap mode is enabled at startup, the Outpost:
- Skips mTLS certificate validation (no Platform connectivity to validate against)
- Skips cert bundle auto-download
- Does not start the background policy sync task
- Does not start the heartbeat sender
- Does not start the cert rotation scheduler
- Loads all configuration from local filesystem volumes
All five disabled capabilities have local-volume equivalents described in this guide.
Policy Bundle Provisioning
Section titled “Policy Bundle Provisioning”Configuration
Section titled “Configuration”OUTPOST_AIRGAP=trueAIRGAP_POLICY_PATH=/opt/arbitex/policies # defaultThe Outpost loads policy_bundle.json from $AIRGAP_POLICY_PATH/policy_bundle.json at startup.
Bundle Format
Section titled “Bundle Format”The policy bundle is a JSON document containing:
- DLP rules (all active rules from the compliance and custom policy configuration)
- OAuth scope enforcement configuration
- Model access controls and risk tier assignments
To generate a policy bundle from the Platform:
# Export current active policy bundle from Platform admin APIcurl https://your-platform/api/admin/policy-bundle/export \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -o policy_bundle.jsonVolume Mount (Kubernetes)
Section titled “Volume Mount (Kubernetes)”env: - name: OUTPOST_AIRGAP value: "true" - name: AIRGAP_POLICY_PATH value: /opt/arbitex/policiesvolumeMounts: - name: policy-bundle mountPath: /opt/arbitex/policies readOnly: truevolumes: - name: policy-bundle configMap: name: arbitex-policy-bundleCreate the ConfigMap from your exported bundle:
kubectl create configmap arbitex-policy-bundle \ --from-file=policy_bundle.json=./policy_bundle.json \ -n arbitexBundle Updates in Air-Gap Mode
Section titled “Bundle Updates in Air-Gap Mode”Since there is no background sync, policy bundle updates require a rolling restart:
- Export a new
policy_bundle.jsonfrom the Platform (or prepare manually). - Update the ConfigMap or volume source.
- Perform a rolling restart of the Outpost deployment.
The Outpost logs the bundle version at startup: air_gap=True policy_bundle version=<version>.
DeBERTa ONNX Model Provisioning
Section titled “DeBERTa ONNX Model Provisioning”The DeBERTa v3 ONNX model provides Tier 3 contextual DLP classification. In air-gap mode, the model is loaded from a local volume rather than downloaded.
Configuration
Section titled “Configuration”OUTPOST_AIRGAP=trueAIRGAP_MODEL_PATH=/opt/arbitex/models # default
# Alternatively, override directly:DEBERTA_MODEL_PATH=/opt/arbitex/models/model.onnxAt startup, the Outpost resolves the model path in this order:
- If
DEBERTA_MODEL_PATHis explicitly set and the file exists, use it directly. - Otherwise, look for
model.onnxin$AIRGAP_MODEL_PATH/model.onnx. - If neither is found, Tier 3 classification is disabled (Tier 1 and Tier 2 DLP remain active).
Volume Mount (Kubernetes)
Section titled “Volume Mount (Kubernetes)”The model file (model.onnx) is large (~500 MB). Use a PersistentVolume rather than a ConfigMap:
env: - name: AIRGAP_MODEL_PATH value: /opt/arbitex/modelsvolumeMounts: - name: deberta-model mountPath: /opt/arbitex/models readOnly: truevolumes: - name: deberta-model persistentVolumeClaim: claimName: arbitex-deberta-model-pvcPre-populate the PVC with the promoted model artifact. The Outpost uses either optimum.onnxruntime (preferred, if available in the container image) or raw onnxruntime.InferenceSession as a fallback loader.
Model Versioning
Section titled “Model Versioning”The model artifact used in air-gap deployments should match the version shipped with the Outpost container image. Check the model version in the startup logs:
DeBERTa Tier3 scanner loaded: model.onnx (label_map={0: 'pii', 1: 'clean'}, threshold=0.7)GeoIP MMDB Provisioning
Section titled “GeoIP MMDB Provisioning”The Outpost uses GeoIP enrichment to annotate audit log entries with country, city, and ISP data from the request IP address. In air-gap mode, the MMDB database is provisioned via volume or baked into the container image.
Resolution Order
Section titled “Resolution Order”The Outpost resolves the GeoIP database in this order:
- Explicit path (
GEOIP_MMDB_PATH): if set and the file exists, use it. - Download on start (
GEOIP_DOWNLOAD_ON_START=true): skipped in air-gap mode — the download step is bypassed entirely whenOUTPOST_AIRGAP=true. - Bundled fallback (
GEOIP_MMDB_FALLBACK_PATH): a pre-baked MMDB baked into the container image or mounted separately. Used when steps 1 and 2 are unavailable.
Configuration for Air-Gap
Section titled “Configuration for Air-Gap”# Option A: explicit volume mountGEOIP_MMDB_PATH=/opt/arbitex/geoip/GeoLite2-City.mmdb
# Option B: use baked-in fallbackGEOIP_MMDB_FALLBACK_PATH=/app/geoip/GeoLite2-City.mmdbIf neither path resolves to a valid file, GeoIP enrichment is disabled and audit records omit geographic fields. This is a graceful degradation — the Outpost continues operating without GeoIP.
Volume Mount (Kubernetes)
Section titled “Volume Mount (Kubernetes)”env: - name: GEOIP_MMDB_PATH value: /opt/arbitex/geoip/GeoLite2-City.mmdbvolumeMounts: - name: geoip-db mountPath: /opt/arbitex/geoip readOnly: truevolumes: - name: geoip-db configMap: name: arbitex-geoipkubectl create configmap arbitex-geoip \ --from-file=GeoLite2-City.mmdb=./GeoLite2-City.mmdb \ -n arbitexNote: MaxMind GeoLite2 databases require a free MaxMind account to download. The anonymous-IP database (GEOIP_ANON_DB_PATH) requires a commercial MaxMind subscription.
SQLite Local Audit Queue
Section titled “SQLite Local Audit Queue”When the Outpost loses connectivity to the Platform audit sync endpoint — or in air-gap mode where no connectivity exists — audit events are written to a local SQLite queue rather than dropped.
Configuration
Section titled “Configuration”AUDIT_QUEUE_DB_PATH=audit_queue/audit_queue.db # defaultThe SQLite database file is created automatically at the configured path. In Kubernetes, mount a PersistentVolume at this path to ensure queue durability across pod restarts.
Queue Behavior
Section titled “Queue Behavior”| Condition | Behavior |
|---|---|
| Platform reachable (circuit CLOSED) | Audit events sent directly to Platform; SQLite queue drained asynchronously |
| Platform unreachable (circuit OPEN) | Audit events written to SQLite queue; no data loss |
| Circuit transitions to CLOSED | Flush task drains queue in 50-event batches to Platform |
The queue stores events as JSON in the local_audit_queue table:
CREATE TABLE local_audit_queue ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_json TEXT NOT NULL, queued_at REAL NOT NULL, retry_count INTEGER NOT NULL DEFAULT 0);Flush-on-Reconnect
Section titled “Flush-on-Reconnect”When connectivity is restored (audit circuit breaker closes), the Outpost automatically flushes the SQLite queue:
_sync_all_pending()detectslocal_queue.count() > 0and circuit stateCLOSED._flush_local_queue()sends batches of 50 events toPOST /v1/internal/outpost-audit-sync.- Successfully delivered events are deleted (
mark_synced(ids)). - Failed events increment their
retry_countfor next flush attempt.
There is no manual flush required. The flush runs automatically on each sync cycle once the circuit closes.
Monitoring Queue Depth
Section titled “Monitoring Queue Depth”Check queue depth via the Outpost admin API:
curl http://localhost:8080/admin/api/sync-status \ -H "Authorization: Bearer $OUTPOST_ADMIN_TOKEN"Response includes audit_queue_depth — the number of events pending flush. A persistently non-zero queue depth in non-air-gap mode indicates connectivity issues with the Platform audit endpoint.
Full Air-Gap Operation
Section titled “Full Air-Gap Operation”In a permanent air-gap deployment (no connectivity ever), the SQLite queue accumulates all audit events indefinitely. To export audit events from a permanently air-gapped Outpost:
- Access the SQLite database file directly (volume mount or kubectl exec).
- Extract events:
sqlite3 audit_queue.db "SELECT event_json FROM local_audit_queue;" - Transfer the extracted events to the Platform via a secure offline transfer process.
Cert Rotation in Offline Mode
Section titled “Cert Rotation in Offline Mode”Standard Cert Rotation (disabled in air-gap)
Section titled “Standard Cert Rotation (disabled in air-gap)”In a connected deployment, the Outpost automatically renews its mTLS certificate 30 days before expiry by calling the Platform cert renewal endpoint. This scheduler is disabled in air-gap mode:
Air-gap mode: cert rotation disabled (no platform connectivity)Manual Cert Rotation for Air-Gap Deployments
Section titled “Manual Cert Rotation for Air-Gap Deployments”In air-gap mode, operators are responsible for certificate rotation:
- Monitor cert expiry: The
/admin/api/sync-statusendpoint returnscert_expiry_days. - Generate replacement certs: Provision a new cert/key pair using your PKI (step-ca, internal CA, or manual).
- Update volume mounts: Replace the cert and key files on the mounted volume.
- Rolling restart: Restart the Outpost pods to load the new certificates.
# Check cert expiry from the Outpost admin APIcurl http://localhost:8080/admin/api/sync-status \ -H "Authorization: Bearer $OUTPOST_ADMIN_TOKEN" | jq '.cert_expiry_days'Set up monitoring alerts when cert_expiry_days drops below your rotation lead time (recommend: 45 days for air-gap environments where restarts require scheduling).
Cert Bundle Configuration
Section titled “Cert Bundle Configuration”In air-gap mode, CERT_BUNDLE_AUTO_DOWNLOAD is implicitly disabled. Configure the cert bundle path directly:
OUTPOST_TLS_CERT=/opt/arbitex/certs/outpost.crtOUTPOST_TLS_KEY=/opt/arbitex/certs/outpost.keyOUTPOST_CA_BUNDLE=/opt/arbitex/certs/ca-bundle.crtComplete Air-Gap Configuration Reference
Section titled “Complete Air-Gap Configuration Reference”# === Core air-gap switch ===OUTPOST_AIRGAP=true
# === Policy bundle ===AIRGAP_POLICY_PATH=/opt/arbitex/policies # contains policy_bundle.json
# === DeBERTa model ===AIRGAP_MODEL_PATH=/opt/arbitex/models # contains model.onnx# or: DEBERTA_MODEL_PATH=/opt/arbitex/models/model.onnx
# === GeoIP ===GEOIP_MMDB_PATH=/opt/arbitex/geoip/GeoLite2-City.mmdb# or: GEOIP_MMDB_FALLBACK_PATH=/app/geoip/GeoLite2-City.mmdb
# === Audit queue ===AUDIT_QUEUE_DB_PATH=/opt/arbitex/audit/audit_queue.db
# === Certificates ===OUTPOST_TLS_CERT=/opt/arbitex/certs/outpost.crtOUTPOST_TLS_KEY=/opt/arbitex/certs/outpost.keyOUTPOST_CA_BUNDLE=/opt/arbitex/certs/ca-bundle.crt
# === DLP settings ===DLP_DEBERTA_ENABLED=true # enable if model is provisionedDEBERTA_MODEL_PATH=/opt/arbitex/models/model.onnxKubernetes Deployment Template
Section titled “Kubernetes Deployment Template”apiVersion: apps/v1kind: Deploymentmetadata: name: arbitex-outpost-airgap namespace: arbitexspec: replicas: 2 selector: matchLabels: app: arbitex-outpost template: metadata: labels: app: arbitex-outpost spec: containers: - name: outpost image: arbitex/outpost:latest env: - name: OUTPOST_AIRGAP value: "true" - name: AIRGAP_POLICY_PATH value: /opt/arbitex/policies - name: AIRGAP_MODEL_PATH value: /opt/arbitex/models - name: GEOIP_MMDB_PATH value: /opt/arbitex/geoip/GeoLite2-City.mmdb - name: AUDIT_QUEUE_DB_PATH value: /opt/arbitex/audit/audit_queue.db - name: DLP_DEBERTA_ENABLED value: "true" volumeMounts: - name: policy-bundle mountPath: /opt/arbitex/policies readOnly: true - name: deberta-model mountPath: /opt/arbitex/models readOnly: true - name: geoip-db mountPath: /opt/arbitex/geoip readOnly: true - name: audit-queue mountPath: /opt/arbitex/audit - name: tls-certs mountPath: /opt/arbitex/certs readOnly: true volumes: - name: policy-bundle configMap: name: arbitex-policy-bundle - name: deberta-model persistentVolumeClaim: claimName: arbitex-deberta-model-pvc - name: geoip-db configMap: name: arbitex-geoip - name: audit-queue persistentVolumeClaim: claimName: arbitex-audit-queue-pvc - name: tls-certs secret: secretName: arbitex-outpost-tlsStartup Validation
Section titled “Startup Validation”At startup, the Outpost logs its air-gap configuration summary:
INFO Air-gap mode enabledINFO Policy bundle loaded: version=2026-03-13, rules=47INFO DeBERTa Tier3 scanner loaded: model.onnx (threshold=0.7)INFO GeoIP: city database loaded (path=/opt/arbitex/geoip/GeoLite2-City.mmdb)INFO Audit queue: SQLite backend at /opt/arbitex/audit/audit_queue.dbINFO Air-gap mode: cert rotation disabled (no platform connectivity)INFO Air-gap mode: heartbeat disabled (no platform connectivity)INFO Air-gap mode: policy sync disabled (no platform connectivity)If any required volume is missing or the policy bundle fails to parse, the Outpost logs an error and continues with the subsystem disabled (graceful degradation) — it does not abort startup.
Feature Availability in Air-Gap Mode
Section titled “Feature Availability in Air-Gap Mode”| Feature | Air-Gap Support | Notes |
|---|---|---|
| DLP scanning (Tier 1 + Tier 2) | Full | Pattern matching and compliance bundles |
| DLP scanning (Tier 3 DeBERTa) | Full | Requires model volume mount |
| GeoIP enrichment | Full | Requires MMDB volume mount |
| Audit logging | Full | Events stored in SQLite queue |
| Policy enforcement | Full | Loaded from policy_bundle.json |
| mTLS cert rotation | Manual only | No automatic rotation |
| Platform heartbeat | Disabled | No connectivity to Platform |
| CredInt breach lookup | Disabled | No connectivity to CredInt microservice |
| Policy bundle sync | Manual only | Rolling restart required for updates |
Related
Section titled “Related”- Outpost Deployment (Kubernetes) — standard connected deployment guide
- Outpost Resilience — circuit breaker and degradation behavior
- Compliance Frameworks — policy bundles for regulatory compliance
- Credential Intelligence — CredInt breach corpus (unavailable in air-gap)
- Distributed Tracing — OTel tracing configuration for air-gapped environments