Satellite Air-Gap Deployment

Air-gap procedures, ECR image mirroring, offline certificate authority.

NIST controls:SC-7, CA-3, CM-7
Last updated:2026-03-22
Category:Technical

Air-Gap Satellite Deployment — step-ca + Offline PKI

Overview

Tier A customers in government, defense, critical infrastructure, or regulated industries may operate in fully air-gapped environments with zero internet connectivity. KuiperDesk supports this with:

  1. step-ca (Smallstep Certificate Authority) for all TLS — no Let's Encrypt dependency
  2. Contract-length certificates — cert lifetime = contract duration + 3 months grace
  3. Pre-loaded Harbor cache — all container images baked into the install media
  4. Offline agent enrollment — enrollment keys + CA bundle shipped with install media

How Air-Gap Install Works

Phase 1: Preparation (Online, at Arivaran or VAR)

Arivaran Hub (online)                     Install Media (USB/ISO)
┌──────────────────────┐                  ┌──────────────────────────┐
│ Dashboard: Generate  │                  │                          │
│ air-gap bundle for   │ ───export───→    │ airgap-bundle-<tenant>/  │
│ tenant X, contract   │                  │   images/                │
│ 3 years              │                  │     aa-hash-svc.tar      │
│                      │                  │     aa-twin-svc.tar      │
│ Creates:             │                  │     aa-enroll-svc.tar    │
│ - Satellite inter CA │                  │     aa-dash.tar          │
│   (3yr + 3mo = 39mo) │                  │     cnpg-citus.tar       │
│ - Enrollment keys    │                  │     seaweedfs.tar        │
│ - step-ca root+inter │                  │     step-ca.tar          │
│ - Agent MSI          │                  │     keycloak.tar         │
│ - Helm chart         │                  │     nginx.tar            │
│ - Bootstrap script   │                  │   charts/                │
│                      │                  │     satellite-0.1.0.tgz  │
│                      │                  │   pki/                   │
│                      │                  │     root-ca.crt          │
│                      │                  │     satellite-inter.crt  │
│                      │                  │     satellite-inter.key  │
│                      │                  │     step-ca-config.json  │
│                      │                  │   enrollment/            │
│                      │                  │     keys.json            │
│                      │                  │     agent.msi             │
│                      │                  │   bootstrap.sh           │
│                      │                  │   values-airgap.yaml     │
│                      │                  │   README.md              │
└──────────────────────┘                  └──────────────────────────┘

Phase 2: Deployment (Offline, at Customer Site)

# 1. Insert install media, mount
mount /dev/sdb1 /mnt/kuiperdesk

# 2. Run bootstrap (detects air-gap: no internet, uses local media)
/mnt/kuiperdesk/bootstrap.sh --airgap --media /mnt/kuiperdesk

# What happens:
#   a) Installs RKE2 from local RPMs/debs (bundled on media)
#   b) Loads container images from .tar files into containerd
#   c) Installs step-ca as the cluster CA (replaces cert-manager + Let's Encrypt)
#   d) Imports satellite intermediate CA (pre-signed by hub)
#   e) Helm installs satellite chart with values-airgap.yaml
#   f) No hub registration (offline) — satellite runs fully autonomous

Phase 3: Operation (Offline)

The satellite operates fully autonomously:

  • TLS certs issued by local step-ca (auto-renews within the cluster)
  • Agent enrollment uses pre-generated keys from install media
  • Backups stored on local S3 (SeaweedFS/CubeFS)
  • No hub sync — all data stays local
  • Dashboard accessible at the satellite's local IP/domain

Phase 4: Renewal (Before Contract Expiry)

90 days before certificate expiry:

  1. Dashboard shows "Certificate renewal required" banner
  2. Customer contacts Arivaran/VAR for renewal bundle
  3. New bundle generated with extended cert lifetime
  4. Applied via USB/sneakernet (same bootstrap process, --renew flag)

step-ca Configuration

Why step-ca (Not cert-manager + Let's Encrypt)

Featurecert-manager + LEstep-ca
Internet requiredYes (ACME HTTP-01/DNS-01)No
Cert lifetime90 days maxCustom (contract-length)
CA controlLet's Encrypt controlsCustomer/Arivaran controls
ACME supportYesYes (local ACME server)
FedRAMPLE not FedRAMP-authorized CAOwn PKI = full control
Air-gapImpossibleNative

step-ca Deployment on Satellite

# In Helm chart values-airgap.yaml
pki:
  provider: step-ca                    # instead of cert-manager + letsencrypt
  stepCA:
    enabled: true
    image: "registry.arivaran.ai/proxy-dockerhub/smallstep/step-ca:0.28.0"
    # Pre-configured: root CA + intermediate loaded from install media
    rootCert: /pki/root-ca.crt
    intermediateCert: /pki/satellite-inter.crt
    intermediateKey: /pki/satellite-inter.key
    # ACME provisioner — local services request certs via standard ACME
    acme:
      enabled: true
      endpoint: "https://step-ca.kd-system.svc:9000/acme/acme/directory"
    # Certificate lifetimes
    defaultTTL: "2160h"                # 90 days (service certs)
    maxTTL: "{{ .Values.pki.contractMonths }}mo"  # contract length

ingress:
  tls:
    enabled: true
    clusterIssuer: step-ca-issuer      # cert-manager StepIssuer (not LE)

Certificate Lifetimes

Cert TypeOnline SatelliteAir-Gap Satellite
Satellite intermediate CA5 yearsContract + 3 months
Service TLS (inter-service)90 days (auto-renew)90 days (auto-renew via local step-ca)
Agent mTLS1 year (auto-renew)Contract + 3 months (no renewal without media)
Ingress TLS (dashboard)90 days (LE)Contract + 3 months (step-ca)
Keycloak signing keys1 yearContract + 3 months

Why contract + 3 months for air-gap:

  • Service certs (90-day) auto-renew within the cluster via step-ca — no issue
  • But the intermediate CA and agent mTLS certs can't be renewed without hub contact
  • Setting them to contract + 3 months ensures everything works through the contract period
  • The 3-month grace gives time for renewal even if the contract renewal is delayed

Agent Configuration for Air-Gap

CA Trust Bundle

The agent needs to trust the satellite's step-ca root instead of Let's Encrypt:

// prod_config.json on air-gap agents
{
  "mode": "prod",
  "grpc_hash_check_endpoint": "api.satellite.local:443",
  "grpc_twin_endpoint": "api.satellite.local:443",
  "cloud_upload_urls": ["https://api.satellite.local/kuiperdesk-blocks"],
  "ca_bundle": "C:\\Program Files\\Arivaran\\pki\\root-ca.crt",
  "tenant_id": "uuid",
  "endpoint_id": "uuid"
}

Agent code change required (CloudComm.cpp):

// If ca_bundle is set, use it instead of system CA store
if (!cfg.caBundlePath.empty()) {
    curl_easy_setopt(curl, CURLOPT_CAINFO, cfg.caBundlePath.c_str());
}

MSI Filename for Air-Gap

aaagent_{version}_{KEY}_{CA_FINGERPRINT}_{base64url(apiHost)}.msi

The CA_FINGERPRINT field tells the installer DLL to:

  1. Fetch the CA cert from https://{apiHost}/api/v1/ca/{fingerprint}
  2. Verify the fingerprint matches
  3. Install to Windows Machine cert store (Local Machine → Trusted Root)
  4. For air-gap: CA cert is bundled ON the install media (no fetch needed)

Air-Gap MSI Installation

# Air-gap: CA cert pre-installed from media, KEY from media, no download
msiexec /i D:\kuiperdesk\enrollment\agent.msi `
  URL=api.satellite.local `
  KEY=kdenr_<from-media> `
  AIRGAPFP=<ca-fingerprint> `
  AIRGAPCA=D:\kuiperdesk\pki\root-ca.crt `
  /qn /l*v C:\temp\install.log

The installer DLL:

  1. Reads AIRGAPCA path → installs cert to machine store (no download)
  2. Reads KEY → enrollment (against local satellite, not hub)
  3. Agent starts, trusts the satellite's TLS via installed CA

Browser Trust

For users accessing the dashboard in a browser on air-gapped machines:

Option A: GPO/MDM deployment (enterprise)

# Deploy root CA to all domain machines via Group Policy
certutil -addstore "Root" \\fileserver\kuiperdesk\root-ca.crt

Option B: Manual trust (per-machine)

# Admin runs on each machine
Import-Certificate -FilePath "D:\kuiperdesk\pki\root-ca.crt" `
  -CertStoreLocation Cert:\LocalMachine\Root

Option C: Firefox (uses own store, ignores Windows)

# Deploy to Firefox via policies.json
{
  "policies": {
    "Certificates": {
      "Install": ["D:\\kuiperdesk\\pki\\root-ca.crt"]
    }
  }
}

Air-Gap Bundle Generation (Hub-Side)

# Dashboard: Settings → Satellite → Generate Air-Gap Bundle
# Or CLI:
kuiperdesk-cli airgap-bundle \
  --tenant-id <uuid> \
  --contract-months 36 \
  --platform bare-metal \
  --output /tmp/airgap-bundle-tenant-x/

The bundle generator:

  1. Pulls all required container images from Harbor → saves as .tar
  2. Generates step-ca root + intermediate keypair
  3. Signs satellite intermediate CA with hub CA (lifetime = contract + 3mo)
  4. Generates enrollment keys (batch of 100, pre-hashed)
  5. Builds agent MSI with embedded CA fingerprint
  6. Packages Helm chart + values-airgap.yaml
  7. Generates bootstrap.sh (offline-capable)
  8. Creates checksum manifest (SHA-256 for integrity)
  9. Optionally: creates bootable ISO

Hub ↔ Air-Gap Satellite Sync (Sneakernet)

For customers who periodically connect (e.g., monthly data export):

Air-Gap Satellite                          USB Drive
┌──────────────┐                          ┌──────────────┐
│ Export:       │ ───copy to USB──→        │ export/      │
│ - Metrics    │                          │   metrics.json│
│ - Audit log  │                          │   audit.jsonl │
│ - Billing    │                          │   billing.json│
│              │                          │              │
│ Import:      │ ←───copy from USB───     │ import/      │
│ - Agent MSI  │                          │   agent.msi  │
│ - Policy     │                          │   policy.json│
│ - CA renewal │                          │   renewal.pem│
└──────────────┘                          └──────────────┘

Compliance Mapping

FrameworkControlHow Air-Gap Satisfies
FedRAMP HighSC-7Complete network boundary — zero external connections
FedRAMP HighSC-8All data encrypted in transit (step-ca TLS) and at rest (LUKS)
FedRAMP HighSC-12FIPS-validated crypto (step-ca supports FIPS mode)
FedRAMP HighCM-3Configuration changes only via install media (auditable)
ITAR—Data never leaves customer facility
CJIS5.10.1.2Encryption in transit via customer-controlled CA
IL4/IL5—No internet dependency, all crypto under government control

Revision History

DateChangeAuthor
2026-03-22Initial — step-ca air-gap, contract-length certs, bundle generation, sneakernet syncClaire Dubois (Security), Viktor Kowalski (Agent Security), Navid Ahmadi (Compliance)

This document is part of the Arivaran Twin compliance program. For questions or the latest version, contact compliance@arivaran.ai.

Release-ready. Saved on this browser.