Skip to content

Air-gapped operations

OrbitalReg is designed to run in air-gapped environments without modification. A fresh install starts in air-gapped mode — no egress to the public internet — until an admin opts each integration in explicitly.

What "air-gapped" means here

Out of the box, the following touch nothing outside the cluster:

ChannelDefault stateToggle
Outbound webhooksBlockedallow_outbound_webhooks
OSV.dev advisory lookupsBlockedallow_osv_lookups
Sigstore Rekor transparency logBlockedallow_sigstore_rekor
OpenTelemetry exporterBlockedallow_otel_export
Update-check manifest fetchOffempty update_check_settings.manifest_url
Telemetry / service pingsBlockedallow_service_pings
Container-image upstream pullsBlockedper-repo remote.allow_egress
Format-adapter upstream pullsBlockedper-repo remote.allow_egress

The master toggle is Admin → System → Egress. Existing deployments preserve their pre-air-gap behaviour through a migration heuristic (any deployment with > 0 webhook subscriptions in the backlog is auto-set to allow_outbound_webhooks=TRUE).

The update-check manifest fetch is its own opt-in independent of the master egress gate: a fresh install ships with the manifest URL empty (the worker short-circuits before any network call), so a default install makes zero outbound calls of its own accord. The operator picks Off / Daily / Weekly in the Update check step of the First-Run Setup Wizard or populates the manifest URL directly on Admin → Version status → Settings. On a regulated install the air-gapped egress gate is the belt-and-braces second layer — even if an operator were to flip the manifest URL on a locked-down cluster, the gate denies the request and last_error shows air-gapped: for transparency.

What still works without egress

  • Every upload + download path
  • All format adapters' local mode
  • All scanners that ship their advisory data offline (Trivy and Grype bundle DBs that can be refreshed from a private mirror)
  • Sigstore signature verification using the embedded public-good Fulcio + the operator-supplied trust policy (no Rekor lookup)
  • The full governance surface (security blocks, retention, license policies)

Refreshing scanner DBs

Trivy and Grype both ship offline DB bundles. The chart's scanners.dbRefresh mode controls how those DBs roll forward:

  • automatic — scanners pull from OSV.dev / ghcr.io on a schedule (requires egress)
  • mirrored — scanners pull from your private mirror (HTTPS, no public internet)
  • manual — operator drops bundles into a known PVC; CronJob unpacks

In an air-gapped install, prefer mirrored with the chart's scanners.dbMirror.url pointing at your private artifact mirror.

Documentation

This site (docs-site/) builds to a fully static bundle. To ship docs into an air-gapped customer environment:

bash
cd docs-site
npm ci
DOCS_BASE_PATH=/docs npm run build
tar czf orbitalreg-docs-${VERSION}.tar.gz -C .vitepress/dist .

Untar behind any reverse proxy and point ORBITALREG_HELP_URL at the chosen URL so the help button in the AppShell topbar opens it.

Image bundle

The container images for an air-gapped install:

ImageSource
ghcr.io/orbitalreg/orbital-api:<tag>API + frontend bundle
ghcr.io/orbitalreg/orbital-frontend:<tag>nginx-served SPA only
ghcr.io/orbitalreg/orbital-operator:<tag>Kubernetes operator
ghcr.io/orbitalreg/orbital-scanner-bundle:<tag>Trivy + Grype + Syft DBs

Use skopeo to copy each into your private registry:

bash
skopeo copy --all \
  docker://ghcr.io/orbitalreg/orbital-api:v1.2.3 \
  docker://registry.internal.example.com/orbitalreg/orbital-api:v1.2.3

Then point the chart's image.repository values at the private registry.

License envelope

For commercial use, OrbitalReg requires a signed license envelope under Admin → License. Mint it on a connected workstation with bin/orbital-license-issuer and copy the envelope into the air-gapped cluster:

bash
bin/orbital-license-issuer \
  --install-id <copy from /admin/license> \
  --customer "Acme Corp" \
  --duration 1y \
  > license.txt

The install-id is a per-cluster deterministic UUID — the same input on the same cluster always produces the same value, so re-issuing after a token rotation is safe.

Released under the Apache-2.0 License.