From 5983dc5bad2d82abc738bf4c129f865022825ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Martins?= Date: Wed, 23 Sep 2026 14:37:27 +0200 Subject: [PATCH] ci: Add support for OIDC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for OIDC, replacing long-lived tokens. Quay.io has been configured accordingly. The token expires after one hour, so it is minted after each build rather than once at the start of the job. The robot account names are read from the QUAY_ROBOT_CI and QUAY_ROBOT_RELEASE variables, defined on the GitHub environments the jobs pin rather than at repository or organisation level, so the value a job receives is the one belonging to its environment. The environment name also forms the OIDC subject that the robot is configured to trust, so renaming an environment breaks the login. Signed-off-by: André Martins --- .github/workflows/build-envoy-image-ci.yaml | 146 ++++++++-- .../build-envoy-images-release-base.yaml | 256 +++++++++++++++--- .../build-envoy-images-release-debug.yaml | 6 +- .../workflows/build-envoy-images-release.yaml | 6 +- 4 files changed, 346 insertions(+), 68 deletions(-) diff --git a/.github/workflows/build-envoy-image-ci.yaml b/.github/workflows/build-envoy-image-ci.yaml index b284c453a..e18ec0646 100644 --- a/.github/workflows/build-envoy-image-ci.yaml +++ b/.github/workflows/build-envoy-image-ci.yaml @@ -6,8 +6,6 @@ on: permissions: # To be able to access the repository with `actions/checkout` contents: read - # Required to generate OIDC tokens for `sigstore/cosign-installer` authentication - id-token: write concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.after }} @@ -16,8 +14,15 @@ concurrency: jobs: build-and-push-prs: name: Build and push multi-arch images + permissions: + contents: read + # Required by the Quay OIDC token exchange and keyless cosign signing. + id-token: write + # Pins the OIDC token subject to + # repo:cilium/proxy:environment:publish-ci-images, which is the identity + # federated with the Quay robot account. environment: - name: ci-build + name: publish-ci-images deployment: false timeout-minutes: 360 runs-on: ${{ vars.PROXY_BUILD_GITHUB_RUNNER }} @@ -32,6 +37,24 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 + - name: Install skopeo + run: | + sudo apt-get update + sudo apt-get install -y skopeo + + - name: Install Cosign + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 + + - name: Install Bom + shell: bash + env: + # renovate: datasource=github-releases depName=kubernetes-sigs/bom + BOM_VERSION: v0.7.1 + run: | + curl -L https://github.com/kubernetes-sigs/bom/releases/download/${{ env.BOM_VERSION }}/bom-amd64-linux -o bom + sudo mv ./bom /usr/local/bin/bom + sudo chmod +x /usr/local/bin/bom + - name: Cache Docker layers uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -39,13 +62,6 @@ jobs: key: docker-cache-${{ github.head_ref }} restore-keys: docker-cache-main - - name: Login to quay.io - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 - with: - registry: quay.io - username: ${{ secrets.QUAY_ENVOY_USERNAME_DEV }} - password: ${{ secrets.QUAY_ENVOY_PASSWORD_DEV }} - - name: Checkout PR uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -77,7 +93,7 @@ jobs: echo exists="false" >> $GITHUB_OUTPUT fi - - name: PR Multi-arch build & push of Builder image (dev) + - name: PR Multi-arch build of Builder image (dev) uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' id: docker_build_builder_ci @@ -86,8 +102,61 @@ jobs: context: . file: ./Dockerfile.builder platforms: linux/amd64,linux/arm64 - push: true + push: false tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} + outputs: type=oci,dest=${{ runner.temp }}/builder-dev.tar + + # Quay's registry endpoint only accepts credentials or a JWT signed by + # Quay itself, so the GitHub OIDC token cannot be used as the registry + # password directly. Trade it for a short lived robot token first. + # + # Because the job references an environment, the subject of the token is + # repo:cilium@21054566/proxy@155294575:environment:publish-ci-images, the + # immutable form that carries the owner and repository ids. That is the + # identity federated with the robot account on the Quay side, so renaming + # the environment breaks the login. + # + # Quay gives the token one hour and the builds below take hours, so every + # artifact gets its own token once its build finishes. Nothing before the + # first push needs Quay auth: the builder tag lookup and the BUILDER_BASE + # and ARCHIVE_IMAGE pulls all read public repositories. + - name: Get a quay.io robot token via OIDC for the Builder image (dev) + id: token-builder-dev + if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' + env: + ROBOT: ${{ vars.QUAY_ROBOT_CI }} + run: | + oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ + -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ + | jq -er '.value')" + echo "::add-mask::${oidc_token}" + + # Pass the credentials on stdin so that the OIDC token is not visible + # in the process list of the runner. + robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ + | curl -sSf --retry 3 --retry-all-errors -K - \ + "https://quay.io/oauth2/federation/robot/token" \ + | jq -er '.token')" + echo "::add-mask::${robot_token}" + + echo "token=${robot_token}" >> "$GITHUB_OUTPUT" + + - name: Login to quay.io for the Builder image (dev) + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' + with: + registry: quay.io + username: ${{ vars.QUAY_ROBOT_CI }} + password: ${{ steps.token-builder-dev.outputs.token }} + + - name: PR Push of Builder image (dev) + if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' + run: | + skopeo copy --multi-arch all \ + "oci-archive:${{ runner.temp }}/builder-dev.tar" \ + docker://quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} + rm -f "${{ runner.temp }}/builder-dev.tar" - name: CI Builder Image Digest if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' @@ -96,7 +165,7 @@ jobs: echo "Digests:" echo "quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }}@${{ steps.docker_build_builder_ci.outputs.digest }}" - - name: PR Multi-arch build & push of cilium-envoy + - name: PR Multi-arch build of cilium-envoy uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 id: docker_build_ci with: @@ -110,25 +179,50 @@ jobs: BAZEL_BUILD_OPTS=--remote_upload_local_results=false cache-from: type=local,src=/tmp/buildx-cache cache-to: type=local,dest=/tmp/buildx-cache,mode=max - push: true + push: false tags: quay.io/${{ github.repository_owner }}/cilium-envoy-dev:${{ github.event.pull_request.head.sha }} + outputs: type=oci,dest=${{ runner.temp }}/cilium-envoy-dev.tar - - name: Install Cosign - uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 + # A token of its own for this push; see the token exchange above. The + # cosign and SBOM steps below write to quay.io with it too. + - name: Get a quay.io robot token via OIDC for cilium-envoy + id: token-cilium-envoy-dev + env: + ROBOT: ${{ vars.QUAY_ROBOT_CI }} + run: | + oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ + -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ + | jq -er '.value')" + echo "::add-mask::${oidc_token}" - - name: Sign Container Image + # Pass the credentials on stdin so that the OIDC token is not visible + # in the process list of the runner. + robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ + | curl -sSf --retry 3 --retry-all-errors -K - \ + "https://quay.io/oauth2/federation/robot/token" \ + | jq -er '.token')" + echo "::add-mask::${robot_token}" + + echo "token=${robot_token}" >> "$GITHUB_OUTPUT" + + - name: Login to quay.io for cilium-envoy + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: quay.io + username: ${{ vars.QUAY_ROBOT_CI }} + password: ${{ steps.token-cilium-envoy-dev.outputs.token }} + + - name: PR Push of cilium-envoy run: | - cosign sign -y quay.io/${{ github.repository_owner }}/cilium-envoy-dev@${{ steps.docker_build_ci.outputs.digest }} + skopeo copy --multi-arch all \ + "oci-archive:${{ runner.temp }}/cilium-envoy-dev.tar" \ + docker://quay.io/${{ github.repository_owner }}/cilium-envoy-dev:${{ github.event.pull_request.head.sha }} + rm -f "${{ runner.temp }}/cilium-envoy-dev.tar" - - name: Install Bom - shell: bash - env: - # renovate: datasource=github-releases depName=kubernetes-sigs/bom - BOM_VERSION: v0.7.1 + - name: Sign Container Image run: | - curl -L https://github.com/kubernetes-sigs/bom/releases/download/${{ env.BOM_VERSION }}/bom-amd64-linux -o bom - sudo mv ./bom /usr/local/bin/bom - sudo chmod +x /usr/local/bin/bom + cosign sign -y quay.io/${{ github.repository_owner }}/cilium-envoy-dev@${{ steps.docker_build_ci.outputs.digest }} - name: Generate SBOM shell: bash diff --git a/.github/workflows/build-envoy-images-release-base.yaml b/.github/workflows/build-envoy-images-release-base.yaml index 91cc5691d..c036bca60 100644 --- a/.github/workflows/build-envoy-images-release-base.yaml +++ b/.github/workflows/build-envoy-images-release-base.yaml @@ -7,19 +7,10 @@ on: required: false type: boolean default: false - secrets: - QUAY_ENVOY_USERNAME: - description: 'Quay.io username for Envoy image registry' - required: true - QUAY_ENVOY_PASSWORD: - description: 'Quay.io password for Envoy image registry' - required: true permissions: # To be able to access the repository with `actions/checkout` contents: read - # Required to generate OIDC tokens for `sigstore/cosign-installer` authentication - id-token: write concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -28,6 +19,13 @@ concurrency: jobs: test-cache-refresh: name: Build test cache and push images + permissions: + contents: read + # Required to generate OIDC tokens for `sigstore/cosign-installer` authentication + id-token: write + # Pins the OIDC token subject to + # repo:cilium/proxy:environment:release-base-images, which is the identity + # federated with the Quay robot account. environment: name: release-base-images deployment: false @@ -42,12 +40,10 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - - name: Login to quay.io - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 - with: - registry: quay.io - username: ${{ secrets.QUAY_ENVOY_USERNAME }} - password: ${{ secrets.QUAY_ENVOY_PASSWORD }} + - name: Install skopeo + run: | + sudo apt-get update + sudo apt-get install -y skopeo - name: Checkout source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -77,7 +73,7 @@ jobs: repo: cilium images: cilium-envoy-builder - - name: Run integration tests on amd64 & push of test artifact archive + - name: Run integration tests on amd64 & build of test artifact archive uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 id: docker_tests_ci_cache_update with: @@ -93,11 +89,66 @@ jobs: BAZEL_BUILD_OPTS=--remote_upload_local_results=false BAZEL_TEST_OPTS=--test_timeout=300 --local_test_jobs=1 --flaky_test_attempts=3 cache-to: type=local,dest=/tmp/buildx-cache,mode=max - push: true + push: false tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder:test-${{ github.ref_name }}-archive-latest + outputs: type=oci,dest=${{ runner.temp }}/test-archive.tar + + # Quay's registry endpoint only accepts credentials or a JWT signed by + # Quay itself, so the GitHub OIDC token cannot be used as the registry + # password directly. Trade it for a short lived robot token first. + # + # Because the job references an environment, the subject of the token is + # repo:cilium@21054566/proxy@155294575:environment:release-base-images, the + # immutable form that carries the owner and repository ids. That is the + # identity federated with the robot account on the Quay side, so renaming + # the environment breaks the login. + # + # Quay gives the token one hour and the build above takes hours, so this + # step mints the token once the build finishes. + - name: Get a quay.io robot token via OIDC for the test artifact archive + id: token-test-archive + env: + ROBOT: ${{ vars.QUAY_ROBOT_RELEASE }} + run: | + oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ + -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ + | jq -er '.value')" + echo "::add-mask::${oidc_token}" + + # Pass the credentials on stdin so that the OIDC token is not visible + # in the process list of the runner. + robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ + | curl -sSf --retry 3 --retry-all-errors -K - \ + "https://quay.io/oauth2/federation/robot/token" \ + | jq -er '.token')" + echo "::add-mask::${robot_token}" + + echo "token=${robot_token}" >> "$GITHUB_OUTPUT" + + - name: Login to quay.io for the test artifact archive + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: quay.io + username: ${{ vars.QUAY_ROBOT_RELEASE }} + password: ${{ steps.token-test-archive.outputs.token }} + + - name: Push of test artifact archive + run: | + skopeo copy --multi-arch all \ + "oci-archive:${{ runner.temp }}/test-archive.tar" \ + docker://quay.io/${{ github.repository_owner }}/cilium-envoy-builder:test-${{ github.ref_name }}-archive-latest + rm -f "${{ runner.temp }}/test-archive.tar" build-cache-and-push-images: name: Build cache and push images + permissions: + contents: read + # Required by the Quay OIDC token exchange and keyless cosign signing. + id-token: write + # Pins the OIDC token subject to + # repo:cilium/proxy:environment:release-base-images, which is the identity + # federated with the Quay robot account. environment: name: release-base-images deployment: false @@ -111,12 +162,10 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - - name: Login to quay.io - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 - with: - registry: quay.io - username: ${{ secrets.QUAY_ENVOY_USERNAME }} - password: ${{ secrets.QUAY_ENVOY_PASSWORD }} + - name: Install skopeo + run: | + sudo apt-get update + sudo apt-get install -y skopeo - name: Checkout source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -138,7 +187,7 @@ jobs: echo exists="false" >> $GITHUB_OUTPUT fi - - name: Multi-arch build & push of Builder image + - name: Multi-arch build of Builder image uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' id: docker_build_builder @@ -147,11 +196,65 @@ jobs: context: . file: ./Dockerfile.builder platforms: linux/amd64,linux/arm64 - push: true - tags: | - quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ env.BUILDER_DOCKER_HASH }} - quay.io/${{ github.repository_owner }}/cilium-envoy-builder:latest - - name: Multi-arch build & push of build artifact archive + push: false + tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ env.BUILDER_DOCKER_HASH }} + outputs: type=oci,dest=${{ runner.temp }}/builder.tar + + # Quay's registry endpoint only accepts credentials or a JWT signed by + # Quay itself, so the GitHub OIDC token cannot be used as the registry + # password directly. Trade it for a short lived robot token first. + # + # Because the job references an environment, the subject of the token is + # repo:cilium@21054566/proxy@155294575:environment:release-base-images, the + # immutable form that carries the owner and repository ids. That is the + # identity federated with the robot account on the Quay side, so renaming + # the environment breaks the login. + # + # Quay gives the token one hour and the builds below take hours, so every + # artifact gets its own token once its build finishes. Nothing before the + # first push needs Quay auth: the builder tag lookup and the BUILDER_BASE + # and ARCHIVE_IMAGE pulls all read public repositories. + - name: Get a quay.io robot token via OIDC for the Builder image + id: token-builder + if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' + env: + ROBOT: ${{ vars.QUAY_ROBOT_RELEASE }} + run: | + oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ + -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ + | jq -er '.value')" + echo "::add-mask::${oidc_token}" + + # Pass the credentials on stdin so that the OIDC token is not visible + # in the process list of the runner. + robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ + | curl -sSf --retry 3 --retry-all-errors -K - \ + "https://quay.io/oauth2/federation/robot/token" \ + | jq -er '.token')" + echo "::add-mask::${robot_token}" + + echo "token=${robot_token}" >> "$GITHUB_OUTPUT" + + - name: Login to quay.io for the Builder image + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' + with: + registry: quay.io + username: ${{ vars.QUAY_ROBOT_RELEASE }} + password: ${{ steps.token-builder.outputs.token }} + + - name: Push of Builder image + if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' + run: | + for tag in ${{ env.BUILDER_DOCKER_HASH }} latest; do + skopeo copy --multi-arch all \ + "oci-archive:${{ runner.temp }}/builder.tar" \ + "docker://quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${tag}" + done + rm -f "${{ runner.temp }}/builder.tar" + + - name: Multi-arch build of build artifact archive uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 with: context: . @@ -163,8 +266,45 @@ jobs: ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest COPY_CACHE_EXT=.new BAZEL_BUILD_OPTS="--jobs=HOST_CPUS*.75" - push: true + push: false tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest + outputs: type=oci,dest=${{ runner.temp }}/archive.tar + + # A token of its own for this push; see the token exchange above. + - name: Get a quay.io robot token via OIDC for the build artifact archive + id: token-archive + env: + ROBOT: ${{ vars.QUAY_ROBOT_RELEASE }} + run: | + oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ + -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ + | jq -er '.value')" + echo "::add-mask::${oidc_token}" + + # Pass the credentials on stdin so that the OIDC token is not visible + # in the process list of the runner. + robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ + | curl -sSf --retry 3 --retry-all-errors -K - \ + "https://quay.io/oauth2/federation/robot/token" \ + | jq -er '.token')" + echo "::add-mask::${robot_token}" + + echo "token=${robot_token}" >> "$GITHUB_OUTPUT" + + - name: Login to quay.io for the build artifact archive + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: quay.io + username: ${{ vars.QUAY_ROBOT_RELEASE }} + password: ${{ steps.token-archive.outputs.token }} + + - name: Push of build artifact archive + run: | + skopeo copy --multi-arch all \ + "oci-archive:${{ runner.temp }}/archive.tar" \ + docker://quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest + rm -f "${{ runner.temp }}/archive.tar" - name: Cache Docker layers uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -177,7 +317,7 @@ jobs: rm -rf /tmp/buildx-cache/* docker buildx prune -f - - name: Multi-arch build & push main latest + - name: Multi-arch build main latest uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 id: docker_build_cd with: @@ -191,13 +331,53 @@ jobs: ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest RELEASE_DEBUG=${{ inputs.release_debug && '1' || '' }} cache-to: type=local,dest=/tmp/buildx-cache,mode=max - push: true - tags: | - quay.io/${{ github.repository_owner }}/cilium-envoy:latest - quay.io/${{ github.repository_owner }}/cilium-envoy:${{ github.sha }} - quay.io/${{ github.repository_owner }}/cilium-envoy:${{ env.ENVOY_MINOR_RELEASE }}-${{ github.sha }} - quay.io/${{ github.repository_owner }}/cilium-envoy:${{ env.ENVOY_PATCH_RELEASE }}-${{ github.sha }} - quay.io/${{ github.repository_owner }}/cilium-envoy:${{ env.ENVOY_PATCH_RELEASE }}-${{ env.SOURCE_TIMESTAMP }}-${{ github.sha }} + push: false + tags: quay.io/${{ github.repository_owner }}/cilium-envoy:${{ github.sha }} + outputs: type=oci,dest=${{ runner.temp }}/main.tar + + # A token of its own for this push; see the token exchange above. The + # cosign and SBOM steps at the end of the job write to quay.io with it too. + - name: Get a quay.io robot token via OIDC for main latest + id: token-main + env: + ROBOT: ${{ vars.QUAY_ROBOT_RELEASE }} + run: | + oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ + -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ + | jq -er '.value')" + echo "::add-mask::${oidc_token}" + + # Pass the credentials on stdin so that the OIDC token is not visible + # in the process list of the runner. + robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ + | curl -sSf --retry 3 --retry-all-errors -K - \ + "https://quay.io/oauth2/federation/robot/token" \ + | jq -er '.token')" + echo "::add-mask::${robot_token}" + + echo "token=${robot_token}" >> "$GITHUB_OUTPUT" + + - name: Login to quay.io for main latest + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: quay.io + username: ${{ vars.QUAY_ROBOT_RELEASE }} + password: ${{ steps.token-main.outputs.token }} + + - name: Push of main latest + run: | + for tag in \ + latest \ + ${{ github.sha }} \ + ${{ env.ENVOY_MINOR_RELEASE }}-${{ github.sha }} \ + ${{ env.ENVOY_PATCH_RELEASE }}-${{ github.sha }} \ + ${{ env.ENVOY_PATCH_RELEASE }}-${{ env.SOURCE_TIMESTAMP }}-${{ github.sha }}; do + skopeo copy --multi-arch all \ + "oci-archive:${{ runner.temp }}/main.tar" \ + "docker://quay.io/${{ github.repository_owner }}/cilium-envoy:${tag}" + done + rm -f "${{ runner.temp }}/main.tar" - name: Install Cosign uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 diff --git a/.github/workflows/build-envoy-images-release-debug.yaml b/.github/workflows/build-envoy-images-release-debug.yaml index 9008d55fe..bd765da50 100644 --- a/.github/workflows/build-envoy-images-release-debug.yaml +++ b/.github/workflows/build-envoy-images-release-debug.yaml @@ -3,12 +3,14 @@ on: workflow_dispatch: permissions: - id-token: write contents: read jobs: build-envoy-images-release-debug: + permissions: + contents: read + # Required by the Quay OIDC token exchange in the called workflow. + id-token: write uses: ./.github/workflows/build-envoy-images-release-base.yaml with: release_debug: true - secrets: inherit diff --git a/.github/workflows/build-envoy-images-release.yaml b/.github/workflows/build-envoy-images-release.yaml index 47165dcab..6e4d17f52 100644 --- a/.github/workflows/build-envoy-images-release.yaml +++ b/.github/workflows/build-envoy-images-release.yaml @@ -6,11 +6,13 @@ on: permissions: contents: read - id-token: write jobs: build-envoy-images-release: + permissions: + contents: read + # Required by the Quay OIDC token exchange in the called workflow. + id-token: write uses: ./.github/workflows/build-envoy-images-release-base.yaml with: release_debug: false - secrets: inherit