Tekton Chains est un composant CNCF de la suite Tekton qui ajoute la sécurité de la supply chain aux pipelines CI/CD Tekton. Il s'installe comme contrôleur Kubernetes et observe automatiquement tous les TaskRuns et PipelineRuns : pour chaque build terminé, il génère des attestations cryptographiques (au format SLSA ou in-toto), signe les artefacts produits avec Cosign, et peut enregistrer ces preuves dans un journal de transparence (Rekor). Aucune modification des pipelines existants n'est nécessaire.
L'objectif est de répondre aux exigences SLSA Level 2/3 : prouver de façon vérifiable qu'une image a bien été produite par un pipeline spécifique, à partir de sources identifiées, sans modification.
Informations essentielles
Origine : Tekton / CNCF · Licence : Apache 2.0 · Architectures : x86_64, ARM64
Liens : Documentation · GitHub · Releases
Support : Projet CNCF actif, release régulières. Requiert Tekton Pipelines.
Stack par défaut
| Composant | Valeur |
|---|---|
| Prérequis | Tekton Pipelines installé |
| Formats d'attestation | SLSA Provenance, in-toto, TaskRun |
| Signatures | Cosign, KMS (AWS/GCP/Azure/HashiCorp Vault) |
| Transparence | Rekor (optionnel, recommandé) |
| Storage attestations | OCI registry, Tekton (annotation TaskRun) |
Concepts clés
| Concept | Description |
|---|---|
| Attestation | Métadonnées signées décrivant comment un artefact a été produit |
| SLSA Provenance | Format standard décrivant la source, le build env et les dépendances |
| in-toto | Framework de vérification de la supply chain |
| Cosign | Outil de signature d'images OCI (Sigstore) |
| Rekor | Journal de transparence immuable (Sigstore) |
| TaskRun | Exécution d'une tâche Tekton - Chains l'observe automatiquement |
Prérequis
| Ressource | Valeur |
|---|---|
| Kubernetes | 1.21+ |
| Tekton Pipelines | Installé et fonctionnel |
| Registry OCI | Pour stocker les attestations (même registry que les images) |
| Clé de signature | Cosign keypair, KMS, ou Sigstore keyless |
Installation
Via kubectl
# Installer Tekton Pipelines d'abord (si non fait)
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
# Installer Tekton Chains
kubectl apply --filename https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
# Vérifier
kubectl get pods -n tekton-chains
# chains-controller-* doit être Running (1/1)
Générer une clé de signature Cosign
# Installer Cosign
curl -Lo cosign https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign && sudo mv cosign /usr/local/bin/
# Générer une paire de clés
cosign generate-key-pair k8s://tekton-chains/signing-secrets
# Crée le secret signing-secrets dans le namespace tekton-chains
Configurer Tekton Chains
kubectl patch configmap chains-config \
-n tekton-chains \
--type merge \
-p '{
"data": {
"artifacts.taskrun.format": "slsa/v1",
"artifacts.taskrun.storage": "oci",
"artifacts.taskrun.signer": "x509",
"transparency.enabled": "true",
"transparency.url": "https://rekor.sigstore.dev"
}
}'
kubectl rollout restart deployment/chains-controller -n tekton-chains
Vérification de l'installation
# 1. Pods Tekton Chains
kubectl get pods -n tekton-chains
# chains-controller-* Running (1/1)
# 2. Secret de signature
kubectl get secret signing-secrets -n tekton-chains
# Doit exister
# 3. Configuration active
kubectl get configmap chains-config -n tekton-chains -o yaml
# Voir les paramètres artifacts.taskrun.*
# 4. Lancer un TaskRun simple et vérifier qu'une attestation est générée
kubectl apply -f - <<EOF
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
name: test-chains
spec:
taskSpec:
results:
- name: IMAGE_DIGEST
type: string
- name: IMAGE_URL
type: string
steps:
- name: echo
image: alpine
script: |
echo -n "sha256:abc123" | tee $(results.IMAGE_DIGEST.path)
echo -n "myregistry.io/myapp:latest" | tee $(results.IMAGE_URL.path)
EOF
kubectl wait --for=condition=succeeded taskrun/test-chains --timeout=60s
kubectl get taskrun test-chains -o yaml | grep chains.tekton.dev
# Doit afficher les annotations chains.tekton.dev/signed: "true"
# et chains.tekton.dev/transparency-url: <url Rekor>
kubectl delete taskrun test-chains
Pièges courants à l'installation
| Symptôme | Cause | Correction |
|---|---|---|
signing-secrets absent | Cosign non exécuté ou erreur | Relancer cosign generate-key-pair k8s://tekton-chains/signing-secrets |
| TaskRun non annoté | Chains ne surveille pas ce namespace | Vérifier chains-config - pas de filtre namespace par défaut |
| Attestation non stockée en OCI | Registry non authentifié | Créer un secret docker-registry et le référencer dans chains-config |
transparency.enabled bloqué | Rekor inaccessible depuis le cluster | Utiliser transparency.url avec un Rekor privé ou désactiver |
Utilisation
Pipeline Tekton avec résultats pour Chains
Pour que Chains génère une attestation, le Task doit exposer les résultats IMAGE_DIGEST et IMAGE_URL :
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: build-and-push
spec:
params:
- name: image
type: string
results:
- name: IMAGE_DIGEST
description: Digest de l'image construite
- name: IMAGE_URL
description: URL de l'image dans le registry
steps:
- name: build
image: gcr.io/kaniko-project/executor:latest
args:
- --destination=$(params.image)
- --digest-file=$(results.IMAGE_DIGEST.path)
env:
- name: DOCKER_CONFIG
value: /kaniko/.docker
- name: set-url
image: alpine
script: |
echo -n "$(params.image)" | tee $(results.IMAGE_URL.path)
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: build-pipeline
spec:
params:
- name: image
tasks:
- name: build
taskRef:
name: build-and-push
params:
- name: image
value: $(params.image)
Chains observe ce PipelineRun et génère automatiquement l'attestation SLSA.
Vérifier les attestations
# Vérifier la signature d'une image
cosign verify \
--key k8s://tekton-chains/signing-secrets \
myregistry.io/myapp:latest
# Vérifier l'attestation SLSA
cosign verify-attestation \
--key k8s://tekton-chains/signing-secrets \
--type slsaprovenance \
myregistry.io/myapp:latest | jq .
# Voir le provenance complet
cosign verify-attestation \
--key k8s://tekton-chains/signing-secrets \
--type slsaprovenance \
myregistry.io/myapp:latest | \
jq -r '.payload' | base64 -d | jq .predicate
Mise à jour
kubectl apply --filename https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
kubectl rollout status deployment/chains-controller -n tekton-chains
Troubleshooting
# Logs du contrôleur Chains
kubectl logs -n tekton-chains -l app=tekton-chains-controller --tail=100
# Vérifier l'état d'un TaskRun (annotations Chains)
kubectl get taskrun <nom> -o yaml | grep -A10 "chains.tekton.dev"
# Chains en erreur de signature
kubectl logs -n tekton-chains -l app=tekton-chains-controller | grep -i "error\|sign"
Commandes utiles
# Vérifier la configuration de Chains
kubectl get configmap chains-config -n tekton-chains -o yaml
# Voir les annotations d'un TaskRun signé
kubectl get taskrun <nom> -o yaml | grep chains.tekton.dev
# Vérifier la signature d'une image
cosign verify --key k8s://tekton-chains/signing-secrets <image>
# Vérifier l'attestation SLSA
cosign verify-attestation --type slsaprovenance --key ... <image>
Ressources
- Documentation Tekton Chains : https://tekton.dev/docs/chains/
- SLSA Framework : https://slsa.dev/
- GitHub : https://github.com/tektoncd/chains
- Releases : https://github.com/tektoncd/chains/releases
- Cosign (signatures) : https://docs.sigstore.dev/cosign/overview/
- Rekor (transparence) : https://docs.sigstore.dev/rekor/overview/