8.6 KiB
8.6 KiB
Cosign Verification Examples
This document provides examples for verifying StellaOps DSSE attestations using Sigstore cosign.
Prerequisites
Install Cosign
# macOS
brew install cosign
# Linux (download latest release)
curl -sSfL https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o cosign
chmod +x cosign
sudo mv cosign /usr/local/bin/
# Windows (download from releases page)
# https://github.com/sigstore/cosign/releases
# Verify installation
cosign version
Required Files
| File | Description |
|---|---|
attestation.json |
DSSE envelope exported from StellaOps |
public.key |
Public key for keyful verification |
trusted_root.json |
Sigstore TUF root for keyless verification |
Export Attestation from StellaOps
# Export attestation for a specific artifact
stellaops attestation export \
--artifact sha256:abc123... \
--output attestation.json
# Export with certificate chain
stellaops attestation export \
--artifact sha256:abc123... \
--include-certificate-chain \
--output attestation-bundle.json
# Export as Sigstore bundle
stellaops attestation export \
--artifact sha256:abc123... \
--format sigstore-bundle \
--output attestation.sigstore.json
Keyful Verification (KMS/HSM Keys)
Verify with Public Key
# Basic verification
cosign verify-attestation \
--key public.key \
--type custom \
sha256:abc123...
# Verify from exported attestation file
cosign verify-attestation \
--key public.key \
--type custom \
--attestation attestation.json \
sha256:abc123...
Verify with KMS Key
# AWS KMS
cosign verify-attestation \
--key awskms:///arn:aws:kms:us-east-1:123456789:key/abc-123 \
--type custom \
sha256:abc123...
# GCP KMS
cosign verify-attestation \
--key gcpkms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key \
--type custom \
sha256:abc123...
# Azure Key Vault
cosign verify-attestation \
--key azurekms://mykeyvault.vault.azure.net/keys/mykey \
--type custom \
sha256:abc123...
# HashiCorp Vault
cosign verify-attestation \
--key hashivault://transit/keys/my-key \
--type custom \
sha256:abc123...
Keyless Verification (Fulcio/OIDC)
Verify with Certificate Identity
# Verify with issuer and subject
cosign verify-attestation \
--certificate-identity "signer@example.com" \
--certificate-oidc-issuer "https://accounts.google.com" \
--type custom \
sha256:abc123...
# Verify with identity regex
cosign verify-attestation \
--certificate-identity-regexp ".*@stellaops\.io" \
--certificate-oidc-issuer "https://github.com/login/oauth" \
--type custom \
sha256:abc123...
Verify GitHub Actions Workload Identity
cosign verify-attestation \
--certificate-identity "https://github.com/org/repo/.github/workflows/build.yml@refs/heads/main" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--type custom \
sha256:abc123...
Verify Specific Predicate Types
StellaOps Attestation Types
# Verify SBOM attestation
cosign verify-attestation \
--key public.key \
--type "https://spdx.dev/Document" \
sha256:abc123...
# Verify SLSA Provenance
cosign verify-attestation \
--key public.key \
--type "https://slsa.dev/provenance/v1" \
sha256:abc123...
# Verify StellaOps scan results
cosign verify-attestation \
--key public.key \
--type "https://stella-ops.org/attestation/scan-results/v1" \
sha256:abc123...
# Verify StellaOps policy evaluation
cosign verify-attestation \
--key public.key \
--type "https://stella-ops.org/attestation/policy-evaluation/v1" \
sha256:abc123...
# Verify graph root attestation
cosign verify-attestation \
--key public.key \
--type "https://stella-ops.org/attestation/graph-root/v1" \
sha256:abc123...
Offline Verification
Verify with Cached Bundle
# Verify using a Sigstore bundle (includes certificate and Rekor entry)
cosign verify-attestation \
--bundle attestation.sigstore.json \
--certificate-identity "signer@example.com" \
--certificate-oidc-issuer "https://accounts.google.com" \
sha256:abc123...
Verify with Local TUF Root
# Initialize TUF root (run once)
cosign initialize --mirror https://tuf-repo.sigstore.dev --root root.json
# Verify using local TUF data
SIGSTORE_ROOT_FILE=trusted_root.json \
cosign verify-attestation \
--certificate-identity "signer@example.com" \
--certificate-oidc-issuer "https://accounts.google.com" \
sha256:abc123...
Air-Gapped Verification
# 1. On connected machine: download required artifacts
cosign download attestation sha256:abc123... > attestation.json
cosign download signature sha256:abc123... > signature.sig
# 2. Transfer files to air-gapped environment
# 3. On air-gapped machine: verify with public key
cosign verify-attestation \
--key public.key \
--offline \
--type custom \
--attestation attestation.json \
sha256:abc123...
Verify with Policy
CUE Policy
// policy.cue
package attestation
predicateType: "https://stella-ops.org/attestation/scan-results/v1"
predicate: {
severity: *"low" | "medium" | "high" | "critical"
vulnerabilities: [...{
id: =~"^CVE-"
severity: !="critical"
}]
}
cosign verify-attestation \
--key public.key \
--type custom \
--policy policy.cue \
sha256:abc123...
Rego Policy
# policy.rego
package attestation
default allow = false
allow {
input.predicateType == "https://stella-ops.org/attestation/policy-evaluation/v1"
input.predicate.verdict == "PASS"
input.predicate.score >= 7.0
}
cosign verify-attestation \
--key public.key \
--type custom \
--policy policy.rego \
sha256:abc123...
Multi-Signature Verification
# Verify that multiple signatures are present
cosign verify-attestation \
--key builder.pub \
--type custom \
sha256:abc123... && \
cosign verify-attestation \
--key witness.pub \
--type custom \
sha256:abc123...
Output Formats
JSON Output
cosign verify-attestation \
--key public.key \
--type custom \
--output-file verification-result.json \
sha256:abc123...
Text Output with Details
cosign verify-attestation \
--key public.key \
--type custom \
-v \
sha256:abc123...
Troubleshooting
Common Errors
| Error | Cause | Solution |
|---|---|---|
no matching attestation found |
No attestation attached to image | Verify attestation was uploaded |
key verification failed |
Wrong key or corrupted signature | Check key matches signer |
certificate expired |
Signing certificate past validity | Use Rekor timestamp verification |
OIDC issuer mismatch |
Wrong issuer in verify command | Check certificate's issuer field |
predicate type mismatch |
Wrong --type argument | Use correct predicate URI |
Debug Commands
# List all attestations on an image
cosign tree sha256:abc123...
# Download and inspect attestation
cosign download attestation sha256:abc123... | jq .
# Verify with verbose output
cosign verify-attestation \
--key public.key \
--type custom \
-v \
sha256:abc123... 2>&1 | tee verify.log
# Check certificate chain
cosign download attestation sha256:abc123... | \
jq -r '.payload' | base64 -d | jq -r '.subject'
Verify Certificate Details
# Extract and inspect the signing certificate
cosign download attestation sha256:abc123... | \
jq -r '.signatures[0].cert' | base64 -d | \
openssl x509 -noout -text
Integration with CI/CD
GitHub Actions
- name: Verify attestation
uses: sigstore/cosign-installer@main
- name: Verify StellaOps attestation
run: |
cosign verify-attestation \
--certificate-identity "https://github.com/${{ github.repository }}/.github/workflows/build.yml@${{ github.ref }}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--type "https://stella-ops.org/attestation/scan-results/v1" \
${{ env.IMAGE_DIGEST }}
GitLab CI
verify-attestation:
image: bitnami/cosign:latest
script:
- cosign verify-attestation
--certificate-identity "https://gitlab.com/${CI_PROJECT_PATH}/.gitlab-ci.yml@${CI_COMMIT_REF_NAME}"
--certificate-oidc-issuer "https://gitlab.com"
--type "https://stella-ops.org/attestation/scan-results/v1"
${IMAGE_DIGEST}