Ce document a été traduit à l'aide d'une technologie de traduction automatique. Bien que nous nous efforcions de fournir des traductions exactes, nous ne fournissons aucune garantie quant à l'exhaustivité, l'exactitude ou la fiabilité du contenu traduit. En cas de divergence, la version originale anglaise prévaut et fait foi.

Il s'agit d'une documentation non publiée pour Admission Controller 1.34-dev.

Capacités d’hôte de Sigstore

À titre d’exemple d’une autre utilisation des capacités d’hôte sur cel-policy de Kubewarden, créons une stratégie qui vérifie toutes les images de conteneurs dans un Pod en vérifiant leurs signatures sans clé Sigstore.

Exemple : Stratégie de vérification Sigstore

Cette stratégie vérifiera toutes les images de conteneurs dans le Pod Sigstore et s’assurera que les images sont signées et de confiance.

Dans ce cas, nous vérifierons une signature sans clé Sigstore effectuée dans GitHub Actions. Ces types de signatures sans clé sont liés à l’émetteur OIDC de GitHub lors de la création des certificats cryptographiques, donc nous n’aurons besoin que de connaître l’organisation GitHub sous laquelle l’image de conteneur est publiée. Vous pouvez en savoir plus sur les capacités d’hôte pour Sigstore ici.

Pour réaliser cela en CEL, nous utilisons les bibliothèques d’extension CEL de SUSE Security Admission Controller pour les capacités d’hôte dans la stratégie, en particulier la fonction githubAction.

Comme toujours, nous pouvons commencer par kwctl :

$ kwctl scaffold manifest -t ClusterAdmissionPolicy \
  registry://ghcr.io/kubewarden/policies/cel-policy:v1.0.0`

Que nous pouvons ensuite modifier pour qu’il soit pertinent pour notre stratégie de vérification des conteneurs :

apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
  name: "cel-sigstore-keyless-verification"
spec:
  module: ghcr.io/kubewarden/policies/cel-policy:v1.0.0
  namespaceSelector:
    matchLabels:
      kubernetes.io/metadata.name: default
  rules:
    - apiGroups: [""]
      apiVersions: ["v1"]
      resources: ["pods"]
      operations: ["CREATE", "UPDATE"]

Maintenant, passons à la partie CEL. Nous allons obtenir une liste d’images de conteneurs dans l’objet Pod actuel, puis vérifier qu’elles sont vérifiées par une signature correspondant à notre organisation choisie (dans ce cas, github.com/opencontainers) :

apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
  name: "cel-sigstore-keyless-verification"
spec:
  module: ghcr.io/kubewarden/policies/cel-policy:v1.0.0
  namespaceSelector:
    matchLabels:
      kubernetes.io/metadata.name: default
  rules:
    - apiGroups: [""]
      apiVersions: ["v1"]
      resources: ["pods"]
      operations: ["CREATE", "UPDATE"]
  settings:
    variables:
      - name: containerImages
        expression: |
          object.spec.containers.map(c, c.image)
      - name: containerImagesNotVerified
        expression: |
          variables.containerImages.filter(image, !kw.sigstore.image(image).githubAction("opencontainers").verify().isTrusted())
    validations:
      - expression: |
          size(variables.containerImagesNotVerified) == 0
        messageExpression: "'These container images are not signed by the kubewarden GitHub organization: ' + variables.containerImagesNotVerified.join(', ')"

Mais attendez, nous ne devons pas oublier que les InitContainers peuvent également faire partie des Pods. Ajoutons donc une autre variable et validation :

apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
  name: "cel-sigstore-keyless-verification"
spec:
  module: ghcr.io/kubewarden/policies/cel-policy:v1.0.0
  namespaceSelector:
    matchLabels:
      kubernetes.io/metadata.name: default
  rules:
    - apiGroups: [""]
      apiVersions: ["v1"]
      resources: ["pods"]
      operations: ["CREATE", "UPDATE"]
  settings:
    variables:
      - name: containerImages
        expression: |
          object.spec.containers.map(c, c.image)
      - name: initContainerImages
        expression: |
          has(object.spec.initContainerImages) ? object.spec.initContainers.map(c, c.image) : []
      - name: containerImagesNotVerified
        expression: |
          variables.containerImages.filter(image, !kw.sigstore.image(image).githubAction("opencontainers").verify().isTrusted())
      - name: initContainerImagesNotVerified
        expression: |
          variables.initContainerImages.filter(image, !kw.sigstore.image(image).githubAction("opencontainers").verify().isTrusted())
    validations:
      - expression: |
          size(variables.containerImagesNotVerified) == 0
        messageExpression: "'Ces images de conteneurs ne sont pas signées par l'organisation GitHub kubewarden : ' + variables.containerImagesNotVerified.join(', ')"
      - expression: |
          size(variables.initContainerImagesNotVerified) == 0
        messageExpression: "'Ces images de conteneurs init ne sont pas signées par l'organisation GitHub kubewarden : ' + variables.initContainerImagesNotVerified.join(', ')"

As usual with CEL, we can add several validations under settings.validations, and they are evaluated in parallel, joined with an AND operation, which is short-circuited.

We can now deploy the policy, and try to deploy a Pod with unsigned images:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: golanci-lint-example
spec:
  containers:
  - name: nginx
    image: ghcr.io/opencontainers/golangci-lint:v1.52.1
    ports:
    - containerPort: 80
EOF
Error from server: error when creating "STDIN":
  admission webhook "clusterwide-cel-sigstore-keyless-verification.kubewarden.admission" denied the request:
  failed to verify image: Callback evaluation failure: no signatures found for image: ghcr.io/opencontainers/golangci-lint:v1.52.1