name: Artifact Signing on: push: tags: - 'v*' workflow_dispatch: inputs: artifact_path: description: 'Path to artifact to sign' required: false default: '' env: COSIGN_VERSION: 'v2.2.0' jobs: sign-containers: name: Sign Container Images runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') permissions: contents: read id-token: write packages: write steps: - uses: actions/checkout@v4 - name: Install cosign uses: sigstore/cosign-installer@v3 with: cosign-release: ${{ env.COSIGN_VERSION }} - name: Log in to registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Sign images (keyless) if: ${{ !env.COSIGN_PRIVATE_KEY_B64 }} env: COSIGN_EXPERIMENTAL: "1" run: | IMAGES=( "ghcr.io/${{ github.repository }}/concelier" "ghcr.io/${{ github.repository }}/scanner" "ghcr.io/${{ github.repository }}/authority" ) for img in "${IMAGES[@]}"; do if docker manifest inspect "${img}:${{ github.ref_name }}" > /dev/null 2>&1; then echo "Signing ${img}:${{ github.ref_name }}..." cosign sign --yes "${img}:${{ github.ref_name }}" fi done - name: Sign images (with key) if: ${{ env.COSIGN_PRIVATE_KEY_B64 }} env: COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY_B64 }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} run: | echo "$COSIGN_PRIVATE_KEY" | base64 -d > /tmp/cosign.key IMAGES=( "ghcr.io/${{ github.repository }}/concelier" "ghcr.io/${{ github.repository }}/scanner" "ghcr.io/${{ github.repository }}/authority" ) for img in "${IMAGES[@]}"; do if docker manifest inspect "${img}:${{ github.ref_name }}" > /dev/null 2>&1; then echo "Signing ${img}:${{ github.ref_name }}..." cosign sign --key /tmp/cosign.key "${img}:${{ github.ref_name }}" fi done rm -f /tmp/cosign.key sign-sbom: name: Sign SBOM Artifacts runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: - uses: actions/checkout@v4 - name: Install cosign uses: sigstore/cosign-installer@v3 with: cosign-release: ${{ env.COSIGN_VERSION }} - name: Generate and sign SBOM run: | # Generate SBOM using syft if command -v syft &> /dev/null; then syft . -o cyclonedx-json > sbom.cdx.json cosign sign-blob --yes sbom.cdx.json --output-signature sbom.cdx.json.sig else echo "syft not installed, skipping SBOM generation" fi - name: Upload signed artifacts uses: actions/upload-artifact@v4 with: name: signed-sbom path: | sbom.cdx.json sbom.cdx.json.sig if-no-files-found: ignore verify-signatures: name: Verify Existing Signatures runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install cosign uses: sigstore/cosign-installer@v3 with: cosign-release: ${{ env.COSIGN_VERSION }} - name: Verify DSSE envelopes run: | find . -name "*.dsse" -o -name "*.dsse.json" | while read f; do echo "Checking $f..." # Basic JSON validation if ! jq empty "$f" 2>/dev/null; then echo "Warning: Invalid JSON in $f" fi done