diff --git a/README.md b/README.md index aeffa1e386809b7705c7f8b60d00572e04a96131..1edfbdda6d0249f00bd5a7327a2a1ecd77055ca1 100644 --- a/README.md +++ b/README.md @@ -243,7 +243,9 @@ The signing process can be configured with the following variables: | Input / Variable | Description | Default value | | --------------------------------------------------------- | -------------------------------------------- | --------------------- | | `cosign-strategy` / `DOCKER_COSIGN_STRATEGY` | Determines when images should be signed with [cosign](https://github.com/sigstore/cosign (`never`: disabled, `onrelease`: only on `$INTEG_REF`, `$PROD_REF` and `$RELEASE_REF` pipelines; `always`: any pipeline).
:warning: `cosign-enabled` / `DOCKER_COSIGN_ENABLED` takes precedence | `never` | -| `cosign-opts` / `DOCKER_COSIGN_OPTS` | Options for cosign | `--tlog-upload=false` | +| `cosign-opts` / `DOCKER_COSIGN_OPTS` | Options for [`cosign sign`](https://docs.sigstore.dev/cosign/signing/signing_with_containers/) command | `--tlog-upload=false --recursive` | +| `cosign-attest-opts` / `DOCKER_COSIGN_ATTEST_OPTS` | Options for [`cosign attest`](https://docs.sigstore.dev/cosign/verifying/attestation/) command + | `--tlog-upload=false` | | `cosign-dist-url` / `DOCKER_COSIGN_DIST_URL` | Url to the `linux-amd64` binary of Cosign to use (ex: `https://github.com/sigstore/cosign/releases/download/v2.5.0/cosign-linux-amd64`)
_When unset, the latest version will be used_ | _none_ | | :lock: `cosign-private-key` / `DOCKER_COSIGN_PRIVATE_KEY` | Private key used for signing the Docker image and the attestation | _none_ | | :lock: `cosign-password` / `COSIGN_PASSWORD` | Password of the private key | _none_ | diff --git a/kicker.json b/kicker.json index 0fac255dd4a2f7e1cee83697433581a048f94ba4..b8071b4d765394feba9462aaff9f2d83d39bff4d 100644 --- a/kicker.json +++ b/kicker.json @@ -231,7 +231,13 @@ }, { "name": "DOCKER_COSIGN_OPTS", - "description": "Options for cosign", + "description": "Options for [`cosign sign`](https://docs.sigstore.dev/cosign/signing/signing_with_containers/) command", + "default": "--tlog-upload=false --recursive", + "advanced": true + }, + { + "name": "DOCKER_COSIGN_ATTEST_OPTS", + "description": "Options for [`cosign attest`](https://docs.sigstore.dev/cosign/verifying/attestation/) command", "default": "--tlog-upload=false", "advanced": true }, diff --git a/templates/gitlab-ci-docker.yml b/templates/gitlab-ci-docker.yml index 6213abbed43de5b3520ede93f3296ecd35fc3ac9..d2ca9a6359ac4d33a145957c777bcd8b33fbea91 100644 --- a/templates/gitlab-ci-docker.yml +++ b/templates/gitlab-ci-docker.yml @@ -180,7 +180,10 @@ spec: - always default: never cosign-opts: - description: Options for cosign + description: Options for [`cosign sign`](https://docs.sigstore.dev/cosign/signing/signing_with_containers/) command + default: --tlog-upload=false --recursive + cosign-attest-opts: + description: Options for [`cosign attest`](https://docs.sigstore.dev/cosign/verifying/attestation/) command default: --tlog-upload=false cosign-dist-url: description: |- @@ -292,6 +295,7 @@ variables: COSIGN_YES: "true" # skip confirmation prompts for non-destructive operations DOCKER_COSIGN_STRATEGY: $[[ inputs.cosign-strategy ]] DOCKER_COSIGN_OPTS: $[[ inputs.cosign-opts ]] + DOCKER_COSIGN_ATTEST_OPTS: $[[ inputs.cosign-attest-opts ]] DOCKER_COSIGN_DIST_URL: $[[ inputs.cosign-dist-url ]] # default: one-click publish @@ -1333,7 +1337,7 @@ docker-sbom: log_info "Attaching attested SBOM to ${DOCKER_SNAPSHOT_IMAGE}..." install_cosign configure_cosign_private_key - $docker_cosign attest --key ${docker_cosign_private_key} ${DOCKER_COSIGN_OPTS} --predicate reports/docker-sbom-${basename}.cyclonedx.json ${DOCKER_SNAPSHOT_IMAGE} + $docker_cosign attest --key ${docker_cosign_private_key} ${DOCKER_COSIGN_ATTEST_OPTS} --predicate reports/docker-sbom-${basename}.cyclonedx.json ${DOCKER_SNAPSHOT_IMAGE} fi artifacts: name: "SBOM for docker from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" @@ -1396,7 +1400,7 @@ docker-publish: - BUILDTOOL_HOME=${BUILDTOOL_HOME:-$HOME} # 1: push main image - log_info "Copying ${DOCKER_SNAPSHOT_IMAGE} to ${DOCKER_RELEASE_IMAGE}..." - - skopeo copy ${TRACE+--debug} --all --src-authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --dest-authfile "$BUILDTOOL_HOME/skopeo/.docker/dest-config.json" ${DOCKER_PUBLISH_ARGS} "docker://$DOCKER_SNAPSHOT_IMAGE" "docker://$DOCKER_RELEASE_IMAGE" + - skopeo copy ${TRACE+--debug} --all --src-authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --dest-authfile "$BUILDTOOL_HOME/skopeo/.docker/dest-config.json" ${DOCKER_PUBLISH_ARGS} "docker://$DOCKER_SNAPSHOT_IMAGE" "docker://$DOCKER_RELEASE_IMAGE" | tee skopeo-copy.log - | if [[ ${DOCKER_COSIGN_STRATEGY} == "onrelease" ]] || [[ ${DOCKER_COSIGN_STRATEGY} == "always" ]] then @@ -1404,12 +1408,16 @@ docker-publish: release_repository=${DOCKER_RELEASE_IMAGE%:*} # extract snapshot image digest # ⚠ don't use upstream $docker_digest due to possible parallel matrix job producing several - docker_digest=$(skopeo inspect ${TRACE+--debug} --authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --format='{{ .Digest }}' "docker://$DOCKER_SNAPSHOT_IMAGE") - tag=$(echo "${docker_digest}" | tr ':' '-') - log_info "Copying image signature to ${release_repository}:${tag}.sig..." - skopeo copy ${TRACE+--debug} --src-authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --dest-authfile "$BUILDTOOL_HOME/skopeo/.docker/dest-config.json" ${DOCKER_PUBLISH_ARGS} "docker://${snapshot_repository}:${tag}.sig" "docker://${release_repository}:${tag}.sig" - log_info "Copying image attestation to ${release_repository}:${tag}.att..." - skopeo copy ${TRACE+--debug} --src-authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --dest-authfile "$BUILDTOOL_HOME/skopeo/.docker/dest-config.json" ${DOCKER_PUBLISH_ARGS} "docker://${snapshot_repository}:${tag}.att" "docker://${release_repository}:${tag}.att" + docker_digest=$(skopeo inspect ${TRACE+--debug} --authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --format='{{ .Digest }}' --no-tags "docker://$DOCKER_SNAPSHOT_IMAGE") + all_digests="$docker_digest"$'\n'"$(sed -nE 's|Copying image (sha256:[[:alnum:]]+).*|\1|p' skopeo-copy.log)" + echo "$all_digests" | tr ':' '-' | sed '/^[ \t]*$/d' | while read sha; do + log_info "Copying image signature to ${release_repository}:${sha}.sig..." + skopeo copy ${TRACE+--debug} --src-authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --dest-authfile "$BUILDTOOL_HOME/skopeo/.docker/dest-config.json" ${DOCKER_PUBLISH_ARGS} "docker://${snapshot_repository}:${sha}.sig" "docker://${release_repository}:${sha}.sig" \ + || log_warn "No signature found for ${sha}" + log_info "Copying image attestation to ${release_repository}:${sha}.att..." + skopeo copy ${TRACE+--debug} --src-authfile "$BUILDTOOL_HOME/skopeo/.docker/src-config.json" --dest-authfile "$BUILDTOOL_HOME/skopeo/.docker/dest-config.json" ${DOCKER_PUBLISH_ARGS} "docker://${snapshot_repository}:${sha}.att" "docker://${release_repository}:${sha}.att" \ + || log_warn "No attestation found for ${sha}" + done fi - | log_info "Well done your image is pushed and can be pulled with: docker pull $DOCKER_RELEASE_IMAGE"