| @@ -0,0 +1,51 @@ | ||
| + | apiVersion: kyverno.io/v1 | |
| + | kind: ClusterPolicy | |
| + | metadata: | |
| + | name: verify-signed-images | |
| + | annotations: | |
| + | policies.kyverno.io/title: Verify image signatures | |
| + | policies.kyverno.io/category: Supply Chain Security | |
| + | policies.kyverno.io/severity: high | |
| + | spec: | |
| + | validationFailureAction: Enforce | |
| + | webhookTimeoutSeconds: 30 | |
| + | failurePolicy: Fail | |
| + | background: false | |
| + | rules: | |
| + | - name: check-cosign-signature | |
| + | match: | |
| + | any: | |
| + | - resources: | |
| + | kinds: | |
| + | - Pod | |
| + | verifyImages: | |
| + | - imageReferences: | |
| + | - "ghcr.io/zionboggan/*" | |
| + | attestors: | |
| + | - count: 1 | |
| + | entries: | |
| + | - keyless: | |
| + | subject: "https://github.com/zionboggan/*" | |
| + | issuer: "https://token.actions.githubusercontent.com" | |
| + | rekor: | |
| + | url: https://rekor.sigstore.dev | |
| + | mutateDigest: true | |
| + | verifyDigest: true | |
| + | required: true | |
| + | - name: require-sbom-attestation | |
| + | match: | |
| + | any: | |
| + | - resources: | |
| + | kinds: | |
| + | - Pod | |
| + | verifyImages: | |
| + | - imageReferences: | |
| + | - "ghcr.io/zionboggan/*" | |
| + | attestations: | |
| + | - type: https://spdx.dev/Document | |
| + | attestors: | |
| + | - count: 1 | |
| + | entries: | |
| + | - keyless: | |
| + | subject: "https://github.com/zionboggan/*" | |
| + | issuer: "https://token.actions.githubusercontent.com" |
| @@ -0,0 +1,17 @@ | ||
| + | apiVersion: v1 | |
| + | kind: Pod | |
| + | metadata: | |
| + | name: signed-app | |
| + | spec: | |
| + | containers: | |
| + | - name: app | |
| + | image: ghcr.io/zionboggan/cicd-supply-chain-security:latest | |
| + | --- | |
| + | apiVersion: v1 | |
| + | kind: Pod | |
| + | metadata: | |
| + | name: unsigned-app | |
| + | spec: | |
| + | containers: | |
| + | - name: app | |
| + | image: docker.io/library/nginx:latest |
| @@ -0,0 +1,29 @@ | ||
| + | #!/usr/bin/env bash | |
| + | set -euo pipefail | |
| + | ||
| + | IMAGE="${1:-}" | |
| + | OWNER="${OWNER:-zionboggan}" | |
| + | ||
| + | if [[ -z "${IMAGE}" ]]; then | |
| + | echo "usage: $0 <image-ref-with-digest>" >&2 | |
| + | echo "example: $0 ghcr.io/${OWNER}/cicd-supply-chain-security@sha256:..." >&2 | |
| + | exit 1 | |
| + | fi | |
| + | ||
| + | IDENTITY_REGEXP="^https://github.com/${OWNER}/" | |
| + | ISSUER="https://token.actions.githubusercontent.com" | |
| + | ||
| + | echo "verifying signature for ${IMAGE}" | |
| + | cosign verify \ | |
| + | --certificate-identity-regexp "${IDENTITY_REGEXP}" \ | |
| + | --certificate-oidc-issuer "${ISSUER}" \ | |
| + | "${IMAGE}" | |
| + | ||
| + | echo "verifying SBOM attestation" | |
| + | cosign verify-attestation \ | |
| + | --type spdxjson \ | |
| + | --certificate-identity-regexp "${IDENTITY_REGEXP}" \ | |
| + | --certificate-oidc-issuer "${ISSUER}" \ | |
| + | "${IMAGE}" | |
| + | ||
| + | echo "ok: ${IMAGE} is signed and carries a verified SBOM" |