diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000000..158a90d4c1 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,39 @@ +# Workflows + +| Workflow | Description | +|---------------------|-----------------------------------------------------------------| +| changelog.yml | Updates changelog when a release is published | +| codeql.yaml | CodeQL analysis | +| docker-publish.yaml | Build container image for PR's & publish for push events | +| image-reuse.yaml | Build, push, and Sign container images | +| go.yaml | lint, build, codegen | +| pr-title-check.yaml | Lint PR for semantic information | +| init-release.yaml | Build manifests and version then create a PR for release branch | +| release.yaml | Build images, cli-binaries, provenances, and post actions | + + +# Reusable workflows + +## image-reuse.yaml + +- The resuable workflow can be used to publish or build images with multiple container registries(Quay,GHCR, dockerhub), and then sign them with cosign when an image is published. +- A GO version `must` be specified e.g. 1.19 +- The image name for each registry *must* contain the tag. Note: multiple tags are allowed for each registry using a CSV type. +- Multiple platforms can be specified e.g. linux/amd64,linux/arm64 +- Images are not published by default. A boolean value must be set to `true` to push images. +- An optional target can be specified. + +| Inputs | Description | Type | Required | Defaults | +|-------------------|-------------------------------------|-------------|----------|-----------------| +| go-version | Version of Go to be used | string | true | none | +| quay_image_name | Full image name and tag | CSV, string | false | none | +| ghcr_image_name | Full image name and tag | CSV, string | false | none | +| docker_image_name | Full image name and tag | CSV, string | false | none | +| platforms | Platforms to build (linux/amd64) | CSV, string | false | linux/amd64 | +| push | Whether to push image/s to registry | boolean | false | false | +| target | Target build stage | string | false | none | + +| Outputs | Description | Type | +|-------------|------------------------------------------|-------| +|image-digest | Image digest of image container created | string| + diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 8794e839d9..ceaf0b0d49 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,132 +1,178 @@ name: Release - on: - workflow_dispatch: - inputs: - tag: - description: Git tag to build release from - required: true - update_stable_tag: - description: 'Update stable tag' - required: true - type: boolean - default: 'false' -permissions: - contents: read + push: + tags: + - 'v*' + +permissions: {} + +env: + GOLANG_VERSION: '1.19' # Note: go-version must also be set in job controller-image.with.go-version & plugin-image.with.go-version. jobs: - release-images: + controller-image: + permissions: + contents: read + packages: write # Required and used to push images to `ghcr.io` if used. + id-token: write # For creating OIDC tokens for signing. + uses: ./.github/workflows/image-reuse.yaml + with: + quay_image_name: quay.io/argoproj/argo-rollouts:${{ github.ref_name }} + # Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations) + go-version: 1.19 + platforms: linux/amd64,linux/arm64 + push: true + secrets: + quay_username: ${{ secrets.QUAY_USERNAME }} + quay_password: ${{ secrets.QUAY_ROBOT_TOKEN }} + + plugin-image: + permissions: + contents: read + packages: write # Required and used to push images to `ghcr.io` if used. + id-token: write # For creating OIDC tokens for signing. + uses: ./.github/workflows/image-reuse.yaml + with: + quay_image_name: quay.io/argoproj/kubectl-argo-rollouts:${{ github.ref_name }} + # Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations) + go-version: 1.19 + platforms: linux/amd64,linux/arm64 + push: true + target: kubectl-argo-rollouts + secrets: + quay_username: ${{ secrets.QUAY_USERNAME }} + quay_password: ${{ secrets.QUAY_ROBOT_TOKEN }} + + controller-image-provenance: + needs: + - controller-image + permissions: + actions: read # for detecting the Github Actions environment. + id-token: write # for creating OIDC tokens for signing. + packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues) + # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.6.0 + with: + image: quay.io/argoproj/argo-rollouts + digest: ${{ needs.controller-image.outputs.image-digest }} + secrets: + registry-username: ${{ secrets.QUAY_USERNAME }} + registry-password: ${{ secrets.QUAY_ROBOT_TOKEN }} + + plugin-image-provenance: + needs: + - plugin-image + permissions: + actions: read # for detecting the Github Actions environment. + id-token: write # for creating OIDC tokens for signing. + packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues) + # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.6.0 + with: + image: quay.io/argoproj/kubectl-argo-rollouts + digest: ${{ needs.plugin-image.outputs.image-digest }} + secrets: + registry-username: ${{ secrets.QUAY_USERNAME }} + registry-password: ${{ secrets.QUAY_ROBOT_TOKEN }} + + + release-artifacts: + permissions: + contents: write # for softprops/action-gh-release to create GitHub release runs-on: ubuntu-latest + outputs: + hashes: ${{ steps.hash.outputs.hashes }} steps: - name: Checkout - uses: actions/checkout@v3.1.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: - ref: ${{ github.event.inputs.tag }} + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} - - name: Get SHA - id: get-sha - run: echo "::set-output name=sha::$(git log -1 --format='%H')" + - name: Setup Golang + uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + with: + go-version: ${{ env.GOLANG_VERSION }} - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - config-inline: | - [worker.oci] - gc = false + uses: docker/setup-buildx-action@4b4e9c3e2d4531116a6f8ba8e71fc6e2cb6e6c8c # v2.5.0 - - name: Print Disk Usage + - name: Generate release artifacts run: | - df -ah - docker buildx du + make release-plugins + make checksums + make manifests IMAGE_TAG=${{ github.ref_name }} - - name: Docker meta (controller) - id: controller-meta - uses: docker/metadata-action@v4 - with: - images: | - quay.io/argoproj/argo-rollouts - # ghcr.io/argoproj/argo-rollouts - tags: | - type=semver,pattern={{version}},prefix=v,value=${{ github.event.inputs.tag }} - flavor: | - latest=false - - - name: Docker meta (plugin) - id: plugin-meta - uses: docker/metadata-action@v4 - with: - images: | - quay.io/argoproj/kubectl-argo-rollouts - # ghcr.io/argoproj/kubectl-argo-rollouts - tags: | - type=semver,pattern={{version}},prefix=v,value=${{ github.event.inputs.tag }} - flavor: | - latest=false - - # - name: Login to GitHub Container Registry - # if: github.event_name != 'pull_request' - # uses: docker/login-action@v2 - # with: - # registry: ghcr.io - # username: ${{ github.repository_owner }} - # password: ${{ secrets.GITHUB_TOKEN }} - - - name: Login to Quay.io - if: github.event_name != 'pull_request' - uses: docker/login-action@v2 + - name: Draft release + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 with: - registry: quay.io - username: ${{ secrets.QUAY_USERNAME }} - password: ${{ secrets.QUAY_ROBOT_TOKEN }} + tag_name: ${{ github.event.inputs.tag }} + draft: true + files: | + dist/kubectl-argo-rollouts-linux-amd64 + dist/kubectl-argo-rollouts-linux-arm64 + dist/kubectl-argo-rollouts-darwin-amd64 + dist/kubectl-argo-rollouts-darwin-arm64 + dist/kubectl-argo-rollouts-windows-amd64 + dist/argo-rollouts-checksums.txt + manifests/dashboard-install.yaml + manifests/install.yaml + manifests/namespace-install.yaml + manifests/notifications-install.yaml + docs/features/kustomize/rollout_cr_schema.json + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push (controller-image) - uses: docker/build-push-action@37abcedcc1da61a57767b7588cb9d03eb57e28b3 # v3.3.0 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.controller-meta.outputs.tags }} - provenance: false - sbom: false - - - name: Build and push (plugin-image) - uses: docker/build-push-action@37abcedcc1da61a57767b7588cb9d03eb57e28b3 # v3.3.0 - with: - context: . - target: kubectl-argo-rollouts - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.plugin-meta.outputs.tags }} - provenance: false - sbom: false + - name: Generate hashes for provenance + id: hash + run: | + echo "hashes=$(sha256sum ./dist/kubectl-argo-rollouts-* ./manifests/*.yaml | base64 -w0)" >> "$GITHUB_OUTPUT" - release-artifacts: + release-artifacts-provenance: + needs: + - release-artifacts permissions: - contents: write # for softprops/action-gh-release to create GitHub release + actions: read # for detecting the Github Actions environment + id-token: write # Needed for provenance signing and ID + contents: write # Needed for release uploads + # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.6.0 + with: + base64-subjects: "${{ needs.release-artifacts.outputs.hashes }}" + provenance-name: "argo-rollouts.intoto.jsonl" + upload-assets: true + draft-release: true + + generate-sbom: + name: Create Sbom and sign assets + needs: + - release-artifacts + - release-artifacts-provenance + permissions: + contents: write # Needed for release uploads + id-token: write # Needed for signing Sbom runs-on: ubuntu-latest - needs: release-images - steps: - - name: Checkout - uses: actions/checkout@v3.1.0 + - name: Checkout code + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.3.0 with: - ref: ${{ github.event.inputs.tag }} + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Golang - uses: actions/setup-go@v3 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: 1.19 + go-version: ${{ env.GOLANG_VERSION }} - - name: Generate release artifacts - run: | - make release-plugins - make checksums - make manifests IMAGE_TAG=${{ github.event.inputs.tag }} + - name: Install cosign + uses: sigstore/cosign-installer@204a51a57a74d190b284a0ce69b44bc37201f343 # v3.0.3 + with: + cosign-release: 'v2.0.2' - name: Generate SBOM (spdx) id: spdx-builder @@ -138,8 +184,8 @@ jobs: # comma delimited list of project relative folders to inspect for package # managers (gomod, yarn, npm). PROJECT_FOLDERS: ".,./ui" - # full qualified name of the docker image to be inspected - DOCKER_IMAGE: quay.io/argoproj/argo-rollouts:${{ github.event.inputs.tag }} + # full qualified name of the container image to be inspected + CONTAINER_IMAGE: quay.io/argoproj/argo-rollouts:${{ github.event.inputs.tag }} run: | yarn install --cwd ./ui @@ -152,82 +198,74 @@ jobs: generator -p $folder -o /tmp done - # Generate SPDX for binaries analyzing the docker image - if [[ ! -z $DOCKER_IMAGE ]]; then - bom generate -o /tmp/bom-docker-image.spdx -i $DOCKER_IMAGE + # Generate SPDX for binaries analyzing the container image + if [[ ! -z CONTAINER_IMAGE ]]; then + bom generate -o /tmp/bom-docker-image.spdx -i $CONTAINER_IMAGE fi cd /tmp && tar -zcf sbom.tar.gz *.spdx - - name: Login to Quay.io - if: github.event_name != 'pull_request' - uses: docker/login-action@v2 - with: - registry: quay.io - username: ${{ secrets.QUAY_USERNAME }} - password: ${{ secrets.QUAY_ROBOT_TOKEN }} + - name: Sign SBOM + run: | + cosign sign-blob \ + --output-certificate=/tmp/sbom.tar.gz.pem \ + --output-signature=/tmp/sbom.tar.gz.sig \ + --yes \ + /tmp/sbom.tar.gz - - name: Install cosign - uses: sigstore/cosign-installer@main + - name: Upload SBOM and signature assets + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - cosign-release: 'v1.13.1' + tag_name: ${{ github.ref_name }} + draft: true + files: | + /tmp/sbom.tar.* - - name: Install crane to get digest of image - uses: imjasonh/setup-crane@v0.2 + post-release: + needs: + - release-artifacts + - generate-sbom + permissions: + contents: write # Needed to push commit to update stable tag + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.3.0 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} - - name: Get digest of controller-image + - name: Setup Git author information run: | - echo "CONTROLLER_DIGEST=$(crane digest quay.io/argoproj/argo-rollouts:${{ github.event.inputs.tag }})" >> $GITHUB_ENV + set -ue + git config --global user.email 'ci@argoproj.com' + git config --global user.name 'CI' - - name: Get digest of plugin-image + - name: Check if tag is the latest version and not a pre-release run: | - echo "PLUGIN_DIGEST=$(crane digest quay.io/argoproj/kubectl-argo-rollouts:${{ github.event.inputs.tag }})" >> $GITHUB_ENV + set -xue + # Fetch all tag information + git fetch --prune --tags --force - - name: Sign Argo Rollouts Images - run: | - cosign sign --key env://COSIGN_PRIVATE_KEY quay.io/argoproj/argo-rollouts@${{ env.CONTROLLER_DIGEST }} - cosign sign --key env://COSIGN_PRIVATE_KEY quay.io/argoproj/kubectl-argo-rollouts@${{ env.PLUGIN_DIGEST }} - env: - COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}} - COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}} + LATEST_TAG=$(git -c 'versionsort.suffix=-rc' tag --list --sort=version:refname | tail -n1) - - name: Sign checksums and create public key for release assets - run: | - cosign sign-blob --key env://COSIGN_PRIVATE_KEY ./dist/argo-rollouts-checksums.txt > ./dist/argo-rollouts-checksums.sig - cosign public-key --key env://COSIGN_PRIVATE_KEY > ./dist/argo-rollouts-cosign.pub - cosign sign-blob --key env://COSIGN_PRIVATE_KEY /tmp/sbom.tar.gz > /tmp/sbom.tar.gz.sig - # Displays the public key to share. - cosign public-key --key env://COSIGN_PRIVATE_KEY - env: - COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}} - COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}} + PRE_RELEASE=false + # Check if latest tag is a pre-release + if echo $LATEST_TAG | grep -E -- '-rc[0-9]+$';then + PRE_RELEASE=true + fi - - name: update stable tag for docs + # Ensure latest tag matches github.ref_name & not a pre-release + if [[ $LATEST_TAG == ${{ github.ref_name }} ]] && [[ $PRE_RELEASE != 'true' ]];then + echo "TAG_STABLE=true" >> $GITHUB_ENV + else + echo "TAG_STABLE=false" >> $GITHUB_ENV + fi + + - name: Update stable tag to latest version run: | - git tag -f stable ${{ github.event.inputs.tag }} + git tag -f stable ${{ github.ref_name }} git push -f origin stable - if: ${{ inputs.update_stable_tag }} - - - name: Draft release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ github.event.inputs.tag }} - draft: true - files: | - dist/kubectl-argo-rollouts-linux-amd64 - dist/kubectl-argo-rollouts-linux-arm64 - dist/kubectl-argo-rollouts-darwin-amd64 - dist/kubectl-argo-rollouts-darwin-arm64 - dist/kubectl-argo-rollouts-windows-amd64 - dist/argo-rollouts-checksums.txt - dist/argo-rollouts-checksums.sig - dist/argo-rollouts-cosign.pub - manifests/dashboard-install.yaml - manifests/install.yaml - manifests/namespace-install.yaml - manifests/notifications-install.yaml - docs/features/kustomize/rollout_cr_schema.json - /tmp/sbom.tar.gz - /tmp/sbom.tar.gz.sig - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: ${{ env.TAG_STABLE == 'true' }} \ No newline at end of file diff --git a/docs/release-action.png b/docs/release-action.png deleted file mode 100644 index 6c0dc61f5f..0000000000 Binary files a/docs/release-action.png and /dev/null differ diff --git a/docs/releasing.md b/docs/releasing.md index d4571c076c..5b0fc7780a 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -1,45 +1,62 @@ # Releasing -1. Tag a commit to release from using semantic versioning (e.g. v1.0.0-rc1) +1. Ensure that the `release branch` already exist. -1. Visit the [Release GitHub Action](https://github.com/argoproj/argo-rollouts/actions/workflows/release.yaml) - and enter the tag. +1. Checkout the release branch. Example: `git fetch upstream && git + checkout release-1.5` -1. To automatically update the stable tag, select `Update stable tag`. (false by default) +1. Run the script found at `hack/trigger-release.sh` as follows: -[![GitHub Release Action](release-action.png)](release-action.png) +```shell +./hack/trigger-release.sh +``` + +Example: +```shell +./hack/trigger-release.sh v1.6.0-rc1 upstream +``` + +!!! tip +The tag must be in one of the following formats to trigger the GH workflow:
+* GA: `v..`
+* Pre-release: `v..-rc` + +Once the script is executed successfully, a GitHub workflow will start +execution. You can follow its progress under the [Actions](https://github.com/argoproj/argo-rollouts/actions/workflows/release.yaml) tab, the name of the action is `Release`. 1. When the action completes, visit the generated draft [Github releases](https://github.com/argoproj/argo-rollouts/releases) and enter the details about the release: - * Getting started (copy from previous release and new version) - * Changelog + * Getting started (copy from previous release and new version) + * Changelog + +### Update Brew formula 1. Update Brew formula: - * Fork the repo https://github.com/argoproj/homebrew-tap - * Run the following commands to update the brew formula: + * Fork the repo https://github.com/argoproj/homebrew-tap + * Run the following commands to update the brew formula: ```bash cd homebrew-tap ./update.sh kubectl-argo-rollouts $VERSION ``` - * If there is a new minor version we want to update the versioned formula as well: - * Run the following commands to update the versioned brew formula: - ```bash - ./update.sh kubectl-argo-rollouts $VERSION @ - ``` - * Example: If the new version is `v1.3.2`, we want to update the formula for `v1.3` as well. + * If there is a new minor version we want to update the versioned formula as well: + * Run the following commands to update the versioned brew formula: ```bash - ./update.sh kubectl-argo-rollouts v1.3.2 @1.3 + ./update.sh kubectl-argo-rollouts $VERSION @ ``` - * Commit and push the changes to your fork - ```bash - git commit -am "Update kubectl-argo-rollouts to $VERSION" - ``` - * Create a PR with the modified files pointing to upstream/master - * Once the PR is approved by a maintainer, it can be merged. + * Example: If the new version is `v1.3.2`, we want to update the formula for `v1.3` as well. + ```bash + ./update.sh kubectl-argo-rollouts v1.3.2 @1.3 + ``` + * Commit and push the changes to your fork + ```bash + git commit -am "Update kubectl-argo-rollouts to $VERSION" + ``` + * Create a PR with the modified files pointing to upstream/master + * Once the PR is approved by a maintainer, it can be merged. ### Verify -1. Install locally using the command below and follow the [Getting Started Guide](https://argoproj.github.io/argo-rollouts/getting-started/): +1. Install locally using the command below and follow the [Getting Started Guide](https://argo-rollouts.readthedocs.io/en/stable/getting-started/): ```bash kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/download/${VERSION}/install.yaml @@ -50,4 +67,4 @@ ```bash brew upgrade kubectl-argo-rollouts kubectl argo rollouts version - ``` + ``` \ No newline at end of file diff --git a/docs/security.md b/docs/security/security.md similarity index 100% rename from docs/security.md rename to docs/security/security.md diff --git a/docs/security/signed-release-assets.md b/docs/security/signed-release-assets.md new file mode 100644 index 0000000000..7f6bf3bbfd --- /dev/null +++ b/docs/security/signed-release-assets.md @@ -0,0 +1,116 @@ +# Verification of Argo Rollouts Artifacts + +## Prerequisites +- cosign `v2.0.0` or higher [installation instructions](https://docs.sigstore.dev/cosign/installation) +- slsa-verifier [installation instructions](https://github.com/slsa-framework/slsa-verifier#installation) + +*** +## Release Assets +| Asset | Description | +|-------------------------------------|--------------------------------------------------| +| argo-rollouts-checksums.txt | Checksums of binaries | +| argo-rollouts-cli.intoto.jsonl | Attestation of CLI binaries & manifiest | +| dashboard-install.yaml | Dashboard install | +| install.yaml | Standard installation method | +| kubectl-argo-rollouts-darwin-amd64 | CLI Binary | +| kubectl-argo-rollouts-darwin-arm64 | CLI Binary | +| kubectl-argo-rollouts-linux-amd64 | CLI Binary | +| kubectl-argo-rollouts-linux-arm64 | CLI Binary | +| kubectl-argo-rollouts-windows-amd64 | CLI Binary | +| namespace-install.yaml | Namespace installation | +| notifications-install.yaml | Notification installation | +| rollout_cr_schema.json | Schema | +| sbom.tar.gz | Sbom | +| sbom.tar.gz.pem | Certificate used to sign sbom | +| sbom.tar.gz.sig | Signature of sbom | + +*** +## Verification of container images + +Argo Rollouts container images are signed by [cosign](https://github.com/sigstore/cosign) using identity-based ("keyless") signing and transparency. Executing the following command can be used to verify the signature of a container image: + +```bash +cosign verify \ +--certificate-identity-regexp https://github.com/argoproj/argo-rollouts/.github/workflows/image-reuse.yaml@refs/tags/v \ +--certificate-oidc-issuer https://token.actions.githubusercontent.com \ +quay.io/argoproj/argo-rollouts:v1.5.0 | jq +``` +The command should output the following if the container image was correctly verified: +```bash +The following checks were performed on each of these signatures: + - The cosign claims were validated + - Existence of the claims in the transparency log was verified offline + - The code-signing certificate was verified using trusted certificate authority certificates +[ + { + "critical": { + "identity": { + "docker-reference": "quay.io/argoproj/argo-rollouts" + }, + "image": { + "docker-manifest-digest": "sha256:519522f8c66c7b4c468f360ebe6c8ba07b8d64f5f948e71ae52c01b9953e1eb9" + }, + "type": "cosign container image signature" + }, + "optional": { + "1.3.6.1.4.1.57264.1.1": "https://token.actions.githubusercontent.com", + "1.3.6.1.4.1.57264.1.2": "push", + "1.3.6.1.4.1.57264.1.3": "aa1afcb418fcebcc68b063377c48225f5a9d1511", + "1.3.6.1.4.1.57264.1.4": "Release", + "1.3.6.1.4.1.57264.1.5": "argoproj/argo-rollouts", + "1.3.6.1.4.1.57264.1.6": "refs/tags/v1.5.0", + ... +``` + +*** +## Verification of container image attestations + +A [SLSA](https://slsa.dev/) Level 3 provenance is generated using [slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator). + +The following command will verify the signature of an attestation and how it was issued. It will contain the payloadType, payload, and signature. +```bash +cosign verify-attestation --type slsaprovenance \ +--certificate-identity-regexp https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v \ +--certificate-oidc-issuer https://token.actions.githubusercontent.com \ +quay.io/argoproj/argo-rollouts:v1.5.0 | jq +``` +The payload is a non-falsifiable provenance which is base64 encoded and can be viewed by using the command below: +```bash +cosign verify-attestation --type slsaprovenance \ +--certificate-identity-regexp https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v \ +--certificate-oidc-issuer https://token.actions.githubusercontent.com \ +quay.io/argoproj/argo-rollouts:v1.5.0 | jq -r .payload | base64 -d | jq +``` +!!! tip + `cosign` or `slsa-verifier` can both be used to verify image attestations. + Check the documentation of each binary for detailed instructions. + +*** +## Verification of CLI artifacts with attestations + +A single attestation (`argo-rollouts.intoto.jsonl`) from each release is provided. This can be used with [slsa-verifier](https://github.com/slsa-framework/slsa-verifier#verification-for-github-builders) to verify that a CLI binary or manifest was generated using Argo Rollouts workflows on GitHub and ensures it was cryptographically signed. +```bash +slsa-verifier verify-artifact kubectl-argo-rollouts-linux-amd64 --provenance-path kubectl-argo-rollouts.intoto.jsonl --source-uri github.com/argoproj/argo-rollouts +``` +## Verifying an artifact and output the provenance + +```bash +slsa-verifier verify-artifact kubectl-argo-rollouts-linux-amd64 --provenance-path kubectl-argo-rollouts.intoto.jsonl --source-uri github.com/argoproj/argo-rollouts --print-provenance | jq +``` +## Verification of Sbom + +```bash +cosign verify-blob --signature sbom.tar.gz.sig --certificate sbom.tar.gz.pem \ +--certificate-identity-regexp ^https://github.com/argoproj/argo-rollouts/.github/workflows/release.yaml@refs/tags/v \ +--certificate-oidc-issuer https://token.actions.githubusercontent.com \ + ~/Downloads/sbom.tar.gz | jq +``` + +*** +## Verification on Kubernetes + +### Policy controllers +!!! note + We encourage all users to verify signatures and provenances with your admission/policy controller of choice. Doing so will verify that an image was built by us before it's deployed on your Kubernetes cluster. + +Cosign signatures and SLSA provenances are compatible with several types of admission controllers. Please see the [cosign documentation](https://docs.sigstore.dev/cosign/overview/#kubernetes-integrations) and [slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#verification) for supported controllers. diff --git a/hack/trigger-release.sh b/hack/trigger-release.sh new file mode 100755 index 0000000000..b7f843fad7 --- /dev/null +++ b/hack/trigger-release.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# This script requires bash shell - sorry. + +NEW_TAG="${1}" +GIT_REMOTE="${2}" + +set -ue + +if test "${NEW_TAG}" = "" -o "${GIT_REMOTE}" = ""; then + echo "!! Usage: $0 " >&2 + exit 1 +fi + +# Target (version) tag must match version scheme vMAJOR.MINOR.PATCH with an +# optional pre-release tag. +if ! echo "${NEW_TAG}" | egrep -q '^v[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)*$'; then + echo "!! Malformed version tag: '${NEW_TAG}', must match 'vMAJOR.MINOR.PATCH(-rcX)'" >&2 + exit 1 +fi + +# Check whether we are in correct branch of local repository +RELEASE_BRANCH="${NEW_TAG%\.[0-9]*}" +RELEASE_BRANCH="release-${RELEASE_BRANCH#*v}" + +currentBranch=$(git branch --show-current) +if test "$currentBranch" != "${RELEASE_BRANCH}"; then + echo "!! Please checkout branch '${RELEASE_BRANCH}' (currently in branch: '${currentBranch}')" >&2 + exit 1 +fi + +echo ">> Working in release branch '${RELEASE_BRANCH}'" + +echo ">> Ensuring release branch is up to date." +# make sure release branch is up to date +git pull ${GIT_REMOTE} ${RELEASE_BRANCH} + +# Check for target (version) tag in local repo +if git tag -l | grep -q -E "^${NEW_TAG}$"; then + echo "!! Target version tag '${NEW_TAG}' already exists in local repository" >&2 + exit 1 +fi + +# Check for target (version) tag in remote repo +if git ls-remote ${GIT_REMOTE} refs/tags/${NEW_TAG} | grep -q -E "${NEW_TAG}$"; then + echo "!! Target version tag '${NEW_TAG}' already exists in remote '${GIT_REMOTE}'" >&2 + exit 1 +fi + +echo ">> Creating new release '${NEW_TAG}' by pushing '${NEW_TAG}' to '${GIT_REMOTE}'" + +# Create new tag in local repository +git tag ${NEW_TAG} + +# Push the new tag to remote repository +git push ${GIT_REMOTE} ${NEW_TAG} diff --git a/mkdocs.yml b/mkdocs.yml index 3781e5d314..48e39a2578 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -124,8 +124,10 @@ nav: - Best Practices: best-practices.md - Migrating: migrating.md - FAQ: FAQ.md -- Security: security.md -- Roadmap: roadmap.md +- Security: + - Security Policy: security/security.md + - Verify Release Artifacts: security/signed-release-assets.md +- Roadmap/Release Schedule: roadmap.md - Contributing: - Contribution Guide: CONTRIBUTING.md - Environment Setup: getting-started/setup/index.md