Skip to content

Air-gap operations guide

This guide covers day-to-day operations for an Arbitex Outpost running in an air-gapped environment. It assumes the outpost was installed using the air-gap deployment guide.


If the systemd service was installed during setup, use standard systemctl commands. The service name is arbitex-outpost.

Terminal window
# Check service status
sudo systemctl status arbitex-outpost
# Start the service
sudo systemctl start arbitex-outpost
# Stop the service
sudo systemctl stop arbitex-outpost
# Restart the service (required after .env changes or certificate replacement)
sudo systemctl restart arbitex-outpost
# View live logs
journalctl -u arbitex-outpost -f
# View the last 200 log lines
journalctl -u arbitex-outpost -n 200
# View logs since a specific time
journalctl -u arbitex-outpost --since "2026-03-01 00:00:00"

If the outpost is not running under systemd, manage it directly with Docker Compose from the install directory:

Terminal window
cd /opt/arbitex-outpost
# View running containers
docker compose -f docker-compose.outpost.yml ps
# Start in foreground
docker compose -f docker-compose.outpost.yml up
# Start in background
docker compose -f docker-compose.outpost.yml up -d
# Stop
docker compose -f docker-compose.outpost.yml down
# View live logs
docker compose -f docker-compose.outpost.yml logs -f
# Restart the outpost container
docker compose -f docker-compose.outpost.yml restart
Terminal window
# Liveness — returns 200 if the process is running
curl http://localhost:8300/healthz
# Readiness — returns 200 if a policy bundle is loaded; 503 if not
curl http://localhost:8300/readyz

Updating the outpost in an air-gapped environment requires transferring a new air-gap package and replacing the running container images. No internet access is required on the target host.

On the internet-connected build machine:

Terminal window
bash scripts/make-airgap.sh <NEW_VERSION>

Output: dist/arbitex-outpost-airgap-<NEW_VERSION>.tar.gz and .sha256.

Transfer the new tarball and checksum to the air-gapped host using any available channel (SCP, removable media, internal file transfer):

Terminal window
scp dist/arbitex-outpost-airgap-<NEW_VERSION>.tar.gz \
dist/arbitex-outpost-airgap-<NEW_VERSION>.tar.gz.sha256 \
user@target-host:/tmp/

On the target host:

Terminal window
cd /tmp
sha256sum -c arbitex-outpost-airgap-<NEW_VERSION>.tar.gz.sha256
tar -xzf arbitex-outpost-airgap-<NEW_VERSION>.tar.gz
Terminal window
cd airgap-<NEW_VERSION>/
docker load < outpost-image-<NEW_VERSION>.tar.gz

Both the CPU and GPU images are loaded from the tarball. No registry pull or internet access occurs.

5. Update docker-compose to reference the new image tag

Section titled “5. Update docker-compose to reference the new image tag”

Edit /opt/arbitex-outpost/docker-compose.outpost.yml and update the image tag from <OLD_VERSION> to <NEW_VERSION>.

Alternatively, if the Compose file references an environment variable for the image tag, update .env:

Terminal window
# In /opt/arbitex-outpost/.env
OUTPOST_IMAGE_TAG=<NEW_VERSION>

If running under systemd:

Terminal window
sudo systemctl restart arbitex-outpost

With Docker Compose directly:

Terminal window
cd /opt/arbitex-outpost
docker compose -f docker-compose.outpost.yml down
docker compose -f docker-compose.outpost.yml up -d
Terminal window
curl http://localhost:8300/healthz
curl http://localhost:8300/readyz

Check logs for the new version string at startup:

Terminal window
journalctl -u arbitex-outpost -n 50

If the new version fails health checks, reload the previous image (if still in the Docker image cache) and revert the image tag reference:

Terminal window
# Check what images are available locally
docker images | grep arbitex/outpost
# Revert docker-compose image tag to the previous version, then restart
sudo systemctl restart arbitex-outpost

Arbitex Outpost requires three mTLS certificate files for management plane connectivity. In internet-connected deployments, the CertRotationClient handles automatic renewal. In air-gapped environments, certificate renewal is a manual procedure.

Default paths (relative to install directory, e.g. /opt/arbitex-outpost/):

FileVariableDefault path
Client certificateOUTPOST_CERT_PATHcerts/outpost.pem
Private keyOUTPOST_KEY_PATHcerts/outpost.key
CA certificateOUTPOST_CA_PATHcerts/ca.pem
Terminal window
openssl x509 -in /opt/arbitex-outpost/certs/outpost.pem -noout -enddate

The Outpost logs a warning when the certificate is within 30 days of expiry.

  1. Contact Arbitex support or log in to cloud.arbitex.ai to request a renewed certificate bundle for your outpost ID.
  2. Download the new outpost.pem, outpost.key, and (if the CA changed) ca.pem.
  3. Transfer the new files to the air-gapped host.
  4. Replace the certificate files:
Terminal window
cp new-outpost.pem /opt/arbitex-outpost/certs/outpost.pem
cp new-outpost.key /opt/arbitex-outpost/certs/outpost.key
# Only replace ca.pem if the CA certificate itself changed
# cp new-ca.pem /opt/arbitex-outpost/certs/ca.pem
  1. Restart the outpost to reload the certificates:
Terminal window
sudo systemctl restart arbitex-outpost
  1. Verify TLS connectivity by checking that the heartbeat and policy sync succeed in the logs:
Terminal window
journalctl -u arbitex-outpost -f | grep -E "policy_sync|heartbeat|cert"

Self-signed certificates (management plane unreachable)

Section titled “Self-signed certificates (management plane unreachable)”

In air-gap environments where the Outpost cannot reach the management plane at all (fully network-isolated), the outpost operates using the locally cached policy bundle. Certificate expiry in this mode does not prevent the proxy from serving requests — only management plane connectivity is affected. The local audit log, DLP pipeline, and request routing continue to function using the cached bundle.


The active policy bundle is stored at policy_cache/policy_bundle.json (relative to install directory). Inspect the current bundle version:

Terminal window
cat /opt/arbitex-outpost/policy_cache/policy_bundle.json | python3 -m json.tool | grep '"version"'

When the outpost can temporarily reach the management plane (e.g., during a brief network window), the PolicySyncClient automatically fetches the latest bundle. No manual action is required.

If you need to push a specific policy bundle to an outpost that has no management plane connectivity at all:

  1. Export the policy bundle from the cloud portal as a JSON file.
  2. Transfer it to the air-gapped host.
  3. Replace the cached bundle:
Terminal window
cp exported-policy-bundle.json /opt/arbitex-outpost/policy_cache/policy_bundle.json
  1. Restart the outpost to reload the bundle:
Terminal window
sudo systemctl restart arbitex-outpost

The systemd journal rotates automatically based on /etc/systemd/journald.conf. To limit journal storage for the outpost service:

Terminal window
# Set a size cap on the journal (edit /etc/systemd/journald.conf)
SystemMaxUse=500M

Then restart journald:

Terminal window
sudo systemctl restart systemd-journald

The audit buffer at audit_buffer/audit.jsonl is managed as a ring buffer by the outpost. The maximum number of entries is set by MAX_AUDIT_BUFFER_ENTRIES (default: 100,000). When the buffer is full, the oldest entries are rotated out automatically.

For long-running air-gap deployments where audit events accumulate without being synced to the management plane, monitor the buffer size periodically:

Terminal window
wc -l /opt/arbitex-outpost/audit_buffer/audit.jsonl
du -sh /opt/arbitex-outpost/audit_buffer/audit.jsonl

If the buffer approaches capacity, extract and archive audit events (see below) before they are rotated out.

If SIEM_DIRECT_DEAD_LETTER_PATH is set, failed SIEM deliveries are appended to that file without rotation. Add an OS-level log rotation entry if SIEM forwarding is enabled:

/etc/logrotate.d/arbitex-outpost-siem
/var/log/arbitex/siem-dead-letter.jsonl {
daily
rotate 30
compress
missingok
notifempty
copytruncate
}

Audit log extraction for manual SIEM import

Section titled “Audit log extraction for manual SIEM import”

In air-gapped environments without a SIEM direct sink configured, audit events accumulate in the local buffer. Extract them manually for import into your SIEM system.

Terminal window
cp /opt/arbitex-outpost/audit_buffer/audit.jsonl \
/tmp/arbitex-audit-$(date +%Y%m%d-%H%M%S).jsonl

The file is JSONL format (one JSON object per line). Each entry includes:

FieldDescription
event_idUnique event UUID
outpost_idOutpost identifier
timestampISO 8601 event time
request_idRequest correlation ID
user_idUser who made the request
modelTarget model
dlp_actionDLP outcome: ALLOW, BLOCK, REDACT, PROMPT
dlp_entitiesList of detected entity types
hmacHMAC-SHA256 chain signature
prev_hmacPrevious entry’s HMAC (chain link)

Before importing, verify the audit chain has not been tampered with:

Terminal window
# The platform provides an audit verification tool; for manual inspection,
# verify that each entry's hmac field is consistent with its content and prev_hmac.
# See: /admin/audit-log-verification/ for the verification reference.

See Audit log verification for the full verification procedure.

Most SIEMs can ingest JSONL directly. For Splunk:

Terminal window
# Using Splunk universal forwarder or one-shot file monitor:
/opt/splunkforwarder/bin/splunk add oneshot /tmp/arbitex-audit-<DATE>.jsonl \
-sourcetype arbitex:outpost:audit \
-index arbitex_audit

For Microsoft Sentinel, use the custom log ingestion API or upload the JSONL file via the Log Analytics workspace data upload feature.


All configuration is managed via /opt/arbitex-outpost/.env. After making changes, restart the outpost:

Terminal window
sudo systemctl restart arbitex-outpost
# or
cd /opt/arbitex-outpost && docker compose -f docker-compose.outpost.yml restart
ChangeVariableNotes
Enable Tier 3 DeBERTa DLPDLP_DEBERTA_ENABLED=true + DEBERTA_MODEL_PATH=<path>DeBERTa ONNX file must be accessible inside the container
Enable SIEM direct sinkSIEM_DIRECT_ENABLED=true + SIEM_DIRECT_URL=<url>See SIEM direct sink guide
Add GeoIP MMDBMAXMIND_DB_PATH=/app/geoip/GeoLite2-City.mmdbCopy MMDB to geoip/ first
Enable HMAC-signed policy bundlesPOLICY_HMAC_KEY=<key>Must match the key configured in the cloud portal
Enable GPU inferenceChange image tag to <VERSION>-gpu in Compose fileRequires NVIDIA runtime