feat: judge, sign and verify netOrk's images in one place (NetOrk/netork#1390)
CI / Tests, lint (push) Successful in 18s

The CIS gate, the SBOM, the cosign signature and the matcher's verdict lived
in NetOrk/base-os, the head of the chain. Every link below it -- base-python,
engine, ui, satellite, the service images -- needs the same, so the tools
move here, and every image repository pins them by commit.

- image_tools: cis.py, cis_os.sh, sbom.py and verify.py from base-os. The
  image's own repository holds its cis.toml and packages.allow; both default
  to the working directory.
- bin/sign.sh signs whatever platforms a reference holds: base-os's index of
  amd64 and arm64 (EXPECT_PLATFORMS) or a dev image's single manifest
  (image_tools/platforms.py).
- bin/verify-base.sh checks every FROM image of a Dockerfile against
  cosign.pub before a build; one without a digest is refused
  (image_tools/dockerfile.py).
- bin/install-cosign.sh installs cosign v3.1.3 for amd64 and arm64 runners,
  checked against the release checksums.
- actions/verify-base, judge, sign wrap them for the workflows.
- cosign.pub is the public half of the COSIGN_PRIVATE_KEY_B64 org secret,
  the key rotated on 2026-10-22.
This commit is contained in:
Christian Manivong committed 2026-10-22 16:23:00 +02:00
commit d139d66c3d
27 files changed
+2085

No files matched your search

+45
View File
@@ -0,0 +1,45 @@
name: Judge an image
description: >-
The CIS gate (image_tools/cis.py) and the CycloneDX SBOM (image_tools/sbom.py)
of one platform image, kept as <out>/cis-<arch>.json, cis-<arch>.md and
sbom-<arch>.cdx.json for bin/sign.sh. The step fails when CIS is red.
inputs:
image:
description: The image to judge, as Docker can run it (local tag or reference)
required: true
arch:
description: Its platform, amd64 or arm64
required: true
decisions:
description: The image repository's CIS decisions
default: cis.toml
packages:
description: The packages the image may hold
default: packages.allow
out:
description: Where the results go
default: attest
runs:
using: composite
steps:
- name: CIS
shell: bash
env:
IMAGE: ${{ inputs.image }}
ARCH: ${{ inputs.arch }}
DECISIONS: ${{ inputs.decisions }}
PACKAGES: ${{ inputs.packages }}
OUT: ${{ inputs.out }}
PYTHONPATH: ${{ github.action_path }}/../..
run: |
mkdir -p "$OUT"
python3 -m image_tools.cis "$IMAGE" --decisions "$DECISIONS" --packages "$PACKAGES" \
--json "$OUT/cis-$ARCH.json" --report "$OUT/cis-$ARCH.md"
- name: SBOM
shell: bash
env:
IMAGE: ${{ inputs.image }}
ARCH: ${{ inputs.arch }}
OUT: ${{ inputs.out }}
PYTHONPATH: ${{ github.action_path }}/../..
run: python3 -m image_tools.sbom "$IMAGE" "$OUT/sbom-$ARCH.cdx.json"
+28
View File
@@ -0,0 +1,28 @@
name: Sign an image
description: >-
Sign a pushed image and every platform image behind it with netOrk's key, and
attach what each was judged by (bin/sign.sh). The caller passes the secrets
COSIGN_PRIVATE_KEY_B64 and COSIGN_PASSWORD as env of this step.
inputs:
ref:
description: The pushed image, <image>@<digest>
required: true
dir:
description: The judge action's results, cis-<arch>.json and sbom-<arch>.cdx.json
default: attest
expect-platforms:
description: The platforms the reference must hold, e.g. "amd64 arm64"; empty takes what is there
default: ""
runs:
using: composite
steps:
- name: Install cosign
shell: bash
run: bash "${{ github.action_path }}/../../bin/install-cosign.sh"
- name: Sign and attest
shell: bash
env:
REF: ${{ inputs.ref }}
DIR: ${{ inputs.dir }}
EXPECT_PLATFORMS: ${{ inputs.expect-platforms }}
run: bash "${{ github.action_path }}/../../bin/sign.sh" "$REF" "$DIR"
+20
View File
@@ -0,0 +1,20 @@
name: Verify the base images
description: >-
Every image the Dockerfiles build on is signed with netOrk's key, checked
before the build (NetOrk/netork#1390, bin/verify-base.sh).
inputs:
dockerfiles:
description: The Dockerfiles, separated by spaces, relative to the workspace
required: true
runs:
using: composite
steps:
- name: Install cosign
shell: bash
run: bash "${{ github.action_path }}/../../bin/install-cosign.sh"
- name: Verify
shell: bash
env:
DOCKERFILES: ${{ inputs.dockerfiles }}
# shellcheck disable=SC2086 # the list splits on purpose
run: bash "${{ github.action_path }}/../../bin/verify-base.sh" $DOCKERFILES