Cosign Aide-mémoire
Cosign Aide-mémoire
Installation
| Plateforme | Commande |
|---|---|
| Ubuntu/Debian | wget https://github.com/sigstore/cosign/releases/latest/download/cosign_amd64.deb && sudo dpkg -i cosign_amd64.deb |
| RHEL/Fedora/CentOS | wget https://github.com/sigstore/cosign/releases/latest/download/cosign-amd64.rpm && sudo rpm -ivh cosign-amd64.rpm |
| macOS (Homebrew) | brew install cosign |
| macOS (Binary) | curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-darwin-amd64 && sudo mv cosign-darwin-amd64 /usr/local/bin/cosign && sudo chmod +x /usr/local/bin/cosign |
| macOS (Apple Silicon) | curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-darwin-arm64 && sudo mv cosign-darwin-arm64 /usr/local/bin/cosign && sudo chmod +x /usr/local/bin/cosign |
| Windows (Scoop) | scoop install cosign |
| Windows (Chocolatey) | choco install cosign |
| Windows (winget) | winget install sigstore.cosign |
| Linux (Generic Binary) | curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 && sudo mv cosign-linux-amd64 /usr/local/bin/cosign && sudo chmod +x /usr/local/bin/cosign |
| Arch Linux | yay -S cosign |
| Container | docker run --rm gcr.io/projectsigstore/cosign:latest version |
| Verify Installation | cosign version |
Commandes de base
| Commande | Description |
|---|---|
cosign version | Afficher les informations de version de cosign |
cosign help | Afficher toutes les commandes et options disponibles |
cosign generate-key-pair | Générer une nouvelle paire de clés (cosign.key et cosign.pub) |
cosign generate-key-pair --output-key-prefix mykey | Générer une paire de clés avec un préfixe personnalisé |
cosign sign --key cosign.key IMAGE_URI | Signer une image de conteneur avec une clé privée |
cosign sign IMAGE_URI | Signer l’image en utilisant le mode sans clé (OIDC) |
cosign verify --key cosign.pub IMAGE_URI | Vérifier la signature d’image avec la clé publique |
cosign verify IMAGE_URI | Vérifier la signature sans clé |
cosign sign --key cosign.key -a key=value IMAGE_URI | Signer l’image avec des annotations personnalisées |
cosign verify --key cosign.pub -a key=value IMAGE_URI | Vérifier la signature et vérifier les annotations |
cosign triangulate IMAGE_URI | Trouver l’emplacement de signature pour une image |
cosign download signature IMAGE_URI | Télécharger la signature pour une image |
cosign download attestation IMAGE_URI | Télécharger les attestations pour une image |
cosign copy SOURCE_IMAGE DEST_IMAGE | Copier l’image avec des signatures vers un nouvel emplacement |
cosign sign --key cosign.key IMAGE1 IMAGE2 IMAGE3 | Signer plusieurs images à la fois |
cosign verify --key cosign.pub IMAGE_URI --output json | Générer les résultats de vérification sous forme de JSON |
cosign sign --key cosign.key gcr.io/project/image@sha256:abc123... | Signer le digest spécifique de l’image |
cosign public-key --key cosign.key | Extraire la clé publique à partir de la clé privée |
cosign initialize | Initialiser cosign avec la racine de confiance |
cosign tree IMAGE_URI | Afficher l’arborescence de signature et d’attestation pour l’image |
Utilisation avancée
| Commande | Description |
|---|---|
cosign generate-key-pair --kms gcpkms://projects/PROJECT/locations/LOCATION/keyRings/RING/cryptoKeys/KEY | Générer une paire de clés dans Google Cloud KMS |
cosign generate-key-pair --kms awskms://arn:aws:kms:region:account:key/key-id | Générer une paire de clés dans AWS KMS |
cosign generate-key-pair --kms azurekms://vault.vault.azure.net/keys/keyname/version | Générer une paire de clés dans Azure Key Vault |
cosign generate-key-pair --kms hashivault://transit/keys/cosign | Générer une paire de clés dans HashiCorp Vault |
cosign attest --key cosign.key --predicate predicate.json IMAGE_URI | Joindre l’attestation à l’image |
cosign attest --key cosign.key --type slsaprovenance --predicate provenance.json IMAGE_URI | Joindre l’attestation de provenance SLSA |
cosign attest --key cosign.key --type vuln --predicate scan-results.json IMAGE_URI | Joindre l’attestation de scan de vulnérabilité |
cosign attest --key cosign.key --type spdx --predicate sbom.spdx.json IMAGE_URI | Joindre l’attestation SBOM |
cosign verify-attestation --key cosign.pub IMAGE_URI | Vérifier les attestations sur l’image |
cosign verify-attestation --key cosign.pub --type slsaprovenance IMAGE_URI | Vérifier le type d’attestation spécifique |
cosign verify-attestation --key cosign.pub --policy policy.cue IMAGE_URI | Vérifier l’attestation par rapport à la politique CUE |
cosign sign-blob --key cosign.key --output-signature file.sig file.txt | Signer un fichier arbitraire (non-conteneur) |
cosign verify-blob --key cosign.pub --signature file.sig file.txt | Vérifier la signature du blob |
cosign sign --key cosign.key --timestamp-server-url http://timestamp.server IMAGE_URI | Signer avec un horodatage RFC3161 |
cosign verify --certificate-identity user@example.com --certificate-oidc-issuer https://accounts.google.com IMAGE_URI | Vérifier la signature sans clé avec l’identité |
cosign verify --key cosign.pub --rekor-url https://rekor.sigstore.dev IMAGE_URI | Vérifier avec le journal de transparence Rekor personnalisé |
cosign verify --key cosign.pub --insecure-ignore-tlog IMAGE_URI | Vérifier sans consulter le journal de transparence |
cosign copy --platform linux/amd64 SOURCE_IMAGE DEST_IMAGE | Copier l’image pour une plateforme spécifique |
cosign copy --sig-only SOURCE_IMAGE DEST_IMAGE | Copier uniquement les signatures (pas l’image) |
cosign manifest verify --key cosign.pub IMAGE_URI | Vérifier la signature du manifeste d’image |
cosign upload blob --signature file.sig --payload file.txt | Télécharger la signature sur le journal de transparence Rekor |
cosign sign --key cosign.key -r gcr.io/myproject/myimage | Signer récursivement toutes les balises |
cosign verify --key cosign.pub --certificate-chain chain.pem IMAGE_URI | Vérifier avec la chaîne de certificats |
cosign attach signature --signature sig.json IMAGE_URI | Attacher manuellement la signature à l’image |
cosign attach attestation --attestation att.json IMAGE_URI | Attacher manuellement l’attestation à l’image |
Configuration
Variables d’environnement
# Enable experimental features (keyless signing)
export COSIGN_EXPERIMENTAL=1
# Set custom Rekor transparency log URL
export REKOR_URL=https://rekor.sigstore.dev
# Set custom Fulcio certificate authority URL
export FULCIO_URL=https://fulcio.sigstore.dev
# Set custom OIDC issuer for keyless signing
export COSIGN_OIDC_ISSUER=https://oauth2.sigstore.dev/auth
# Set custom OIDC client ID
export COSIGN_OIDC_CLIENT_ID=sigstore
# Set Docker registry credentials
export COSIGN_REPOSITORY=registry.example.com/signatures
# Set password for private key (CI/CD use)
export COSIGN_PASSWORD=your-password-here
# Skip TUF root verification (not recommended for production)
export COSIGN_EXPERIMENTAL_SKIP_TUF=1
# Set custom Docker config location
export DOCKER_CONFIG=/path/to/.docker
Exemple de fichier de politique CUE
// policy.cue - Example attestation policy
predicateType: "https://slsa.dev/provenance/v0.2"
predicate: {
buildType: "https://cloudbuild.googleapis.com/CloudBuildYaml@v1"
builder: id: =~"^https://cloudbuild.googleapis.com/"
invocation: {
configSource: {
repository: =~"^https://github.com/myorg/"
}
}
}
Politique d’attestation pour les analyses de vulnérabilité
// vuln-policy.cue - Require no critical vulnerabilities
predicateType: "https://cosign.sigstore.dev/attestation/vuln/v1"
predicate: {
scanner: {
name: "trivy"
}
metadata: {
scanFinishedOn: string
}
// No critical vulnerabilities allowed
scanner: result: {
criticalCount: 0
}
}
Intégration avec GitHub Actions
# .github/workflows/sign.yml
name: Sign Container Image
on: [push]
permissions:
contents: read
id-token: write # Required for keyless signing
packages: write
jobs:
sign:
runs-on: ubuntu-latest
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@v3
- name: Login to Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Image
run: docker build -t ghcr.io/${{ github.repository }}:latest .
- name: Push Image
run: docker push ghcr.io/${{ github.repository }}:latest
- name: Sign Image (Keyless)
run: |
cosign sign --yes ghcr.io/${{ github.repository }}:latest
Cas d’utilisation courants
Cas d’utilisation 1 : Signer et vérifier une image de conteneur avec une paire de clés
# Generate key pair (will prompt for password)
cosign generate-key-pair
# Build your container image
docker build -t myregistry.io/myapp:v1.0 .
# Push image to registry
docker push myregistry.io/myapp:v1.0
# Sign the image
cosign sign --key cosign.key myregistry.io/myapp:v1.0
# Verify the signature
cosign verify --key cosign.pub myregistry.io/myapp:v1.0
# Verify and extract payload
cosign verify --key cosign.pub myregistry.io/myapp:v1.0 | jq .
Cas d’utilisation 2 : Signature sans clé avec GitHub Actions
# Enable experimental mode for keyless signing
export COSIGN_EXPERIMENTAL=1
# Sign image (will open browser for OIDC authentication)
cosign sign myregistry.io/myapp:v1.0
# In CI/CD (GitHub Actions), use --yes flag
cosign sign --yes myregistry.io/myapp:v1.0
# Verify keyless signature with identity
cosign verify \
--certificate-identity user@example.com \
--certificate-oidc-issuer https://github.com/login/oauth \
myregistry.io/myapp:v1.0
# Verify in GitHub Actions workflow
cosign verify \
--certificate-identity https://github.com/myorg/myrepo/.github/workflows/build.yml@refs/heads/main \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
myregistry.io/myapp:v1.0
Cas d’utilisation 3 : Attacher et vérifier un SBOM
# Generate SBOM using syft
syft myregistry.io/myapp:v1.0 -o spdx-json > sbom.spdx.json
# Attach SBOM as attestation
cosign attest --key cosign.key \
--type spdx \
--predicate sbom.spdx.json \
myregistry.io/myapp:v1.0
# Verify attestation
cosign verify-attestation --key cosign.pub \
--type spdx \
myregistry.io/myapp:v1.0
# Download and view SBOM
cosign verify-attestation --key cosign.pub \
--type spdx \
myregistry.io/myapp:v1.0 | jq -r '.payload' | base64 -d | jq .
Cas d’utilisation 4 : Signer avec Cloud KMS
# Generate key in Google Cloud KMS
cosign generate-key-pair --kms gcpkms://projects/my-project/locations/us-central1/keyRings/cosign/cryptoKeys/signing-key
# Sign image using KMS key
cosign sign --key gcpkms://projects/my-project/locations/us-central1/keyRings/cosign/cryptoKeys/signing-key \
myregistry.io/myapp:v1.0
# Get public key from KMS
cosign public-key --key gcpkms://projects/my-project/locations/us-central1/keyRings/cosign/cryptoKeys/signing-key > cosign.pub
# Verify using public key
cosign verify --key cosign.pub myregistry.io/myapp:v1.0
# AWS KMS example
cosign sign --key awskms://arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 \
myregistry.io/myapp:v1.0
Cas d’utilisation 5 : Vérification basée sur des politiques avec des attestations
# Create vulnerability scan
trivy image --format json --output scan-results.json myregistry.io/myapp:v1.0
# Attach scan results as attestation
cosign attest --key cosign.key \
--type vuln \
--predicate scan-results.json \
myregistry.io/myapp:v1.0
# Create policy file
cat > vuln-policy.cue <<EOF
predicateType: "https://cosign.sigstore.dev/attestation/vuln/v1"
predicate: {
scanner: {
name: "trivy"
}
}
EOF
# Verify against policy
cosign verify-attestation --key cosign.pub \
--type vuln \
--policy vuln-policy.cue \
myregistry.io/myapp:v1.0
# If policy passes, deploy image
kubectl set image deployment/myapp myapp=myregistry.io/myapp:v1.0
Meilleures pratiques
-
Toujours utiliser des digestifs d’image spécifiques : Signer et vérifier en utilisant
@sha256:...des digestifs au lieu des tags pour prévenir les attaques de mutation de tags. Les tags peuvent être déplacés, mais les digestifs sont immuables. -
Stocker les clés privées de manière sécurisée : Utiliser des KMS cloud (AWS KMS, Google Cloud KMS, Azure Key Vault) ou des modules de sécurité matériels (HSM) au lieu de stocker les clés sur le disque. Ne jamais commiter les clés dans le contrôle de version.
-
Préférer la signature sans clé pour CI/CD : Utiliser la signature sans clé basée sur OIDC dans les pipelines automatisés pour éviter de gérer des identifiants de longue durée. Cela exploite des certificats de courte durée liés à votre fournisseur d’identité.
-
Implémenter l’application de politique au runtime : Intégrer la vérification cosign avec des contrôleurs d’admission Kubernetes (comme Kyverno ou OPA Gatekeeper) pour empêcher l’exécution d’images non signées ou non vérifiées.
-
Attacher des attestations complètes : Inclure des attestations SBOM, des analyses de vulnérabilité et des attestations de provenance SLSA pour fournir une transparence complète de la chaîne d’approvisionnement. Cela permet des pistes d’audit et des rapports de conformité.
-
Utiliser des journaux de transparence : Toujours vérifier par rapport au journal de transparence Rekor en production pour détecter la prédatation de signature ou la compromission de clé. Ne sauter qu’avec
--insecure-ignore-tlogdans des environnements isolés. -
Faire tourner les clés régulièrement : Établir un calendrier de rotation de clés (par exemple, tous les 90 jours) et maintenir un processus de révocation de clés. Conserver les anciennes clés publiques pour vérifier les signatures historiques.
-
Vérifier l’identité en mode sans clé : Toujours spécifier
--certificate-identityet--certificate-oidc-issuerlors de la vérification des signatures sans clé pour éviter d’accepter des signatures d’identités inattendues. -
Tester la vérification en staging : Toujours tester vos politiques de vérification dans des environnements non-production avant de les appliquer en production pour éviter les échecs de déploiement.
-
Documenter votre workflow de signature : Maintenir une documentation claire de qui peut signer des images, quelles attestations sont requises, et comment vérifier les signatures pour la réponse aux incidents et l’audit.
Dépannage
| Problème | Solution |
|---|---|
| Error: “private key password incorrect” | Ensure you’re using the correct password for your private key. Set COSIGN_PASSWORD environment variable for non-interactive use: export COSIGN_PASSWORD=your-password |
| Error: “no matching signatures” | The image may not be signed, or you’re using the wrong public key. Verify with cosign triangulate IMAGE_URI to check if signatures exist, and ensure you’re using the correct public key. |
| Error: “UNAUTHORIZED: authentication required” | You need to authenticate to the registry first. Run docker login or use cosign login with appropriate credentials before signing or verifying. |
| Keyless signing fails with “no provider found” | Enable experimental mode with export COSIGN_EXPERIMENTAL=1 and ensure you have internet access to reach Fulcio and Rekor services. |
| Error: “failed to verify certificate identity” | When verifying keyless signatures, you must specify both --certificate-identity and --certificate-oidc-issuer flags matching the signer’s identity. |
| Signatures not found after copying image | Use cosign copy instead of docker tag or crane copy to ensure signatures are copied along with the image. Regular Docker commands don’t copy OCI artifacts. |
| Error: “tlog entry not found” | The signature may not have been uploaded to Rekor transparency log. Use --insecure-ignore-tlog flag only in air-gapped environments or re-sign the image. |
| Verification fails in air-gapped environment | Initialize cosign with TUF root: cosign initialize --mirror https://your-mirror --root root.json, or use --insecure-ignore-tlog and --insecure-ignore-sct flags (not recommended for production). |
| Error: “image is a manifest list” | Sign the specific platform image instead of the manifest list, or use cosign sign --recursive to sign all images in the manifest list. |
| Attestation verification fails with policy | Check your CUE policy syntax with cue vet policy.cue. Ensure the predicateType matches exactly. Use cosign verify-attestation --output json to inspect actual attestation structure. |
| Error: “failed to get public key from KMS” | Verify your cloud credentials are configured (gcloud auth, aws configure, az login) and you have permissions to access the KMS key. Check the KMS key URI format is correct. |