⏪ back

Trusted workloads on Kubernetes

with sigstore’s policy-controller

Caleb Woodbine <calebwoodbine.public@gmail.com>

Introduction

  • software supply chain security
  • sigstore
  • trusting workloads in Kubernetes

About me

based in Wellington, New Zealand. Software and infrastructure engineer. Cloud & Open Source enthusiast.

https://calebwoodbine.nz

Background and Projects

  • Safe Surfer
    • routers
    • infrastructure
  • ii.nz
    • Kubernetes conformance
    • sig-k8s-infra
  • personal
    • FlatTrack (software for humans living together)

Software Supply Chain

simplified graph. results may vary

Our Industry Has a Problem

  • supply chain attacks
  • out of date software
  • unpatched CVEs everywhere

A Call to Action

  • know what’s in your software
  • know how your software is built
  • automate the build process
  • sign environment metadata and artifacts
  • enforce ⬅️ policy-controller

Under the Linux Foundation

and from friends, comes:

Making sure your software is what it claims to be

see: https://sigstore.dev, https://github.com/sigstore

cosign

  • sign
  • attest
  • verify
  • tree

a CLI tool from Sigstore for signing and verifying.

supports keypairs as well as keyless with OpenID Connect (OIDC) integration.

Artifact Provenance

make claims through signed metadata about build environments, dependencies and artifacts.

policy-controller

A ValidatingWebhookConfiguration to fit your needs.

based on cosign, policy-controller verifies container images in your cluster and enforces policies based on supply chain metadata.

ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.

Some Functions Include

e.g:

  • images with names like … must be signed with these authorities
  • parse SBOM attachments (including SPDX metadata) for gating off images containing …
    • images cannot contain the following dependencies …

Example of policies (1️⃣/3️⃣)

apiVersion: policy.sigstore.dev/v1alpha1
kind: ClusterImagePolicy
metadata:
  name: kubernetes-signed
spec:
  images:
  - glob: registry.k8s.io/**
  authorities:
  - keyless:
      url: https://fulcio.sigstore.dev
      identities:
      - issuer: https://accounts.google.com
        subject: krel-trust@k8s-releng-prod.iam.gserviceaccount.com
    ctlog:
      url: https://rekor.sigstore.dev

Example of policies (2️⃣/3️⃣)

apiVersion: policy.sigstore.dev/v1alpha1
kind: ClusterImagePolicy
metadata:
  name: certmanager-signed
spec:
  images:
    - glob: quay.io/jetstack/cert-manager-*
  authorities:
    - key:
        hashAlgorithm: sha512
        data: |
          -----BEGIN PUBLIC KEY-----
          MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsZZKaaIRjOpzbiWYIDKO
          yry9XGBqAfve1iOGmt5VO1jpjNoEseT6zewozHfWTM7osxayy2WjN8G+QV39MlT3
          Vxo91/31g+Zcq8KcvxG+iB8GRaD9pNgLmghorv+eYDiPYMO/+fhsLImyG5WEoPct
          MeCBD7umZ/A2t96U9DQxVDqQbTHlsNludno1p1wsgRnfUM3QHexNljDvJg5FcDMo
          dCpVLpRNvbw0lbJVfybJ4siJ5o/MmXzy0QCJpw+yMIqvqMc8qgKJ1yooJtuTVF4t
          4/luP+EG/oVIiSWCFeRMqYdbJ3R+CJi+4LN7vFNYQM1Q/NwOB52RteaR7wnqmcBz
          qSYK32MM8xdPCQ5tioWwnPTRbPZuzsZsRmJsKBO9JUrBYdDntZX1xY5g4QNSufxi
          QgJgJSU7E4VGMvagEzB1JzvOr6A/qNFCO1Z6JsA3jw3cJLV1rSHfxqfSXBACTLDf
          6bOPWRILRKydTJA6uLKNKmo1/nFm3jvd5tHKOjy4VAQLJ/Vx9wBsAAiLa+06veun
          Oz3AJ9sNh3wLp21RL11u9TuOKRBipE/TYsBYp8jpIyWPXDSV+JcD/TZqoT8y0Z6S
          0damfUmspuK9DTQFL2crpeaqJSG9RA+OuPZLxGD1IMURTsPJB7kXhPtmceeirBnw
          sVcRHHDitVt8oO/x4Wus1c0CAwEAAQ==
          -----END PUBLIC KEY-----

Example of policies (3️⃣/3️⃣)

apiVersion: policy.sigstore.dev/v1alpha1
kind: ClusterImagePolicy
metadata:
  name: sample-ko-monorepo
spec:
  images:
  - glob: "ghcr.io/bobymcbobs/sample-ko-monorepo**"
  authorities:
  - keyless:
      identities:
      - issuer: https://token.actions.githubusercontent.com
        subjectRegExp: "^(https://github.com/BobyMCbobs/sample-ko-monorepo/.github/workflows/build-and-release.yml@refs/(heads/main|tags/v[0-9].[0-9].[0-9]))$"

Links

supplychain reads

Demo

check it out!

kind create cluster

kind create cluster

tag container image

DATE="$(date +%Y-%m-%d-%H-%M)"
crane cp cgr.dev/chainguard/nginx:latest ttl.sh/cgr-nginx-caleb-shows-sigstore-"$DATE":1h

sign image

cosign sign --yes ttl.sh/cgr-nginx-caleb-shows-sigstore-"$DATE":1h

verify signature

cosign verify -o text --certificate-identity-regexp='.*' --certificate-oidc-issuer-regexp='.*' ttl.sh/cgr-nginx-caleb-shows-sigstore-"$DATE":1h
cosign tree ttl.sh/cgr-nginx-caleb-shows-sigstore-"$DATE":1h

install policy-controller

helm repo add sigstore https://sigstore.github.io/helm-charts
helm repo update
kubectl create namespace cosign-system
helm install policy-controller -n cosign-system sigstore/policy-controller

show installation

kubectl -n cosign-system get pods

install trust policy

cat << EOF | kubectl apply -f -
apiVersion: policy.sigstore.dev/v1alpha1
kind: ClusterImagePolicy
metadata:
  name: ttl-sh-is-signed
spec:
  images:
  - glob: "ttl.sh/**"
  authorities:
  - keyless:
      identities:
      - issuer: https://github.com/login/oauth
        subjectRegExp: "calebwoodbine.public@gmail.com"
EOF

enforce on one namespace

kubectl label namespace default policy.sigstore.dev/include=true

create a pod with an untrusted container image

kubectl create deployment nginx-unsigned --image=cgr.dev/chainguard/nginx:latest

create a pod with a trusted container image

kubectl create deployment nginx --image=ttl.sh/cgr-nginx-caleb-shows-sigstore-"$DATE":1h

tidy up

kubectl delete clusterimagepolicy ttl-sh-is-signed
helm uninstall -n cosign-system policy-controller
kubectl delete namespace cosign-system
kind delete cluster

End