ACCESS TO IT INTEL GRANTED

Mirror Signed Images to an Air-Gapped Registry Preserving DCT

TARGET_ENV: skopeo 1.13+, Notary 1.2+, Docker 24.0+, Ubuntu 22.04
[ TAGS: docker, snippet, content-trust, air-gapped, mirror, skopeo ]

This pipeline copies a signed image and its Notary metadata from a public registry to an internal air-gapped registry while preserving the trust chain. Internally, skopeo copies the image by digest to the destination, and notary copies the TUF metadata using the source and destination Notary servers. The destination Notary server must be initialized with a root key, and the copied targets.json is re-signed by the destination repository key so that air-gapped clients verify against the internal trust anchor rather than the public one. The image digest is preserved, so the signed target still matches the copied manifest.

This is essential for defense, finance, and any environment with no outbound internet, where you still must guarantee provenance. It is also used by platform teams that curate an approved image catalog and must prove that the mirrored image is bit-identical to the upstream signed artifact. The pattern supports periodic sync jobs that mirror a curated allowlist of images and their signatures.

Security implications: the mirroring host becomes a trust boundary, so it must itself be hardened and its destination keys protected. If you copy the image but not the Notary metadata, clients with DCT enabled will refuse to pull, which is the desired fail-closed behavior. Performance is dominated by image layer transfer; metadata is tiny. Common pitfalls include copying by tag instead of digest (allowing upstream tag mutation to silently change what you mirrored), forgetting to initialize the destination Notary server, and not re-signing after copy so the metadata references the source key the air-gapped client does not trust. Always verify with docker trust inspect on the destination.

> System.Execute()

set -euo pipefail
SRC=registry.example.com/app/api:1.4.2
DST=internal-registry.local/app/api:1.4.2
DIGEST=$(skopeo inspect --format '{{.Digest}}' docker://$SRC)
skopeo copy --all docker://$SRC docker://$DST
notary -s https://notary.example.com -d ~/.docker/trust list registry.example.com/app/api > /tmp/src-trust.txt
notary -s https://notary.internal.local -d ~/.docker/trust init internal-registry.local/app/api
notary -s https://notary.internal.local -d ~/.docker/trust addhash internal-registry.local/app/api \
  "$DIGEST" --publish
notary -s https://notary.internal.local -d ~/.docker/trust publish internal-registry.local/app/api
docker trust inspect --pretty internal-registry.local/app/api:1.4.2

> Architecture & Security Context

Verified for Valters IT Hub. When deploying this configuration in a production homelab or enterprise environment, ensure that you monitor system resources and implement strict access controls. Administrator privileges are required.


ID: VALTERSIT-FD6F41A8C19B

← BACK_TO_VAULT → CVE_DATABASE