Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update cosign #1201

Merged
merged 3 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 8 additions & 17 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ jobs:
- test-linux-arm64
- test-windows
runs-on: ubuntu-latest
permissions:
id-token: write
Comment on lines +114 to +115
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -192,20 +194,6 @@ jobs:
- name: Set env
run: |
cat tag.txt >> $GITHUB_ENV
- name: Rename cosign public key
run: |
cp cosign.pub lifecycle-v${{ env.LIFECYCLE_VERSION }}-cosign.pub
- uses: actions/upload-artifact@v3
with:
name: lifecycle-cosign-public-key
path: lifecycle-v${{ env.LIFECYCLE_VERSION }}-cosign.pub
- name: Calculate cosign sha
run: |
shasum -a 256 lifecycle-v${{ env.LIFECYCLE_VERSION }}-cosign.pub > lifecycle-v${{ env.LIFECYCLE_VERSION }}-cosign.pub.sha256
- uses: actions/upload-artifact@v3
with:
name: lifecycle-cosign-public-key-sha256
path: lifecycle-v${{ env.LIFECYCLE_VERSION }}-cosign.pub.sha256
- name: Publish images
if: github.event_name == 'push'
run: |
Expand All @@ -229,11 +217,14 @@ jobs:
MANIFEST_SHA=$(docker manifest push buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG})
echo "MANIFEST_SHA: $MANIFEST_SHA"

COSIGN_PASSWORD=${{ secrets.COSIGN_PASSWORD }} cosign sign -r --tlog-upload=false \
--key <(echo -n "${{ secrets.COSIGN_PRIVATE_KEY }}" | base64 --decode) \
cosign sign -r -y \
-a tag=${LIFECYCLE_IMAGE_TAG} \
buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}@${MANIFEST_SHA}
cosign verify --insecure-ignore-tlog=true --key cosign.pub -a tag=${LIFECYCLE_IMAGE_TAG} buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}
cosign verify \
--certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/build.yml" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
-a tag=${LIFECYCLE_IMAGE_TAG} \
buildpacksio/lifecycle:${LIFECYCLE_IMAGE_TAG}
- name: Scan image
if: github.event_name == 'push'
uses: anchore/scan-action@v3
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/draft-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ on:
jobs:
draft-release:
runs-on: ubuntu-latest
permissions:
contents: write
Comment on lines +9 to +10
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the repo "Actions permissions" settings to use the more restrictive "Read repository contents and package permissions" instead of the more permissive "Read and write permissions", thus this is now required.

steps:
- uses: actions/checkout@v4
- name: Install jq
Expand Down Expand Up @@ -80,8 +82,8 @@ jobs:
if (urlList.length === 0) {
throw "no artifacts found"
}
if (urlList.length != 10) {
throw "there should be exactly ten artifacts"
if (urlList.length != 8) {
throw "there should be exactly 8 artifacts"
}
return urlList.join(",")
})
Expand Down
52 changes: 33 additions & 19 deletions .github/workflows/post-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
jobs:
retag-lifecycle-images:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- name: Setup go
Expand All @@ -30,15 +32,15 @@ jobs:
echo "LIFECYCLE_IMAGE_TAG=$(git describe --always --abbrev=7)" >> $GITHUB_ENV
- name: Verify lifecycle images
run: |
LINUX_AMD64_SHA=$(cosign verify -key cosign.pub buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-x86-64 | jq -r .[0].critical.image.\"docker-manifest-digest\")
LINUX_AMD64_SHA=$(cosign verify --certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/build.yml" --certificate-oidc-issuer https://token.actions.githubusercontent.com buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-x86-64 | jq -r .[0].critical.image.\"docker-manifest-digest\")
echo "LINUX_AMD64_SHA: $LINUX_AMD64_SHA"
echo "LINUX_AMD64_SHA=$LINUX_AMD64_SHA" >> $GITHUB_ENV

LINUX_ARM64_SHA=$(cosign verify -key cosign.pub buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-arm64 | jq -r .[0].critical.image.\"docker-manifest-digest\")
LINUX_ARM64_SHA=$(cosign verify --certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/build.yml" --certificate-oidc-issuer https://token.actions.githubusercontent.com buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-linux-arm64 | jq -r .[0].critical.image.\"docker-manifest-digest\")
echo "LINUX_ARM64_SHA: $LINUX_ARM64_SHA"
echo "LINUX_ARM64_SHA=$LINUX_ARM64_SHA" >> $GITHUB_ENV

WINDOWS_AMD64_SHA=$(cosign verify -key cosign.pub buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-windows | jq -r .[0].critical.image.\"docker-manifest-digest\")
WINDOWS_AMD64_SHA=$(cosign verify --certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/build.yml" --certificate-oidc-issuer https://token.actions.githubusercontent.com buildpacksio/lifecycle:${{ env.LIFECYCLE_IMAGE_TAG }}-windows | jq -r .[0].critical.image.\"docker-manifest-digest\")
echo "WINDOWS_AMD64_SHA: $WINDOWS_AMD64_SHA"
echo "WINDOWS_AMD64_SHA=$WINDOWS_AMD64_SHA" >> $GITHUB_ENV
- name: Download SBOM
Expand All @@ -62,18 +64,24 @@ jobs:
MANIFEST_SHA=$(docker manifest push buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }})
echo "MANIFEST_SHA: $MANIFEST_SHA"

COSIGN_PASSWORD=${{ secrets.COSIGN_PASSWORD }} cosign sign -r \
-key <(echo -n "${{ secrets.COSIGN_PRIVATE_KEY }}" | base64 --decode) \
cosign sign -r -y \
-a tag=${{ env.LIFECYCLE_VERSION }} \
buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}@${MANIFEST_SHA}
cosign verify -key cosign.pub -a tag=${{ env.LIFECYCLE_VERSION }} buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}
cosign verify \
--certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/post-release.yml" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
-a tag=${{ env.LIFECYCLE_VERSION }} \
buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}

cosign attach sbom -sbom ./*-bom.cdx.json -type cyclonedx buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}
COSIGN_PASSWORD=${{ secrets.COSIGN_PASSWORD }} cosign sign -r \
-key <(echo -n "${{ secrets.COSIGN_PRIVATE_KEY }}" | base64 --decode) \
-a tag=${{ env.LIFECYCLE_VERSION }} -attachment sbom \
cosign attach sbom --sbom ./*-bom.cdx.json --type cyclonedx buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}
cosign sign -r -y \
-a tag=${{ env.LIFECYCLE_VERSION }} --attachment sbom \
buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}@${MANIFEST_SHA}
cosign verify -key cosign.pub -a tag=${{ env.LIFECYCLE_VERSION }} -attachment sbom buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}@${MANIFEST_SHA}
cosign verify \
--certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/post-release.yml" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
-a tag=${{ env.LIFECYCLE_VERSION }} --attachment sbom \
buildpacksio/lifecycle:${{ env.LIFECYCLE_VERSION }}
- name: Retag lifecycle images & create manifest list - latest
if: "!contains(env.LIFECYCLE_VERSION, 'rc') && !contains(env.LIFECYCLE_VERSION, 'pre')"
run: |
Expand All @@ -91,15 +99,21 @@ jobs:
MANIFEST_SHA=$(docker manifest push buildpacksio/lifecycle:latest)
echo "MANIFEST_SHA: $MANIFEST_SHA"

COSIGN_PASSWORD=${{ secrets.COSIGN_PASSWORD }} cosign sign -r \
-key <(echo -n "${{ secrets.COSIGN_PRIVATE_KEY }}" | base64 --decode) \
cosign sign -r -y \
-a tag=latest \
buildpacksio/lifecycle:latest@${MANIFEST_SHA}
cosign verify -key cosign.pub -a tag=latest buildpacksio/lifecycle:latest
cosign verify \
--certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/post-release.yml" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
-a tag=latest \
buildpacksio/lifecycle:latest

cosign attach sbom -sbom ./*-bom.cdx.json -type cyclonedx buildpacksio/lifecycle:latest
COSIGN_PASSWORD=${{ secrets.COSIGN_PASSWORD }} cosign sign -r \
-key <(echo -n "${{ secrets.COSIGN_PRIVATE_KEY }}" | base64 --decode) \
-a tag=${{ env.LIFECYCLE_VERSION }} -attachment sbom \
cosign attach sbom --sbom ./*-bom.cdx.json --type cyclonedx buildpacksio/lifecycle:latest
cosign sign -r -y \
-a tag=${{ env.LIFECYCLE_VERSION }} --attachment sbom \
buildpacksio/lifecycle:latest@${MANIFEST_SHA}
cosign verify -key cosign.pub -a tag=${{ env.LIFECYCLE_VERSION }} -attachment sbom buildpacksio/lifecycle:latest@${MANIFEST_SHA}
cosign verify \
--certificate-identity-regexp "https://github.com/${{ github.repository_owner }}/lifecycle/.github/workflows/post-release.yml" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
-a tag=${{ env.LIFECYCLE_VERSION }} --attachment sbom \
buildpacksio/lifecycle:latest
6 changes: 2 additions & 4 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,18 @@

The lifecycle release process involves chaining a series of GitHub actions together such that:
* The "build" workflow creates the artifacts
* .tgz files containing the lifecycle binaries, shasums for the .tgz files, a cosign public key, an SBOM, etc.
* .tgz files containing the lifecycle binaries, shasums for the .tgz files, an SBOM, etc.
* OCI images containing the lifecycle binaries, tagged with their commit sha (for more information, see RELEASE.md)
* The "draft-release" workflow finds the artifacts and downloads them, creating the draft release
* The "post-release" workflow re-tags the OCI images that were created during the "build" workflow with the release version

It can be rather cumbersome to test changes to these workflows, as they are heavily intertwined. Thus we recommend forking the buildpacks/lifecycle repository in GitHub and running through the entire release process end-to-end.
For the fork, it is necessary to add the following secrets:
* COSIGN_PASSWORD (see [cosign](https://github.com/sigstore/cosign#generate-a-keypair))
* COSIGN_PRIVATE_KEY
* DOCKER_PASSWORD (if not using ghcr.io)
* DOCKER_USERNAME (if not using ghcr.io)

The tools/test-fork.sh script can be used to update the source code to reflect the state of the fork.
It can be invoked like so: `./tools/test-fork.sh <registry repo name> <path to cosign public key>`
It can be invoked like so: `./tools/test-fork.sh <registry repo name>`

## Tasks

Expand Down
16 changes: 11 additions & 5 deletions IMAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,24 @@ Supported tags are semver-versioned manifest lists - e.g., `0.12.0` or `0.12.0-r
# About this image

Images are built in [GitHub actions](https://github.com/buildpacks/lifecycle/actions) and signed with [`cosign`](https://github.com/sigstore/cosign). To verify:
* Locate the public key `lifecycle-v<tag>-cosign.pub` on the [releases page](https://github.com/buildpacks/lifecycle/releases)
* Run:
```
cosign verify -key lifecycle-v<tag>-cosign.pub buildpacksio/lifecycle:<tag>
cosign version # must be at least 2.0.0
cosign verify \
--certificate-identity-regexp "https://github.com/buildpacks/lifecycle/.github/workflows/post-release.yml" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
buildpacksio/lifecycle:<tag>
```

A CycloneDX SBOM is "attached" to the image and signed with [`cosign`](https://github.com/sigstore/cosign). To verify:
* Locate the public key `lifecycle-v<tag>-cosign.pub` on the [releases page](https://github.com/buildpacks/lifecycle/releases)
* Run:
```
cosign version # must be at least 1.2.0
cosign verify -key cosign.pub -a tag=<tag> -attachment sbom buildpacksio/lifecycle:<tag>
cosign version # must be at least 2.0.0
cosign verify \
--certificate-identity-regexp "https://github.com/buildpacks/lifecycle/.github/workflows/post-release.yml" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
-a tag=<tag> -attachment sbom \
buildpacksio/lifecycle:<tag>
cosign download sbom buildpacksio/lifecycle:<tag>
```

Expand Down
5 changes: 0 additions & 5 deletions cosign.pub

This file was deleted.

8 changes: 2 additions & 6 deletions tools/test-fork.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#!/bin/bash

# $1 - registry repo name
# $2 - path to cosign public key
# $3 - enable tests
# $2 - enable tests

echo "Parse registry: $1"
firstPart=$(echo $1 | cut -d/ -f1)
Expand Down Expand Up @@ -42,14 +41,11 @@ if [[ $registry == *"ghcr.io"* ]]; then
sed -i '' "s/secrets.DOCKER_PASSWORD/secrets.GITHUB_TOKEN/g" .github/workflows/*.yml
fi

echo "Using public key from fork (assumes base-64 encoded COSIGN_PRIVATE_KEY and COSIGN_PASSWORD have been added to GitHub secrets)"
cp $2 cosign.pub

echo "Removing arm tests (these require a self-hosted runner)"
sed -i '' "/test-linux-arm64:/,+14d" .github/workflows/build.yml
sed -i '' "/test-linux-arm64/d" .github/workflows/build.yml

if [[ -z $3 ]]; then
if [[ -z $2 ]]; then
echo "Removing all tests to make things faster"
sed -i '' "s/make test/echo test/g" .github/workflows/*.yml
sed -i '' "s/make acceptance/echo acceptance/g" .github/workflows/*.yml
Expand Down