Skip to content

BobyMCbobs/gha-sync-scan-and-build

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

gha-sync-scan-and-build

Test GHA for image syncing, scanning and building

Purpose

  • sync to vendor images
  • build container images
  • run security scans again each destination image in configuration
  • separate implementation from the data
    • implementation can be swapped out underneath, if need be and maintain the function

The repo is mostly concerned with base images or images used in build processes.

Features

  • declarative image sync management, given source and destination
  • declarative apko build management
    • with Melange (Alpine APK building) integration
    • generated SBOMs
    • container image signing
  • automatic security scanning for each image synced and built
  • multiple build modes
    • apko
    • apko + melange
    • docker (fallback)
  • automatic trigger of builds, sync and scan every week

Layout

the structure of the repo is as follows:

  • config.yaml: define configuration about runtime
  • images/NAME/{images.yaml|Dockerfile,*}: images to build configurations
  • .github/workflows/{sync,scan,build}.yml: lifecycle actions

Set up

  1. specify images for syncing and building in the respective sync and build fields
  2. set the image push GitHub secrets of QUAY_USERNAME and QUAY_ROBOT_TOKEN

Usage

Sync an image

Images are synced by specifying source and destinations like this

sync:
  - source: docker.io/alpine:latest
    destination: ghcr.io/somecoolorg/images/alpine:latest

Images will only be synced if the digest of the source and destination don't match or if the sync[].always key is set to true

Build with apko

Images for building are specified with the source being an apko formatted YAML file and an image destination

build:
  - source: ./images/acoolthing/image.yaml
    destination: ghcr.io/somecoolorg/images/acoolthing:latest

with ./images/acoolthing/image.yaml being something like this

contents:
  repositories:
    - https://dl-cdn.alpinelinux.org/alpine/v3.17/main
    - https://dl-cdn.alpinelinux.org/alpine/v3.17/community
  packages:
    - alpine-base
    - busybox
    - ca-certificates-bundle

entrypoint:
  command: /bin/sh -c

archs:
- x86_64
- aarch64

Build with apko and Melange

Specify a source, destination and as many melangeConfigs

build:
  - source: ./images/coolthing/image.yaml
    destination: ghcr.io/somecoolorg/images/coolthing:latest
    melangeConfigs:
      - ./images/coolthing/pkg-hello.yaml

with each melange config being a path to the package to build. An entry in the apko YAML must be set contents.repositories[last index] to @local /github/workspace/packages, then packages can be installed with NAME@local; like this apko configuration

contents:
  repositories:
    - https://dl-cdn.alpinelinux.org/alpine/v3.17/main
    - https://dl-cdn.alpinelinux.org/alpine/v3.17/community
    - '@local /github/workspace/packages'
  packages:
    - alpine-base
    - busybox
    - ca-certificates-bundle
    - hello@local

entrypoint:
  command: /bin/sh -c

archs:
- x86_64

Build with Docker

Only use this if you have to. It is better to build with apko.

Images can be built with Docker like this

build:
  - source: ./images/oldschool/Dockerfile
    destination: ghcr.io/somecoolorg/images/oldschool:latest
    dockerOptions:
      context: ./images/oldschool

Tips

What is an image ref?

IMAGE_REF refers to an image reference in the format of either

  • ghcr.io/somecoolorg/images/hello:latest (just a tag)
  • ghcr.io/somecoolorg/images/hello@sha256:a61743b19423a01827ba68a1ec81a09d04f84bc69848303905ecbc73824fb88b (just a digest)
  • ghcr.io/somecoolorg/images/hello:latest@sha256:a61743b19423a01827ba68a1ec81a09d04f84bc69848303905ecbc73824fb88b (a tag and a digest)

Obtaining a digest

the digest can be obtained through

crane digest IMAGE_REF

to use it, it can be included when an image ref is formatted like the examples above in What is an image ref?.

Tagging built images

determine the digest of the image, for example given the image is ghcr.io/somecoolorg/images/hello:latest

crane digest ghcr.io/somecoolorg/images/hello:latest

the digest might be sha256:a61743b19423a01827ba68a1ec81a09d04f84bc69848303905ecbc73824fb88b.

add a new sync image to the sync key like

  - source: ghcr.io/somecoolorg/images/hello@sha256:a61743b19423a01827ba68a1ec81a09d04f84bc69848303905ecbc73824fb88b
    destination: ghcr.io/somecoolorg/images/hello:some-cool-tag

Verifying images

Images are signed using cosign with keyless, this means that

  • signatures depend on the build or key infrastructure
  • there's no worry of key rotation

Images are able to be verified through

cosign verify IMAGE_REF \
  --certificate-identity https://github.com/BobyMCbobs/gha-sync-scan-and-build/.github/workflows/sync.yml@refs/heads/main \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

please note: the certificate identity field will vary between

See the tree of attached signatures and SBOMs

produces a nice and readible tree of signatures, attestations and SBOMs related to the IMAGE_REF

cosign tree IMAGE_REF

View the SBOM in the attestation

verify the attestation

cosign verify-attestation IMAGE_REF --certificate-identity https://github.com/BobyMCbobs/gha-sync-scan-and-build/.github/workflows/sync.yml@refs/heads/main \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

since SBOMs are the predicate of a signed attestation instead of just uploaded, it requires an extra layer to retrieve their content

cosign verify-attestation IMAGE_REF --certificate-identity https://github.com/BobyMCbobs/gha-sync-scan-and-build/.github/workflows/sync.yml@refs/heads/main \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com | jq -r .payload | base64 -d | jq -r .predicate.Data

using sigs.k8s.io/bom, the SBOM attestation can be visualised

🐚 cosign verify-attestation IMAGE_REF --certificate-identity https://github.com/BobyMCbobs/gha-sync-scan-and-build/.github/workflows/sync.yml@refs/heads/main \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com | jq -r .payload | base64 -d | jq -r .predicate.Data | bom document outline -

Verification for ghcr.io/bobymcbobs/gha-sync-scan-and-build/hello:latest --
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 signatures were verified against the specified public key
&{Version:SPDX-2.3 DataLicense:CC0-1.0 ID:SPDXRef-DOCUMENT Name:sbom-sha256:e1097a462313187e2a61ba229179efafa8e62bd6166dc94698c9dcffdff05c9c Namespace:https://spdx.org/spdxdocs/apko/ Creator:{Person: Organization:Chainguard, Inc Tool:[apko (v0.7.3-45-g39b16b5)]} Created:1970-01-01 00:00:00 +0000 UTC LicenseListVersion:3.16 Packages:map[SPDXRef-Package-sha256-63bd196f274790f29c3956c9df4a8525aacec14c1c2ecb684cf7462c53f0471f:0xc000314000] Files:map[] ExternalDocRefs:[]}
PACKAGE:  <nil>
               _      
 ___ _ __   __| |_  __
/ __| '_ \ / _` \ \/ /
\__ \ |_) | (_| |>  < 
|___/ .__/ \__,_/_/\_\
    |_|               

 πŸ“‚ SPDX Document sbom-sha256:e1097a462313187e2a61ba229179efafa8e62bd6166dc94698c9dcffdff05c9c
  β”‚ 
  β”‚ πŸ“¦ DESCRIBES 1 Packages
  β”‚ 
  β”œ sha256:63bd196f274790f29c3956c9df4a8525aacec14c1c2ecb684cf7462c53f0471f
  β”‚  β”‚ πŸ”— 2 Relationships
  β”‚  β”œ CONTAINS PACKAGE sha256:e1097a462313187e2a61ba229179efafa8e62bd6166dc94698c9dcffdff05c9c@unknown
  β”‚  β”‚  β”‚ πŸ”— 4 Relationships
  β”‚  β”‚  β”œ CONTAINS PACKAGE alpine-baselayout-data@3.4.0-r0
  β”‚  β”‚  β”œ CONTAINS PACKAGE ca-certificates-bundle@20220614-r4
  β”‚  β”‚  β”œ CONTAINS PACKAGE musl@1.2.3-r4
  β”‚  β”‚  β”” CONTAINS PACKAGE hello@2.12-r0
  β”‚  β”‚  β”‚  β”‚ πŸ”— 3 Relationships
  β”‚  β”‚  β”‚  β”œ CONTAINS FILE /usr/bin/hello (/usr/bin/hello)
  β”‚  β”‚  β”‚  β”œ CONTAINS FILE /usr/share/info/hello.info (/usr/share/info/hello.info)
  β”‚  β”‚  β”‚  β”” CONTAINS FILE /usr/share/man/man1/hello.1 (/usr/share/man/man1/hello.1)
  β”‚  β”‚  β”‚ 
  β”‚  β”‚ 
  β”‚  β”” GENERATED_FROM PACKAGE github.com/BobyMCbobs/gha-sync-scan-and-build@6d8476f50ccdd7864eb0d46b2036f44516a55336
  β”‚ 
  β”” πŸ“„ DESCRIBES 0 Files

Tooling

Name Description Links Related/Alternatives
crane an officially supported cli container registry tool from Google https://github.com/google/go-containerregistry/tree/main/cmd/crane skopeo
yq a cli YAML parser https://github.com/mikefarah/yq jq
cosign a cli container image artifact signing utility by Sigstore (Linux Foundation) https://github.com/sigstore/cosign ...
melange a cli Alpine APK package declarative builder supported by Chainguard https://github.com/chainguard-dev/melange ...
apko a cli tool for declaratively building Alpine based container images https://github.com/chainguard-dev/apko ko (https://ko.build - Linux Foundation)
docker a container ecosystem, primarily for development https://docker.io podman
trivy a container image scanner https://github.com/aquasecurity/trivy clair
syft a cli tool to generate sboms based on container images and filesystems https://github.com/anchore/syft

Patterns for discussion

semi-related topics

Good reads

About

Test GHA for image syncing, scanning and building

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages