Skip to main content

Install in an air-gapped environment

Last updated on


Install Harness Self-Managed Platform (SMP) in an air-gapped network by staging image bundles and a Helm chart, pushing both to private registries, then running helm install.

Workstation requirements

  • A minimum of 150GB of free disk space to download and extract the Harness air gap bundle

  • ECR/GCR/private registry details to tag and push images

  • Kubernetes: A supported cluster. Go to Supported Kubernetes versions to confirm compatibility with Harness SMP.

  • Latest version of Helm

  • Helm charts: Go to the Harness helm-charts releases to download charts locally when you cannot use a public Helm repo. Image bundle sources differ by chart line; go to Choose your Helm chart line to match your version.


Choose your Helm chart line

Harness SMP uses three different image bundle delivery methods depending on your chart version. Each change reflects a deliberate improvement in how images are packaged, distributed, or secured.

VersionsHow you get image bundlesWhy this method
0.41.0+Support manifest.yaml (signed downloadUrl per module; no public bundle URLs)Harness now ships Rapidfort-hardened images, which are distributed as private images only. The signed manifest.yaml provides per-module download URLs tied to your support entitlement instead of a public bucket.
0.38.0 to 0.40.xPublic GCP bucket and Script or Manual in Step 1Adds the harness-airgap-images.sh helper script on top of the per-module bundles, so you can automate loading and pushing images instead of running each step by hand.
0.37.x and earlierGCS *.tgz per module from the bundle bucketBundles were split per module starting in this line so you only download images for the modules you deploy, instead of pulling one bundle that contains every Harness image.

Harness installation workflow

  1. Step 1: Download image bundles (version-specific; transfer into the air gap if needed)
  2. Step 2: Push images to your private container registry
  3. Step 3: Download and push the Helm chart
  4. Step 4: Install with Helm with your private registry in override.yaml

Step 1: Download image bundles

Open the tab for the chart version you want to deploy.

For Helm chart 0.41.0 and later, Harness no longer provides public air gap image bundles. You use a private, Support-provided manifest file with signed downloadUrl values per module.

Step 1.1: Get private manifest from Harness Support

Request the air gap bundle manifest for your target Helm chart version before you begin.

  1. Open a case with Harness Support and request the air gap bundle manifest for your Helm chart version.
  2. Ask for a signed URL validity window that covers your maintenance window.
  3. Keep the file off public source control and treat signed URLs as secrets until they expire.

Use this support checklist in your request:

  • Harness account ID: The account that the manifest is issued for. Find your account ID in any Harness UI URL (https://app.harness.io/ng/account/<account_id>/...).
  • Chart version: Exact Helm chart version (example: 0.41.2).
  • Signed URL validity window: Expiry duration that matches your maintenance window.
  • Delivery contact: Team or alias that receives the manifest file.
  • Retry context: Mention if this is a refreshed manifest for expired links.

Manifest filename

Support delivers the manifest as a YAML file named for your account and chart version:

smp-bundle-manifest-<account_id>-<chart_version>.yaml

For example, an account with ID Y-UFocCmSPynCt0NCxhebg on chart 0.39.1 receives:

smp-bundle-manifest-Y-UFocCmSPynCt0NCxhebg-0.39.1.yaml
Manifest filename in examples

The rest of this page refers to the file as manifest.yaml for brevity. When you run the commands below, substitute the actual smp-bundle-manifest-<account_id>-<chart_version>.yaml filename Support sent you, or rename the file to manifest.yaml locally.

The manifest lists all required modules and their signed URLs. Only the downloadUrl values are needed to retrieve bundle archives.

Example manifest shape (redacted)
version: "1.0"
modules:
platform:
description: "Core Platform Services"
bucket_path: "platform"
downloadUrl: "https://storage.googleapis.com/.../platform_images.tgz?X-Goog-Algorithm=..."
ci:
description: "Continuous Integration"
bucket_path: "ci"
downloadUrl: "https://storage.googleapis.com/.../ci_images.tgz?X-Goog-Algorithm=..."

Step 1.2: Download air gap scripts

Use the same helper scripts as in chart 0.38.0 through 0.40.x. Download them from the Harness helm-charts repository:

curl -f -s -L -o download-airgap-bundles.sh https://raw.githubusercontent.com/harness/helm-charts/refs/heads/main/src/airgap/download-airgap-bundles.sh
curl -f -s -L -o harness-airgap-images.sh https://raw.githubusercontent.com/harness/helm-charts/refs/heads/main/src/airgap/harness-airgap-images.sh

chmod +x download-airgap-bundles.sh
chmod +x harness-airgap-images.sh

Step 1.3: Download module bundles with the private manifest

Choose a download method

warning

If download URLs return HTTP 403 during this step, they are often expired. Request a refreshed manifest.yaml from Support, then retry.

Run download-airgap-bundles.sh and pass the path to your manifest with -m. The script downloads each module's *.tgz and preserves the same directory layout that harness-airgap-images.sh expects (aligned with the 0.38.0 to 0.40.x public layout).

./download-airgap-bundles.sh -m /path/to/manifest.yaml -o ./airgap-bundles

When your chart version supports them, you can also use the same interactive menu, non-interactive -b and -n flags, and saved -g / -s selection files as in the Version 0.38.0 - 0.40.x tab. The new input is the manifest file path; there are no other new flags for this flow.

Example script output
Reading manifest: /path/to/manifest.yaml
Downloading platform_images.tgz ...
Downloading ci_images.tgz ...
Download completed. Bundles saved under ./airgap-bundles
Optional: verify private bundle layout and checksums

Confirm that your output directory looks like a typical bundle tree, for example:

airgap-bundles/
├── platform/
│ └── platform_images.tgz
├── platform/agents/
│ ├── delegate.tgz
│ └── upgrader.tgz
├── ci/
│ └── ci_images.tgz
└── ...

Optional integrity check:

find ./airgap-bundles -name "*.tgz" -type f -exec sha256sum {} \;

Store the checksum output with your deployment artifacts so you can validate copied files in disconnected environments.

For download-airgap-bundles.sh flags in this flow, go to download-airgap-bundles.sh (0.41.0 and later) in the Reference. For signed URL errors, go to Troubleshooting.

When downloads are complete, continue with Step 2: Push images to your private registry. Use Push using a bundle directory. Pass the same path to harness-airgap-images.sh -d that you used for download-airgap-bundles.sh -o (for example ./airgap-bundles).


Step 2: Push images to your private registry

After you download the module bundle *.tgz files, use harness-airgap-images.sh to load and push images to your private container registry. Pick the tab that matches your chart line.

Step 2.1: Set Docker architecture

Air gap installation uses amd64 container images. Set the platform on the host that runs the script.

export DOCKER_DEFAULT_PLATFORM=linux/amd64

Step 2.2: Sign in to your private registry

# Authenticate with Docker for Docker Registry
docker login <registry-url>

# Authenticate with Google Cloud Platform for GCR
gcloud auth login

# Authenticate with AWS for ECR
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin

When you work with the public GCS download flow, bundle objects also appear in the Harness air gap bundles bucket for reference.

Pre-flight check before you push
  • Registry authentication: docker login (or your cloud provider registry login) succeeds.
  • Bundle path: The directory that contains your *.tgz tree (from your download output path) is the path you will pass to -d. Common values include ./airgap-bundles and ./bundles, but use your own output directory.
  • Disk capacity: The host has enough free space to unpack and push the images.
  • Runtime tools: skopeo and jq are installed if you use Skopeo mode.

Step 2.3: Push images

Point -d at the same directory that contains the module layout from the download step (the folder that includes platform/, ci/, and other subfolders, not the top-level *.tgz only).

Use Skopeo mode when you can. Skopeo copies images between registries without a Docker daemon and can reduce push times by up to 50%.

Prerequisites: skopeo and jq are installed on the host that runs the script.

Add the -s flag. Set -r to your registry, and set -d to your download output directory.

./harness-airgap-images.sh -r my-registry.com/harness -d ./airgap-bundles -s

Docker (fallback)

If you cannot use Skopeo, run the script without -s to use docker load and docker push. Add the -c flag to clean up local Docker images after a successful push.

./harness-airgap-images.sh -r my-registry.com/harness -d ./airgap-bundles -c
Looker (ng-dashboard) image

The ng-dashboard (Looker) image is not in the standard air gap bundle archives. The script can prompt for Docker Hub credentials, or you can use -n to skip the image. If you need access for Looker, contact Harness Support.

harness-airgap-images.sh flag reference: harness-airgap-images.sh in Reference.


Step 3: Download and push the Helm chart to your private registry

After you push images in Step 2, download the Harness Helm chart and push it to a repository your air-gapped environment can use (for example a private OCI registry for charts).

  • Helm pull and push: If your host can reach the public Helm index from a controlled path, add the repo, pull the chart, and push to your private registry in one sequence:
helm repo add harness https://harness.github.io/helm-charts
helm pull harness/harness
helm push harness-*.tgz oci://private-repo
  • Direct download: Go to the Harness helm-charts releases to download the chart package, then copy it into your air-gapped network and push to your private registry with your standard process.

Step 4: Install with Helm

Install the chart into your cluster and set override.yaml so the deployment uses your private image registry and air gap settings.

To install via Helm, do the following:

  1. Update the override.yaml file with your private registry information.

    global:
    airgap: true
    imageRegistry: "private-123.com"
  2. Run the Helm install command.

    helm install my-release harness/harness -n <namespace> -f override.yaml

Troubleshooting

If you hit issues during download or install, expand the topic that matches your symptom.

Signed air gap bundle downloadUrl in manifest.yaml returns HTTP 403 or the link is expired

Signed URLs stop working after the configured validity period. Open a case with Harness Support, request a new manifest.yaml for the same chart release, and state how long the next signed URLs must stay valid. Replace the old file, then download the bundles and push the images again.


Reference

Bundle path reference (0.38.0 to 0.40.x)

When you construct manual download URLs for 0.38.0 through 0.40.x, replace <bundle-name> with the bundle key (for example platform, cdng). This table lists bucket_path style paths for modules and components.

BundleTypeFull Path
PlatformModuleharness-<VERSION>/platform/platform_images.tgz
Platform AgentsAgentharness-<VERSION>/platform/agents/<agent>.tgz
DashboardModuleharness-<VERSION>/dashboard/dashboard_images.tgz
Continuous Deployment (cdng)Moduleharness-<VERSION>/cdng/cdng_images.tgz
CD AgentsAgentharness-<VERSION>/cdng/agents/cdng-agents_images.tgz
Continuous Integration (ci)Moduleharness-<VERSION>/ci/ci_images.tgz
CI PluginsPluginharness-<VERSION>/ci/plugins/ci-plugins_images.tgz
Security Testing Orchestration (sto)Moduleharness-<VERSION>/sto/sto_images.tgz
STO ScannersScannerharness-<VERSION>/sto/scanners/<scanner>.tgz
Feature Flags (ff)Moduleharness-<VERSION>/ff/ff_images.tgz
Cloud Cost Management (ccm)Moduleharness-<VERSION>/ccm/ccm_images.tgz
Chaos Engineering (ce)Moduleharness-<VERSION>/ce/ce_images.tgz
Chaos PluginsPluginharness-<VERSION>/ce/plugins/ce-plugins_images.tgz
Supply Chain Security (ssca)Moduleharness-<VERSION>/ssca/ssca_images.tgz
SCS PluginsPluginharness-<VERSION>/ssca/plugins/ssca-plugins_images.tgz
Database DevOps (dbdevops)Moduleharness-<VERSION>/dbdevops/dbdevops_images.tgz
Code Repository (code)Moduleharness-<VERSION>/code/code_images.tgz
Infrastructure as Code Management (iacm)Moduleharness-<VERSION>/iacm/iacm_images.tgz
IACM PluginsPluginharness-<VERSION>/iacm/plugins/iacm-plugins_images.tgz
Internal Developer Portal (idp)Moduleharness-<VERSION>/idp/idp_images.tgz
IDP PluginsPluginharness-<VERSION>/idp/plugins/idp-plugins_images.tgz

Available single bundles

The following components are packaged as individual single bundles (.tgz), rather than a combined bundle:

Platform Agents:

  • delegate.tgz
  • upgrader.tgz

STO Scanners:

  • anchore-job-runner.tgz
  • aqua-security-job-runner.tgz
  • aqua-trivy-job-runner.tgz
  • aws-ecr-job-runner.tgz
  • aws-security-hub-job-runner.tgz
  • bandit-job-runner.tgz
  • blackduckhub-job-runner.tgz
  • brakeman-job-runner.tgz
  • burp-job-runner.tgz
  • checkmarx-job-runner.tgz
  • checkov-job-runner.tgz
  • docker-content-trust-job-runner.tgz
  • fossa-job-runner.tgz
  • github-advanced-security-job-runner.tgz
  • gitleaks-job-runner.tgz
  • grype-job-runner.tgz
  • modelscan-job-runner.tgz
  • nexusiq-job-runner.tgz
  • nikto-job-runner.tgz
  • nmap-job-runner.tgz
  • osv-job-runner.tgz
  • owasp-dependency-check-job-runner.tgz
  • prowler-job-runner.tgz
  • semgrep-job-runner.tgz
  • snyk-job-runner.tgz
  • sonarqube-agent-job-runner.tgz
  • sysdig-job-runner.tgz
  • traceable-job-runner.tgz
  • twistlock-job-runner.tgz
  • veracode-agent-job-runner.tgz
  • whitesource-agent-job-runner.tgz
  • wiz-job-runner.tgz
  • zap-job-runner.tgz

download-airgap-bundles.sh (0.38.0 to 0.40.x)

Use this script to fetch air gap bundles from public bundle locations for chart 0.38.0 through 0.40.x.

FlagDescription
-vHarness version to download (for example 0.38.0).
-oOutput directory for the downloaded bundles.
-b / --bundlesComma-separated list of bundles to download (for example ci,delegate).
-gGenerate a configuration file with your interactive selections.
-sUse a previously generated configuration file.
-nRun in non-interactive mode.

Helm chart 0.41.0 and later uses a Support-provided manifest.yaml and the -m flag instead of public bundle URLs. Go to Step 1 and open the Version 0.41.0 and later tab on this page.

download-airgap-bundles.sh (0.41.0 and later)

Use this script to download module *.tgz files using a Support-provided manifest.yaml.

FlagDescription
-mPath to manifest.yaml from Harness Support. The manifest lists every module for the chart release; each module entry includes a downloadUrl to its *.tgz bundle.
-oOutput directory for downloaded bundles.
-b / --bundlesComma-separated list of components to download, when this flag is supported for your chart.
-gGenerate a configuration file with your interactive selections.
-sUse a previously generated selection configuration file.
-nRun in non-interactive mode.

For chart 0.41.0 and later, do not use public GCS or app.harness.io URLs, and do not rely on -v to resolve public harness-airgap paths. Bundle locations come from the downloadUrl values in the manifest.

harness-airgap-images.sh

FlagDescription
-rTarget private container registry URL.
-dDirectory that contains the downloaded bundle *.tgz files (for chart 0.38.0 and later, typical download output layout).
-fSingle bundle *.tgz (for chart 0.37.x and earlier, per-file push).
-sEnable Skopeo mode for faster transfers without a local Docker daemon.
-cWhen Skopeo is not enabled, clean up local Docker images after a successful push to save disk.
-nRun in non-interactive mode (for example, skip the Looker image prompt).