|
| 1 | +# |
| 2 | +# This makefile's targets rebuild various container images that can be used |
| 3 | +# for development and testing in the CoCo project. |
| 4 | +# They also are intended to serve as an up-to-date reference for creating |
| 5 | +# new images. |
| 6 | +# |
| 7 | +# Note: The targets push to ghcr, which requires proper credentials and |
| 8 | +# `docker login`. |
| 9 | +# |
| 10 | +# For multi-arch targets, Docker buildx with QEMU is required: |
| 11 | +# docker run --rm --privileged multiarch/qemu-user-static --reset -p yes |
| 12 | +# docker buildx create --name multiarch-coco --use |
| 13 | +# docker buildx inspect --bootstrap |
| 14 | +# |
| 15 | + |
| 16 | +.PHONY: unsig \ |
| 17 | + cosign-sig \ |
| 18 | + simple-sig \ |
| 19 | + enc-unsig \ |
| 20 | + enc-cosign-sig \ |
| 21 | + test-container-unencrypted \ |
| 22 | + test-container-encrypted \ |
| 23 | + multi-arch-encrypted \ |
| 24 | + multi-arch-encrypted-cosign-sig \ |
| 25 | + busybox \ |
| 26 | + setup-buildx \ |
| 27 | + coco-keyprovider \ |
| 28 | + all |
| 29 | + |
| 30 | +SHELL := /bin/bash |
| 31 | + |
| 32 | +COCO_PKG := confidential-containers/test-container |
| 33 | +COCO_PKG_IMGRS := confidential-containers/test-container-image-rs |
| 34 | +REGISTRY := ghcr.io |
| 35 | + |
| 36 | +PLATFORMS := linux/amd64 linux/arm64 linux/s390x |
| 37 | +BUILDX_BUILDER := multiarch-coco |
| 38 | +KEYPROVIDER_IMAGE := coco-keyprovider |
| 39 | + |
| 40 | +SSH_DEMO_KEY_B64 := HUlOu8NWz8si11OZUzUJMnjiq/iZyHBJZMSD3BaqgMc= |
| 41 | +SSH_DEMO_KEY_ID := kbs:///default/key/ssh-demo |
| 42 | + |
| 43 | +WORK_DIR := /tmp/coco-multi-arch-build |
| 44 | + |
| 45 | + |
| 46 | +all: \ |
| 47 | + unsig \ |
| 48 | + cosign-sig \ |
| 49 | + simple-sig \ |
| 50 | + enc-unsig \ |
| 51 | + enc-cosign-sig \ |
| 52 | + test-container-unencrypted \ |
| 53 | + test-container-encrypted \ |
| 54 | + multi-arch-encrypted \ |
| 55 | + multi-arch-encrypted-cosign-sig \ |
| 56 | + busybox |
| 57 | + |
| 58 | + |
| 59 | +# --------------------------------------------------------------------------- |
| 60 | +# Setup targets |
| 61 | +# --------------------------------------------------------------------------- |
| 62 | + |
| 63 | +setup-buildx: |
| 64 | + @if ! docker buildx inspect $(BUILDX_BUILDER) >/dev/null 2>&1; then \ |
| 65 | + echo "==> Setting up QEMU and buildx builder"; \ |
| 66 | + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes; \ |
| 67 | + docker buildx create --name $(BUILDX_BUILDER) --use; \ |
| 68 | + docker buildx inspect --bootstrap; \ |
| 69 | + else \ |
| 70 | + docker buildx use $(BUILDX_BUILDER); \ |
| 71 | + fi |
| 72 | + |
| 73 | +coco-keyprovider: |
| 74 | + @if ! docker image inspect $(KEYPROVIDER_IMAGE) >/dev/null 2>&1; then \ |
| 75 | + echo "==> Building coco-keyprovider from guest-components"; \ |
| 76 | + if [ ! -d /tmp/guest-components ]; then \ |
| 77 | + git clone --depth 1 https://github.com/confidential-containers/guest-components.git /tmp/guest-components; \ |
| 78 | + fi; \ |
| 79 | + docker build -t $(KEYPROVIDER_IMAGE) \ |
| 80 | + -f /tmp/guest-components/attestation-agent/docker/Dockerfile.keyprovider \ |
| 81 | + /tmp/guest-components/; \ |
| 82 | + else \ |
| 83 | + echo "==> coco-keyprovider image already exists"; \ |
| 84 | + fi |
| 85 | + |
| 86 | + |
| 87 | +# --------------------------------------------------------------------------- |
| 88 | +# Single-arch targets (build for host arch, push directly) |
| 89 | +# --------------------------------------------------------------------------- |
| 90 | + |
| 91 | +unsig: |
| 92 | + docker build \ |
| 93 | + -t $(REGISTRY)/$(COCO_PKG):unsig \ |
| 94 | + -f dockerfiles/alpine-with-sshd/Dockerfile \ |
| 95 | + . |
| 96 | + docker push $(REGISTRY)/$(COCO_PKG):unsig |
| 97 | + |
| 98 | +cosign-sig: |
| 99 | + docker build \ |
| 100 | + -t $(REGISTRY)/$(COCO_PKG):cosign-sig \ |
| 101 | + -f dockerfiles/alpine-with-sshd/Dockerfile \ |
| 102 | + . |
| 103 | + docker push $(REGISTRY)/$(COCO_PKG):cosign-sig |
| 104 | + ${CURDIR}/scripts/make-cosign-sig.sh $(COCO_PKG) cosign-sig $(REGISTRY) |
| 105 | + |
| 106 | +# NOTE: This depends on a gpg key owned by git@runner.com. |
| 107 | +# Before issuing this make target: |
| 108 | +# gpg --batch --import ./keys/sign/github-runner.keys |
| 109 | +simple-sig: unsig |
| 110 | + skopeo \ |
| 111 | + copy \ |
| 112 | + --debug \ |
| 113 | + --insecure-policy \ |
| 114 | + --sign-by git@runner.com \ |
| 115 | + --sign-passphrase-file $(shell pwd)/keys/sign/git-runner-password.txt \ |
| 116 | + docker-daemon:$(REGISTRY)/$(COCO_PKG):unsig \ |
| 117 | + docker://$(REGISTRY)/$(COCO_PKG):simple-sig |
| 118 | + |
| 119 | +# NOTE: This requires coco-keyprovider running on localhost:50000. |
| 120 | +# Use `make coco-keyprovider` to build the container, then run it: |
| 121 | +# docker run --rm --network host coco-keyprovider |
| 122 | +enc-unsig: unsig |
| 123 | + OCICRYPT_KEYPROVIDER_CONFIG="$(shell pwd)/configs/ocicrypt.conf" \ |
| 124 | + skopeo copy \ |
| 125 | + --insecure-policy \ |
| 126 | + --encryption-key provider:attestation-agent:keypath=$(shell pwd)/keys/encrypt/key1::keyid=kbs:///default/key/key_id1::algorithm=A256GCM \ |
| 127 | + docker-daemon:$(REGISTRY)/$(COCO_PKG):unsig \ |
| 128 | + docker://$(REGISTRY)/$(COCO_PKG):enc-unsig |
| 129 | + |
| 130 | +enc-cosign-sig: cosign-sig |
| 131 | + OCICRYPT_KEYPROVIDER_CONFIG="$(shell pwd)/configs/ocicrypt.conf" \ |
| 132 | + skopeo copy \ |
| 133 | + --insecure-policy \ |
| 134 | + --encryption-key provider:attestation-agent:keypath=$(shell pwd)/keys/encrypt/key1::keyid=kbs:///default/key/key_id1::algorithm=A256GCM \ |
| 135 | + docker-daemon:$(REGISTRY)/$(COCO_PKG):cosign-sig \ |
| 136 | + docker://$(REGISTRY)/$(COCO_PKG):enc-cosign-sig |
| 137 | + ${CURDIR}/scripts/make-cosign-sig.sh $(COCO_PKG) enc-cosign-sig $(REGISTRY) |
| 138 | + |
| 139 | +test-container-unencrypted: |
| 140 | + docker build \ |
| 141 | + -t $(REGISTRY)/$(COCO_PKG):unencrypted \ |
| 142 | + -f dockerfiles/alpine-with-sshd/Dockerfile \ |
| 143 | + . |
| 144 | + docker push $(REGISTRY)/$(COCO_PKG):unencrypted |
| 145 | + |
| 146 | +test-container-encrypted: test-container-unencrypted |
| 147 | + OCICRYPT_KEYPROVIDER_CONFIG="$(shell pwd)/configs/ocicrypt.conf" \ |
| 148 | + skopeo copy \ |
| 149 | + --insecure-policy \ |
| 150 | + --encryption-key provider:attestation-agent:keypath=$(shell pwd)/keys/encrypt/key1::keyid=kbs:///default/key/key_id1::algorithm=A256GCM \ |
| 151 | + docker-daemon:$(REGISTRY)/$(COCO_PKG):unencrypted \ |
| 152 | + docker://$(REGISTRY)/$(COCO_PKG):encrypted |
| 153 | + |
| 154 | +busybox: |
| 155 | + docker build \ |
| 156 | + -t $(REGISTRY)/$(COCO_PKG_IMGRS):busybox \ |
| 157 | + -f dockerfiles/busybox/Dockerfile \ |
| 158 | + dockerfiles/busybox |
| 159 | + docker push $(REGISTRY)/$(COCO_PKG_IMGRS):busybox |
| 160 | + |
| 161 | + |
| 162 | +# --------------------------------------------------------------------------- |
| 163 | +# Multi-arch encrypted target |
| 164 | +# |
| 165 | +# Builds the ccv0-ssh image for each platform, encrypts with the |
| 166 | +# coco-keyprovider container, pushes per-arch images, and assembles |
| 167 | +# a multi-arch manifest. |
| 168 | +# |
| 169 | +# Encryption key: from demos/ssh-demo/aa-offline_fs_kbc-keys.json |
| 170 | +# Key ID: kbs:///default/key/ssh-demo |
| 171 | +# --------------------------------------------------------------------------- |
| 172 | + |
| 173 | +multi-arch-encrypted: setup-buildx coco-keyprovider |
| 174 | + @echo "==> Building multi-arch-encrypted for: $(PLATFORMS)" |
| 175 | + @mkdir -p $(WORK_DIR) |
| 176 | + @for platform in $(PLATFORMS); do \ |
| 177 | + arch=$$(echo $$platform | cut -d/ -f2); \ |
| 178 | + arch_dir="$(WORK_DIR)/$$arch"; \ |
| 179 | + per_arch_tag="$(REGISTRY)/$(COCO_PKG):encrypted-$$arch"; \ |
| 180 | + \ |
| 181 | + echo "==> [$$arch] Building unencrypted image"; \ |
| 182 | + docker buildx build \ |
| 183 | + --platform "$$platform" \ |
| 184 | + --provenance=false \ |
| 185 | + -t "ccv0-ssh:$$arch" \ |
| 186 | + --load \ |
| 187 | + -f dockerfiles/alpine-with-sshd/Dockerfile \ |
| 188 | + . ; \ |
| 189 | + \ |
| 190 | + echo "==> [$$arch] Exporting to OCI directory"; \ |
| 191 | + mkdir -p "$$arch_dir"/{input,output}; \ |
| 192 | + skopeo copy --override-arch "$$arch" \ |
| 193 | + "docker-daemon:ccv0-ssh:$$arch" \ |
| 194 | + "dir:$$arch_dir/input"; \ |
| 195 | + \ |
| 196 | + echo "==> [$$arch] Encrypting with coco-keyprovider"; \ |
| 197 | + docker run --rm \ |
| 198 | + -v "$$arch_dir:/oci" \ |
| 199 | + $(KEYPROVIDER_IMAGE) \ |
| 200 | + /encrypt.sh \ |
| 201 | + -k "$(SSH_DEMO_KEY_B64)" \ |
| 202 | + -i "$(SSH_DEMO_KEY_ID)" \ |
| 203 | + -s "dir:/oci/input" \ |
| 204 | + -d "dir:/oci/output"; \ |
| 205 | + \ |
| 206 | + echo "==> [$$arch] Verifying encryption annotations"; \ |
| 207 | + skopeo inspect "dir:$$arch_dir/output" \ |
| 208 | + | jq -e 'any(.LayersData[]?; .Annotations?["org.opencontainers.image.enc.keys.provider.attestation-agent"] != null)' \ |
| 209 | + || { echo "ERROR: [$$arch] No encryption annotation"; exit 1; }; \ |
| 210 | + \ |
| 211 | + echo "==> [$$arch] Pushing encrypted image"; \ |
| 212 | + skopeo copy "dir:$$arch_dir/output" "docker://$$per_arch_tag"; \ |
| 213 | + done |
| 214 | + @echo "==> Creating multi-arch manifest" |
| 215 | + @docker manifest rm $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted 2>/dev/null || true |
| 216 | + @docker manifest create $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted \ |
| 217 | + $(foreach p,$(PLATFORMS),$(REGISTRY)/$(COCO_PKG):encrypted-$(lastword $(subst /, ,$(p)))) |
| 218 | + @$(foreach p,$(PLATFORMS), \ |
| 219 | + docker manifest annotate $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted \ |
| 220 | + $(REGISTRY)/$(COCO_PKG):encrypted-$(lastword $(subst /, ,$(p))) \ |
| 221 | + --os linux --arch $(lastword $(subst /, ,$(p))) ; \ |
| 222 | + ) |
| 223 | + @echo "==> Pushing multi-arch manifest" |
| 224 | + @docker manifest push $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted |
| 225 | + @echo "==> Done! Image: $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted" |
| 226 | + |
| 227 | + |
| 228 | +# --------------------------------------------------------------------------- |
| 229 | +# Multi-arch encrypted + cosign-signed target |
| 230 | +# |
| 231 | +# Re-tags the per-arch encrypted images under a new manifest and |
| 232 | +# cosign-signs it, producing an image that is both encrypted and |
| 233 | +# cosign-signed under a separate tag. |
| 234 | +# --------------------------------------------------------------------------- |
| 235 | + |
| 236 | +multi-arch-encrypted-cosign-sig: multi-arch-encrypted |
| 237 | + @echo "==> Creating multi-arch-encrypted-cosign-sig manifest" |
| 238 | + @docker manifest rm $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted-cosign-sig 2>/dev/null || true |
| 239 | + @docker manifest create $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted-cosign-sig \ |
| 240 | + $(foreach p,$(PLATFORMS),$(REGISTRY)/$(COCO_PKG):encrypted-$(lastword $(subst /, ,$(p)))) |
| 241 | + @$(foreach p,$(PLATFORMS), \ |
| 242 | + docker manifest annotate $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted-cosign-sig \ |
| 243 | + $(REGISTRY)/$(COCO_PKG):encrypted-$(lastword $(subst /, ,$(p))) \ |
| 244 | + --os linux --arch $(lastword $(subst /, ,$(p))) ; \ |
| 245 | + ) |
| 246 | + @echo "==> Pushing multi-arch-encrypted-cosign-sig manifest" |
| 247 | + @docker manifest push $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted-cosign-sig |
| 248 | + @echo "==> Cosign-signing multi-arch-encrypted-cosign-sig" |
| 249 | + ${CURDIR}/scripts/make-cosign-sig.sh $(COCO_PKG) multi-arch-encrypted-cosign-sig $(REGISTRY) |
| 250 | + @echo "==> Done! Image: $(REGISTRY)/$(COCO_PKG):multi-arch-encrypted-cosign-sig" |
0 commit comments