Skip to main content

Air-Gap Security & Compliance

Purpose: For security officers, provides package signing, SBOM generation, and chain-of-custody documentation.

Overview

Air-gap artifacts carry all dependencies for a production Kubernetes cluster. This reference documents the security controls applied during build, transfer, and deployment.

Artifact Signing (Cosign)

Packages are signed using Sigstore Cosign during the build phase in Zone A.

PropertyValue
Signing toolCosign
Key typeECDSA P-256
Signature format.sig file alongside the artifact
Key generationopencenter-airgap keygen

Verification in Zone C:

cosign verify-blob \
--key cosign.pub \
--signature zarf-package-*.tar.zst.sig \
zarf-package-*.tar.zst

The public key must be distributed through a separate trusted channel (not on the same media as the artifact).

SBOM (Software Bill of Materials)

Zarf generates an SBOM for every package. The SBOM lists:

  • Every container image with tag and digest
  • Every binary with version and download source
  • Every Helm chart with version and repository
  • OS packages and Python wheels

Inspect the SBOM:

zarf package inspect zarf-package-*.tar.zst --sbom

SBOM format: SPDX JSON (Zarf default). Compatible with vulnerability scanners like Grype and Trivy.

Vulnerability Scanning

The build pipeline runs Trivy against all container images:

SettingValue
ScannerTrivy
Severity thresholdHIGH, CRITICAL
PolicyFail build on HIGH or CRITICAL findings
DatabaseUpdated at build time (Zone A)

Run a manual scan:

trivy image --severity HIGH,CRITICAL <image-ref>

For SBOM-based scanning after build:

trivy sbom sbom.json --severity HIGH,CRITICAL

Checksum Integrity

ArtifactChecksum methodFile
Zarf packageSHA-256package.sha256
Kubernetes binariesSHA-256 (upstream)*.sha256 from dl.k8s.io
Build manifestSHA-256 (in state file)build/.state.json

Generate and verify:

# Generate (Zone A)
sha256sum dist/zarf-package-*.tar.zst > dist/package.sha256

# Verify (Zone C)
sha256sum -c package.sha256

Chain-of-Custody

For regulated environments, document the transfer path:

ZoneActionEvidence
Zone ABuild completedBuild log (logs/build-*.log), artifact-manifest.json
Zone APackage signedCosign signature file (.sig)
Zone A → Zone BCopied to mediapackage.sha256 recorded
Zone B → Zone CMedia deliveredChain-of-custody form (organization-specific)
Zone CChecksum verifiedsha256sum -c output
Zone CSignature verifiedcosign verify-blob output
Zone CPackage deployedZarf deploy log

Secrets Handling

Secret typeStorageNotes
Cosign private keyBuild host only (Zone A)Never transferred to Zone C
SSH keysInjected at deploy timeNot embedded in the Zarf artifact
Registry credentialsNot requiredBastion registry runs without auth (local network only)

Secrets are never committed to Git. The build uses file-based injection from config/.secrets/ (gitignored).

Compliance Mapping

ControlImplementation
Supply chain integrityCosign signatures + SHA-256 checksums
Software inventorySBOM (SPDX JSON) embedded in every package
Vulnerability managementTrivy scan at build time; fail on HIGH/CRITICAL
Version pinningAll versions in versions.env; no mutable tags
Audit trailBuild logs, state file, artifact manifest
Data-at-restZarf package is compressed but not encrypted; encrypt media if required by policy
Network isolationZone C has zero internet access; all traffic stays on local subnet

Encryption at Rest

The Zarf package itself is not encrypted — it is a compressed tarball. If your security policy requires encryption of data at rest on transfer media, apply full-disk encryption (e.g., LUKS) to the USB drive or use an encrypted container:

# Example: create encrypted container for transfer
dd if=/dev/zero of=transfer.img bs=1M count=50000
cryptsetup luksFormat transfer.img
cryptsetup open transfer.img transfer
mkfs.ext4 /dev/mapper/transfer
mount /dev/mapper/transfer /mnt/transfer
cp dist/zarf-package-*.tar.zst /mnt/transfer/