Skip to content

Commit

Permalink
Publish Kubernetes content container image on each commit
Browse files Browse the repository at this point in the history
This adds a GitHub action that will trigger a container build for each
commit merged to the `master` branch. These commits will also be signed
with cosign. The registry used is the GitHub Container Registry, which
allows us to host containers for open source projects without a fee.

Signed-off-by: Juan Antonio Osorio <juan.osoriorobles@eu.equinix.com>
  • Loading branch information
JAORMX committed Apr 27, 2022
1 parent 8e3f9b1 commit d2bb8c2
Showing 1 changed file with 161 additions and 0 deletions.
161 changes: 161 additions & 0 deletions .github/workflows/k8s-content.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
name: Kubernetes content

on:
push:
branches: [ 'master' ]

env:
COSIGN_EXPERIMENTAL: 1
IMAGE_NAME: ghcr.io/ComplianceAsCode/k8scontent

jobs:
container:
runs-on: ubuntu-latest

permissions:
packages: write

outputs:
image-digest: ${{ steps.container_info.outputs.image-digest }}
image-tags: ${{ steps.container_info.outputs.image-tags }}


steps:
- name: Checkout
uses: actions/checkout@v3

- name: Login to ghcr.io
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# TODO: Rename ocp4_content to k8s_content and make it more general
- name: Build container image
run: |
revision="$(git rev-parse "${GITHUB_REF_NAME:-HEAD}")"
docker build \
-f ./Dockerfiles/ocp4_content \
-t "${IMAGE_NAME}:latest" \
-t "${IMAGE_NAME}:${GITHUB_REF_NAME}" \
-t "${IMAGE_NAME}:${revision}" \
--label "org.opencontainers.image.source=https://github.com/ComplianceAsCode/content" \
--label "org.opencontainers.image.created=$(date --iso-8601=seconds)" \
--label "org.opencontainers.image.title=k8scontent" \
--label "org.opencontainers.image.revision=${revision}" \
--label "org.opencontainers.image.version=${GITHUB_REF_NAME}" \
--label "org.opencontainers.image.licenses=BSD" \
.
- name: Publish Container images
run: docker push "${IMAGE_NAME}" --all-tags

- name: Get container info
id: container_info
run: |
image_digest="$(docker inspect "${IMAGE_NAME}:latest" --format '{{ index .RepoDigests 0 }}' | awk -F '@' '{ print $2 }')"
image_tags="latest,${GITHUB_REF_NAME},$(git rev-parse "${GITHUB_REF_NAME:-HEAD}")"
echo "::set-output name=image-digest::${image_digest}"
echo "::set-output name=image-tags::${image_tags}"
sign:
runs-on: ubuntu-latest
needs: [container]

permissions:
packages: write
id-token: write

env:
IMAGE_DIGEST: ${{ needs.container.outputs.image-digest }}

steps:
- name: Install cosign
uses: sigstore/cosign-installer@v2.2.1

- name: Login to ghcr.io
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Sign image
run: |
cosign sign "${IMAGE_NAME}@${IMAGE_DIGEST}"
echo "::notice title=Verify signature::COSIGN_EXPERIMENTAL=1 cosign verify ${IMAGE_NAME}@${IMAGE_DIGEST} | jq '.[0]'"
echo "::notice title=Inspect signature bundle::COSIGN_EXPERIMENTAL=1 cosign verify ${IMAGE_NAME}@${IMAGE_DIGEST} | jq '.[0].optional.Bundle.Payload.body |= @base64d | .[0].optional.Bundle.Payload.body | fromjson'"
echo "::notice title=Inspect certificate::COSIGN_EXPERIMENTAL=1 cosign verify ${IMAGE_NAME}@${IMAGE_DIGEST} | jq -r '.[0].optional.Bundle.Payload.body |= @base64d | .[0].optional.Bundle.Payload.body | fromjson | .spec.signature.publicKey.content |= @base64d | .spec.signature.publicKey.content' | openssl x509 -text"
sbom:
runs-on: ubuntu-latest
needs: [container]

permissions:
packages: write
id-token: write

env:
IMAGE_DIGEST: ${{ needs.container.outputs.image-digest }}

steps:
- name: Install cosign
uses: sigstore/cosign-installer@v2.2.1

- name: Install Syft
uses: anchore/sbom-action/download-syft@v0.11.0

- name: Login to ghcr.io
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Attach SBOM to image
run: |
syft "${IMAGE_NAME}@${IMAGE_DIGEST}" -o spdx-json=sbom-spdx.json
cosign attest --predicate sbom-spdx.json --type spdx "${IMAGE_NAME}@${IMAGE_DIGEST}"
echo "::notice title=Verify SBOM attestation::COSIGN_EXPERIMENTAL=1 cosign verify-attestation ${IMAGE_NAME}@${IMAGE_DIGEST} | jq '.payload |= @base64d | .payload | fromjson | select(.predicateType == \"https://spdx.dev/Document\") | .predicate.Data | fromjson'"
provenance:
runs-on: ubuntu-latest
needs: [container]

permissions:
packages: write
id-token: write

env:
IMAGE_DIGEST: ${{ needs.container.outputs.image-digest }}
PROVENANCE_FILE: provenance.att

steps:
- name: Install cosign
uses: sigstore/cosign-installer@v2.2.1

- name: Generate provenance
uses: philips-labs/slsa-provenance-action@v0.7.2
with:
command: generate
subcommand: container
arguments: --repository "${IMAGE_NAME}" --output-path "${PROVENANCE_FILE}" --digest "${IMAGE_DIGEST}" --tags "${IMAGE_TAGS}"
env:
COSIGN_EXPERIMENTAL: 0
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
IMAGE_TAGS: ${{ needs.container.outputs.image-tags }}

- name: Login to ghcr.io
uses: docker/login-action@v1.14.1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Attach provenance
run: |
jq '.predicate' "${PROVENANCE_FILE}" > provenance-predicate.att
cosign attest --predicate provenance-predicate.att --type slsaprovenance "${IMAGE_NAME}@${IMAGE_DIGEST}"
echo "::notice title=Verify provenance attestation::COSIGN_EXPERIMENTAL=1 cosign verify-attestation ${IMAGE_NAME}@${IMAGE_DIGEST} | jq '.payload |= @base64d | .payload | fromjson | select(.predicateType == \"https://slsa.dev/provenance/v0.2\")'"

0 comments on commit d2bb8c2

Please sign in to comment.