Air-Gapped Deployment
Deploy Scrydon in disconnected environments using Zarf
Use this guide if your Kubernetes cluster has no outbound internet access — for example, classified government networks, isolated industrial environments, or strict compliance environments. If your cluster can reach the internet, see Helm instead.
What is Zarf?
Zarf is an open-source tool (Apache 2.0) purpose-built for delivering Kubernetes applications into air-gapped and disconnected environments. Scrydon uses Zarf to bundle all container images, Helm charts, and manifests into a single self-contained .tar.zst archive that can be transferred physically (USB, DVD, cross-domain guard) or over a one-way data diode.
| Capability | How Zarf Handles It |
|---|---|
| Image loading | Automatically pushes all images to an in-cluster registry |
| Image reference rewriting | Mutating webhook rewrites image refs — no manual imageRegistry overrides needed |
| Registry management | Zarf deploys and manages the in-cluster registry |
| Signature verification | Built-in Cosign verification |
| SBOM | Built-in (Syft, with viewer) |
You do not need Harbor, Artifactory, or any external registry. Zarf provides everything.
Prerequisites
- Kubernetes 1.28+ cluster (air-gapped)
zarfCLI installed — a single static binary, available at zarf.dev/releases or delivered alongside your package- License bundle (
{ jwt, publicKey }JSON file) received via secure channel — see Licensing. Bare.jwtfiles are no longer accepted; the bundle ships the matching RSA public key so the platform can verify signatures without a network call.
Step 1: Receive the Package
Scrydon ships air-gapped packages as a signed .tar.zst archive, published to an OCI registry:
# Pull the Zarf package from the OCI registry (on a connected machine)
zarf package pull oci://ghcr.io/scrydon/scrydon:<version>
# Output: zarf-package-scrydon-amd64-<version>.tar.zstTransfer this file to your air-gapped environment via approved means (encrypted USB, DVD, cross-domain guard, one-way data diode). The package is a standard tar archive and is compatible with most cross-domain guard appliances.
Step 2: Verify the Package
Before deploying, verify the package's integrity and authenticity.
Verify the Cosign Signature
zarf package inspect zarf-package-scrydon-amd64-<version>.tar.zst \
--key scrydon-cosign-public-key.pemThe Scrydon public key (scrydon-cosign-public-key.pem) is delivered alongside the package. Contact your Scrydon account representative if you need a fresh copy.
Verify the SHA-256 Checksum
sha256sum -c SHA256SUMSThe SHA256SUMS file is included in the delivery bundle. Both checks must pass before deploying.
Inspect the SBOM
zarf package inspect zarf-package-scrydon-amd64-<version>.tar.zst --sbomThis opens the built-in SBOM viewer, listing all software components and their licenses included in the package.
Step 3: Deploy the Package
zarf package deploy zarf-package-scrydon-amd64-<version>.tar.zst --confirmZarf will:
- Create an in-cluster OCI registry (if one is not already present)
- Load all container images from the archive into the in-cluster registry
- Deploy a mutating webhook that rewrites image references to point to the in-cluster registry
- Run
helm installwith the Helm chart and values bundled in the package - Wait for all deployments to become ready
To pass custom configuration during deployment:
zarf package deploy zarf-package-scrydon-amd64-<version>.tar.zst \
--confirm \
--set DOMAIN=scrydon.yourdomain.milStep 4: Apply the License Bundle
After deployment, apply your license bundle. The bundle is a JSON file delivered separately via secure channel ({ "jwt": "…", "publicKey": "-----BEGIN PUBLIC KEY-----…" }) and is NOT included in the Zarf package. There is no scrydon-license Kubernetes Secret — the bundle is stored in the platform's platform_config DB row after first use, and rotated through the platform UI.
You have two ways to apply the bundle on a fresh install:
Option A — /setup wizard (default). Open https://app.yourdomain.com/platform/setup (or /setup if you mounted platform at the root) in a browser and paste/drop the bundle into Step 1. The wizard parses the bundle, verifies the JWT against the public key in the bundle, and persists both on Step 2.
Option B — pre-seed via Helm values. Set auth.secrets.LICENSE (the bundle's jwt) and auth.secrets.LICENSE_PUBLIC_KEY (the bundle's publicKey) when deploying the Zarf package, then go straight to the Admin step in /setup:
zarf package deploy zarf-package-scrydon-amd64-<version>.tar.zst \
--confirm \
--set LICENSE_JWT="$(jq -r .jwt license.bundle.json)" \
--set LICENSE_PUBLIC_KEY="$(jq -r .publicKey license.bundle.json)"Whichever path you pick, the license is persisted to the DB on first read and the values entries are no longer consulted afterwards.
Step 5: Verify the Deployment
Check Pod Status
The default chart layout puts every service in scrydon-platform. Multi-namespace installs are opt-in via namespaces.* overrides.
kubectl get pods -n scrydon-platform
# If you split namespaces via namespaces.agentic / namespaces.analytics,
# also check those namespaces.All pods should reach Running 2/2 (app container + Dapr sidecar). If pods stay at 1/1, Dapr injection failed — check kubectl get pod -l app=dapr-sidecar-injector -A.
If a pod is stuck in Init:0/1, the wait-for-db init container hasn't completed — confirm the bundled Postgres (kubectl get pod -l app=db -n scrydon-platform) is Running.
Check Ingress
kubectl get ingress -n scrydon-platformAll options
The Zarf package wraps the same Helm chart. Any chart value can be set at deploy time with --set <KEY>=<VALUE> (as shown for DOMAIN and the license above), or baked into the bundle's values overlay. Every value the chart exposes — routing, BYO database, StarRocks/SeaweedFS, scheduling, low-resource trims — is documented in the Helm reference. Air-gapped installs additionally set license.mode: offline so the platform never phones home.
Security Considerations
Air-gapped environments have additional security requirements:
- No external DNS lookups: Scrydon's offline license mode does not make any outbound network calls. The license JWT is validated locally using the embedded public key.
- No telemetry: In air-gapped deployments, no telemetry or analytics data leaves the cluster.
- Image integrity: All images are digest-pinned. The mutating webhook rewrites references to the in-cluster registry while preserving digest pins.
- Secrets: The license JWT and any credentials you supply are stored only as Kubernetes Secrets within your cluster. Zarf does not retain or transmit these values.
Next: See Licensing for details on license validation, grace periods, and renewal.