name: Signals DSSE Sign & Evidence Locker on: workflow_dispatch: inputs: out_dir: description: "Output directory for signed artifacts" required: false default: "evidence-locker/signals/2025-12-01" allow_dev_key: description: "Allow dev key for testing (1=yes, 0=no)" required: false default: "0" push: branches: [main] paths: - 'docs/modules/signals/decay/**' - 'docs/modules/signals/unknowns/**' - 'docs/modules/signals/heuristics/**' - 'docs/modules/signals/SHA256SUMS' - 'tools/cosign/sign-signals.sh' jobs: sign-signals-artifacts: runs-on: ubuntu-22.04 env: COSIGN_PRIVATE_KEY_B64: ${{ secrets.COSIGN_PRIVATE_KEY_B64 }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} OUT_DIR: ${{ github.event.inputs.out_dir || 'evidence-locker/signals/2025-12-01' }} COSIGN_ALLOW_DEV_KEY: ${{ github.event.inputs.allow_dev_key || '0' }} steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install cosign uses: sigstore/cosign-installer@v3 with: cosign-release: 'v2.2.4' - name: Verify artifacts exist run: | cd docs/modules/signals sha256sum -c SHA256SUMS echo "All artifacts verified against SHA256SUMS" - name: Check signing key availability id: check-key run: | if [[ -n "$COSIGN_PRIVATE_KEY_B64" ]]; then echo "key_source=ci_secret" >> "$GITHUB_OUTPUT" echo "Signing key available via CI secret" elif [[ "$COSIGN_ALLOW_DEV_KEY" == "1" ]]; then echo "key_source=dev_key" >> "$GITHUB_OUTPUT" echo "[warn] Using development key - NOT for production Evidence Locker" else echo "key_source=none" >> "$GITHUB_OUTPUT" echo "::error::No signing key available. Set COSIGN_PRIVATE_KEY_B64 secret or enable dev key." exit 1 fi - name: Sign signals artifacts run: | chmod +x tools/cosign/sign-signals.sh OUT_DIR="${OUT_DIR}" tools/cosign/sign-signals.sh - name: Verify signatures run: | cd "$OUT_DIR" # List generated artifacts echo "=== Generated Artifacts ===" ls -la echo "" echo "=== SHA256SUMS ===" cat SHA256SUMS - name: Upload signed artifacts uses: actions/upload-artifact@v4 with: name: signals-dsse-signed-${{ github.run_number }} path: | ${{ env.OUT_DIR }}/*.sigstore.json ${{ env.OUT_DIR }}/*.dsse ${{ env.OUT_DIR }}/SHA256SUMS if-no-files-found: error retention-days: 90 - name: Push to Evidence Locker if: ${{ secrets.CI_EVIDENCE_LOCKER_TOKEN != '' && env.EVIDENCE_LOCKER_URL != '' }} env: TOKEN: ${{ secrets.CI_EVIDENCE_LOCKER_TOKEN }} URL: ${{ env.EVIDENCE_LOCKER_URL }} run: | tar -cf /tmp/signals-dsse.tar -C "$OUT_DIR" . curl -f -X PUT "$URL/signals/dsse/$(date -u +%Y-%m-%d)/signals-dsse.tar" \ -H "Authorization: Bearer $TOKEN" \ --data-binary @/tmp/signals-dsse.tar echo "Pushed to Evidence Locker" - name: Evidence Locker skip notice if: ${{ secrets.CI_EVIDENCE_LOCKER_TOKEN == '' || env.EVIDENCE_LOCKER_URL == '' }} run: | echo "::notice::Evidence Locker push skipped (CI_EVIDENCE_LOCKER_TOKEN or EVIDENCE_LOCKER_URL not set)" echo "Artifacts available as workflow artifact for manual ingestion" verify-signatures: runs-on: ubuntu-22.04 needs: sign-signals-artifacts steps: - name: Checkout uses: actions/checkout@v4 - name: Download signed artifacts uses: actions/download-artifact@v4 with: name: signals-dsse-signed-${{ github.run_number }} path: signed-artifacts/ - name: Install cosign uses: sigstore/cosign-installer@v3 with: cosign-release: 'v2.2.4' - name: Verify decay config signature run: | if [[ -f signed-artifacts/confidence_decay_config.sigstore.json ]]; then cosign verify-blob \ --key tools/cosign/cosign.dev.pub \ --bundle signed-artifacts/confidence_decay_config.sigstore.json \ docs/modules/signals/decay/confidence_decay_config.yaml \ && echo "✓ decay config signature verified" \ || echo "::warning::Signature verification failed (may need production public key)" fi - name: Verify unknowns manifest signature run: | if [[ -f signed-artifacts/unknowns_scoring_manifest.sigstore.json ]]; then cosign verify-blob \ --key tools/cosign/cosign.dev.pub \ --bundle signed-artifacts/unknowns_scoring_manifest.sigstore.json \ docs/modules/signals/unknowns/unknowns_scoring_manifest.json \ && echo "✓ unknowns manifest signature verified" \ || echo "::warning::Signature verification failed (may need production public key)" fi - name: Verify heuristics catalog signature run: | if [[ -f signed-artifacts/heuristics_catalog.sigstore.json ]]; then cosign verify-blob \ --key tools/cosign/cosign.dev.pub \ --bundle signed-artifacts/heuristics_catalog.sigstore.json \ docs/modules/signals/heuristics/heuristics.catalog.json \ && echo "✓ heuristics catalog signature verified" \ || echo "::warning::Signature verification failed (may need production public key)" fi - name: Summary run: | echo "## Signals DSSE Signing Summary" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" echo "| Artifact | Status |" >> "$GITHUB_STEP_SUMMARY" echo "|----------|--------|" >> "$GITHUB_STEP_SUMMARY" for f in signed-artifacts/*.sigstore.json signed-artifacts/*.dsse; do [[ -f "$f" ]] && echo "| $(basename $f) | ✓ Signed |" >> "$GITHUB_STEP_SUMMARY" done echo "" >> "$GITHUB_STEP_SUMMARY" echo "Run ID: ${{ github.run_number }}" >> "$GITHUB_STEP_SUMMARY"