Skip to content
PostMTA Hosted
StatusSign inOpen panelRequest access
Open menu

Docs

Open in panel → /app · appliance

Air-gap updates

Customer-VPC and air-gapped sites need an offline upgrade path that does not call a public package registry at apply time.

What ships

Piece Role Matrix
scripts/gen-release-key.sh Durable ed25519 release key under artifacts/release-keys/ M73
scripts/publish-release.sh Build → sign tarball + .sig + side-car pubkey M73
scripts/install-bundle.sh Verify fingerprint, unpack, lightweight smoke M73
scripts/airgap-drill.sh Gold ceremony: sign → offline copy → tamper-reject → install M73
scripts/rollback-appliance.sh Reinstall prior release-<sha>-* bundle M63
MOCK_RELEASE_SIGNING=1 Deterministic CI path without a live release key
Appliance GPG key scripts/gen-appliance-key.sh for signing backups M66

Release key ceremony

Generate once on a connected build host (or reuse idempotently):

bash scripts/gen-release-key.sh
cat artifacts/release-keys/fingerprint.txt

Pin the fingerprint on every consumer:

export POSTMTA_RELEASE_FINGERPRINT="$(cat artifacts/release-keys/fingerprint.txt)"

Transfer artifacts/release-keys/public-key.asc through your approved offline channel alongside bundles. Consumers must refuse bundles signed by any other fingerprint.

Operator flow (summary)

  1. Publisher: bash scripts/publish-release.sh --key "$POSTMTA_RELEASE_FINGERPRINT"
  2. Transfer: bundle + .sig + .public-key.asc + .SHA256SUMS offline
  3. Consumer: verify fingerprint, unpack, run smoke (never skip smoke in production)
sudo bash scripts/install-bundle.sh \
  --bundle /tmp/release-<sha>-<stamp>.tar.gz \
  --sig    /tmp/release-<sha>-<stamp>.tar.gz.sig \
  --target /opt/postmta-hosted \
  --verify-with "$POSTMTA_RELEASE_FINGERPRINT"

Tampered payloads must fail closed before unpack.

CI / lab drills

Fast round-trip without a durable key:

MOCK_RELEASE_SIGNING=1 bash scripts/release-roundtrip.sh

Gold air-gap drill (requires gpg; honest SKIP when missing):

bash scripts/airgap-drill.sh
# AIRGAP-DRILL PASS

The drill may pass --skip-smoke for speed (AIRGAP_DRILL=1). Production installs must not use --skip-smoke — the gold path runs scripts/check-appliance-deploy.sh after unpack.

Rollback (M63)

Keep prior bundles in artifacts/release/ (or your artifact store). Roll back application files with:

bash scripts/rollback-appliance.sh --to <sha> \
  --bundle-dir artifacts/release \
  --verify-with "$POSTMTA_RELEASE_FINGERPRINT"

Schema rollback is separate: down migrations live in supabase/migrations/_down/*.down.sql. Apply those manually and carefully when the database must regress — the bundle rollback only restores code/infra.

Last verified: Sun Jul 12 2026 17:00:00 GMT-0700 (Pacific Daylight Time). Cross-link maintained byscripts/check-docs-drift.sh (M54).

← All docs