Skip to content

fix: attach cosign signatures and provenance bundle to release assets#438

Merged
Aureliolo merged 4 commits intomainfrom
fix/signed-release-assets
Mar 15, 2026
Merged

fix: attach cosign signatures and provenance bundle to release assets#438
Aureliolo merged 4 commits intomainfrom
fix/signed-release-assets

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Add cosign keyless signing of checksums.txt in the CLI release job — produces .sig (detached signature) and .pem (Fulcio certificate) attached to the GitHub Release
  • Add Sigstore provenance bundle (.sigstore.json) for checksums.txt via a separate attest-build-provenance attestation, uploaded as a release asset
  • Update finalize-release to extract CLI_COSIGN_DATA from hidden HTML comments and render a "CLI Binary Signatures" subsection in the combined Verification section
  • Update docs (docs/security.md, docs/architecture/tech-stack.md, CLAUDE.md) to reflect the new signing and provenance capabilities

Why: OpenSSF Scorecard "Signed-Releases" check scores 0/10 because it only inspects GitHub Release assets for signature/provenance files. We have SLSA L3 attestations in GitHub's attestation store, but no .sig or .sigstore.json files on the release itself. This PR adds them, targeting 8/10 scoring.

Release assets after this change: 7 existing + checksums.txt.sig + checksums.txt.pem + checksums.txt.sigstore.json = 10 total.

Test plan

  • Verify YAML syntax is valid (pre-commit hooks pass)
  • Verify cosign-installer SHA pin matches docker.yml (ba7bc0a3...)
  • Verify step ordering: install cosign → GoReleaser → validate → sign → upload → attest → bundle upload → release notes
  • Verify $BUNDLE is passed via env: block (not direct interpolation)
  • Verify finalize-release extraction pattern matches embedded comment format
  • Real validation: next v* tag release exercises the full pipeline — check draft release has all 10 assets before finalize-release publishes

Review coverage

Pre-reviewed by 2 agents (docs-consistency, infra-reviewer), 6 findings addressed:

  • Removed unused id: attest step reference
  • Moved step output interpolation to env: block for security consistency
  • Updated docs/security.md, docs/architecture/tech-stack.md, CLAUDE.md for documentation accuracy

🤖 Generated with Claude Code

OpenSSF Scorecard "Signed-Releases" check scores 0/10 because it only
inspects GitHub Release assets for signature files. Add cosign keyless
signing of checksums.txt (.sig + .pem) and a Sigstore provenance bundle
(.sigstore.json) as release assets to achieve 8/10 scoring.

Release assets: 7 existing + checksums.txt.sig + checksums.txt.pem +
checksums.txt.sigstore.json = 10 total.
Pre-reviewed by 2 agents, 6 findings addressed:
- docs/security.md: add cosign signing to CLI binaries bullet
- docs/architecture/tech-stack.md: add cosign to CLI row and container
  packaging decision
- CLAUDE.md: document finalize-release verification assembly behavior
- cli.yml: remove unused step id, move step output to env: block
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 15, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
actions/sigstore/cosign-installer ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 🟢 8
Details
CheckScoreReason
Maintained🟢 910 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 9
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies🟢 10all dependencies are pinned
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Security-Policy🟢 10security policy file detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • .github/workflows/cli.yml

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the supply chain security and verifiability of CLI releases by integrating Cosign keyless signing and Sigstore provenance bundles directly into GitHub Release assets. This change directly addresses a limitation identified by the OpenSSF Scorecard, improving the project's "Signed-Releases" score by making signature and provenance information readily available alongside release artifacts, rather than solely in GitHub's attestation store.

Highlights

  • CLI Release Signing: Implemented Cosign keyless signing for checksums.txt in the CLI release job, generating .sig (detached signature) and .pem (Fulcio certificate) files that are attached to the GitHub Release.
  • Sigstore Provenance Bundle: Added a Sigstore provenance bundle (.sigstore.json) for checksums.txt via a separate attest-build-provenance attestation, which is also uploaded as a release asset.
  • Release Notes Enhancement: Updated the finalize-release workflow to extract CLI_COSIGN_DATA from hidden HTML comments and render a dedicated "CLI Binary Signatures" subsection within the combined Verification section of the release notes.
  • Documentation Updates: Updated CLAUDE.md, docs/security.md, and docs/architecture/tech-stack.md to accurately reflect the newly introduced signing and provenance capabilities for CLI releases.
Changelog
  • CLAUDE.md
    • Updated the description of the CLI workflow to include Cosign keyless signing and Sigstore provenance bundle attachment.
    • Updated the description of the finalize-release workflow to mention the extraction and assembly of verification data into release notes.
  • docs/architecture/tech-stack.md
    • Updated the CLI section to include Cosign keyless signing and Sigstore provenance bundle details.
    • Updated the Container Packaging section to clarify Cosign keyless signing for container images and CLI checksums file.
  • docs/security.md
    • Updated the "CLI binaries" entry under "Signed Artifacts" to reflect the addition of Cosign keyless signatures and Sigstore provenance bundles.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/cli.yml
    • .github/workflows/finalize-release.yml
Activity
  • Pre-reviewed by 2 agents (docs-consistency, infra-reviewer), with 6 findings addressed.
  • Removed an unused id: attest step reference.
  • Moved step output interpolation to an env: block for improved security consistency.
  • Updated docs/security.md, docs/architecture/tech-stack.md, and CLAUDE.md for documentation accuracy.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 838f05c5-2108-43ac-a49a-d330a8cd7d27

📥 Commits

Reviewing files that changed from the base of the PR and between e734b64 and 5642a74.

📒 Files selected for processing (1)
  • .github/workflows/cli.yml

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • CLI releases now include cosign keyless signatures, signature/certificate artifacts, and accompanying provenance bundles; release notes embed verification data and commands for easier validation.
  • Documentation
    • Security and architecture docs updated with guidance on new signing, provenance, and verification procedures for CLI and container artifacts.

Walkthrough

Adds Cosign keyless signing and Sigstore provenance bundle generation to the CLI release workflow, uploads signature/certificate/provenance artifacts to releases, and updates finalize-release logic to extract and embed CLI Cosign and SLSA provenance blocks into the combined VERIFICATION section. Documentation updated accordingly.

Changes

Cohort / File(s) Summary
Release Workflows
.github/workflows/cli.yml, .github/workflows/finalize-release.yml
Adds cosign installation and keyless signing of cli/dist/checksums.txt (produces checksums.txt.sig and checksums.txt.pem), generates a Sigstore/SLSA provenance bundle, uploads signature/certificate/provenance artifacts to releases, and extends finalize-release to extract CLI_COSIGN_DATA and CLI_SLSA_BUNDLE_DATA and render "CLI Binary Signatures" and "CLI Provenance Bundle" in VERIFICATION.
Documentation & Notes
docs/security.md, docs/architecture/tech-stack.md, CLAUDE.md
Updates describing Cosign keyless signing of CLI checksums, inclusion of .sig/.pem and Sigstore provenance bundles in releases, and verification commands (e.g., cosign verify-blob, gh attestation verify). Minor wording and security-observables clarifications.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Dev as Release Trigger
    participant GH as GitHub Actions
    participant Cosign as Cosign (keyless)
    participant Sigstore as Sigstore/Provenance
    participant Release as GitHub Release

    Dev->>GH: push tag / create draft release
    GH->>Cosign: install & sign cli/dist/checksums.txt
    Cosign-->>GH: produces checksums.txt.sig + checksums.txt.pem
    GH->>Sigstore: generate SLSA/provenance bundle for checksums
    Sigstore-->>GH: returns provenance bundle (.sigstore.json)
    GH->>Release: upload artifacts (checksums, .sig, .pem, .sigstore.json)
    GH->>GH: embed verification blocks (CLI_COSIGN_DATA, CLI_SLSA_BUNDLE_DATA) into release body
    GH->>Release: finalize release notes with VERIFICATION section
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: attaching cosign signatures and provenance bundles to release assets, which directly aligns with the primary objective of addressing OpenSSF Scorecard's Signed-Releases check.
Description check ✅ Passed The description is well-detailed and directly related to the changeset, explaining what was added (cosign signing, provenance bundle, finalize-release updates, docs updates), why it was done (OpenSSF Scorecard compliance), and what the expected outcomes are.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/signed-release-assets
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/signed-release-assets
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 15, 2026 11:42 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the documentation across several files (CLAUDE.md, docs/architecture/tech-stack.md, docs/security.md) to reflect the new cosign signing and Sigstore provenance bundle generation for CLI releases. The changes accurately describe the new security features. My review focuses on improving the readability and maintainability of the updated documentation, as some of the new descriptions are quite long and dense. I've suggested breaking down long lines and list items into more structured formats like sub-bullets to make the information easier to digest.

- **Docker**: `.github/workflows/docker.yml` — builds backend + web images, pushes to GHCR, signs with cosign. SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed, pushed to registry). Scans: Trivy (CRITICAL = hard fail, HIGH = warn-only) + Grype (critical cutoff). CVE triage via `.github/.trivyignore.yaml` and `.github/.grype.yaml`. Images only pushed after scans pass. Triggers on push to main and version tags (`v*`).
- **Matrix**: Python 3.14
- **CLI**: `.github/workflows/cli.yml` — Go lint (`golangci-lint` + `go vet`) + test (`-race -coverprofile`) + build (cross-compile matrix: linux/darwin/windows × amd64/arm64) + vulnerability check (`govulncheck`) + fuzz testing (main-only, 30s/target, `continue-on-error`, matrix over 4 packages) on `cli/**` changes. `cli-pass` gate includes fuzz result as informational warning. GoReleaser release on `v*` tags (attaches assets to the draft Release Please release). SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed). Post-release step appends install instructions + checksum table + provenance verification instructions to the draft release notes (while still in draft — before finalize-release publishes).
- **CLI**: `.github/workflows/cli.yml` — Go lint (`golangci-lint` + `go vet`) + test (`-race -coverprofile`) + build (cross-compile matrix: linux/darwin/windows × amd64/arm64) + vulnerability check (`govulncheck`) + fuzz testing (main-only, 30s/target, `continue-on-error`, matrix over 4 packages) on `cli/**` changes. `cli-pass` gate includes fuzz result as informational warning. GoReleaser release on `v*` tags (attaches assets to the draft Release Please release). Cosign keyless signing of `checksums.txt` (`.sig` + `.pem` attached to release). SLSA L3 provenance attestations via `actions/attest-build-provenance` (SHA-pinned, Sigstore-signed) for individual binaries and checksums file. Sigstore provenance bundle (`.sigstore.json`) attached to release for OpenSSF Scorecard signed-releases scoring. Post-release step appends install instructions + checksum table + cosign verification + provenance verification instructions to the draft release notes (while still in draft — before finalize-release publishes).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line is over 650 characters long, which makes it difficult to read and maintain. For better readability, consider breaking this down into sub-bullets to describe the different responsibilities of this workflow, perhaps separating the CI, Release, Signing, and Post-release steps.

- **CLA**: `.github/workflows/cla.yml` — Contributor License Agreement signature check on PRs via `contributor-assistant/github-action`. Triggers on `pull_request_target` and `issue_comment`. Skips Dependabot. Signatures stored in `.github/cla-signatures.json` on the `cla-signatures` branch (unprotected, so the action can commit directly).
- **Release**: `.github/workflows/release.yml` — Release Please (Google) auto-creates a release PR on every push to main. Merging the release PR creates a git tag (`vX.Y.Z`) + **draft** GitHub Release with changelog. Tag push triggers Docker and CLI workflows to attach assets to the draft. Uses `RELEASE_PLEASE_TOKEN` secret (PAT/GitHub App token) so tag creation triggers downstream workflows (GITHUB_TOKEN cannot). Config in `.github/release-please-config.json` (`"draft": true`) and `.github/.release-please-manifest.json`. After creating/updating a release PR, auto-updates the BSL Change Date in LICENSE to 3 years ahead.
- **Finalize Release**: `.github/workflows/finalize-release.yml` — publishes draft releases created by Release Please. Triggers on `workflow_run` completion of Docker and CLI workflows. Verifies that both workflows succeeded for the associated tag before publishing the draft. Guards against PR-triggered runs (`event != 'pull_request'`). Handles TOCTOU races (concurrent publish attempts exit cleanly). Immutable releases are enabled on the repo — once published, release assets and body cannot be modified.
- **Finalize Release**: `.github/workflows/finalize-release.yml` — publishes draft releases created by Release Please. Triggers on `workflow_run` completion of Docker and CLI workflows. Verifies that both workflows succeeded for the associated tag before publishing the draft. Extracts CLI checksums, CLI cosign verification, and container verification data from HTML comments embedded by the CLI and Docker workflows, and assembles them into a combined Verification section in the release notes. Guards against PR-triggered runs (`event != 'pull_request'`). Handles TOCTOU races (concurrent publish attempts exit cleanly). Immutable releases are enabled on the repo — once published, release assets and body cannot be modified.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line is over 580 characters long, making it hard to parse. For better readability, consider using sub-bullets to describe the different responsibilities of this workflow, such as triggering, verification, data extraction, and security guards.

| **Authentication** | PyJWT + argon2-cffi | JWT (HMAC HS256/384/512) for session tokens, Argon2id for password hashing, HMAC-SHA256 for API key storage (keyed with server secret). |
| **Config Format** | YAML + Pydantic validation | Human-readable config with strict validation. |
| **CLI** | Go (Cobra + charmbracelet/huh) | Cross-platform binary for Docker lifecycle management: `init`, `start`, `stop`, `status`, `logs`, `update`, `doctor`, `uninstall`, `version`. Distributed via GoReleaser + install scripts (`curl \| bash`, `irm \| iex`). SLSA Level 3 provenance attestations on all release archives. |
| **CLI** | Go (Cobra + charmbracelet/huh) | Cross-platform binary for Docker lifecycle management: `init`, `start`, `stop`, `status`, `logs`, `update`, `doctor`, `uninstall`, `version`. Distributed via GoReleaser + install scripts (`curl \| bash`, `irm \| iex`). Cosign keyless signing of checksums file (`.sig` + `.pem`). SLSA Level 3 provenance attestations on all release archives. Sigstore provenance bundle (`.sigstore.json`) attached to releases. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This table cell's content is becoming very dense. To improve readability, consider using an HTML list (<ul><li>...</li></ul>) or line breaks (<br>) to separate the different features of the CLI build and release process.

docs/security.md Outdated

- **Container images**: cosign keyless signatures (verify via `cosign verify`) + SLSA Level 3 provenance attestations (verify via `gh attestation verify`)
- **CLI binaries**: SLSA Level 3 provenance attestations (verify via `gh attestation verify`)
- **CLI binaries**: cosign keyless signature on checksums file (verify via `cosign verify-blob`) + SLSA Level 3 provenance attestations (verify via `gh attestation verify`) + Sigstore provenance bundle (`.sigstore.json`)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This list item contains multiple distinct pieces of information. To improve clarity and readability, consider breaking it down into sub-bullets.

Suggested change
- **CLI binaries**: cosign keyless signature on checksums file (verify via `cosign verify-blob`) + SLSA Level 3 provenance attestations (verify via `gh attestation verify`) + Sigstore provenance bundle (`.sigstore.json`)
- **CLI binaries**:
- cosign keyless signature on checksums file (verify via `cosign verify-blob`)
- SLSA Level 3 provenance attestations (verify via `gh attestation verify`)
- Sigstore provenance bundle (`.sigstore.json`)

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 15, 2026

Greptile Summary

This PR wires up cosign keyless signing and a Sigstore provenance bundle for CLI releases, targeting the OpenSSF Scorecard "Signed-Releases" check by attaching checksums.txt.sig, checksums.txt.pem, and checksums.txt.sigstore.json as release assets. It also extends finalize-release to extract and render the new verification snippets into the published release notes.

  • cli.yml: Installs cosign before GoReleaser, signs checksums.txt after build validation, uploads .sig/.pem alongside the archives, runs a second attest-build-provenance with subject-path to produce a harvestable bundle, then uploads it as checksums.txt.sigstore.json. Embedded HTML comments (CLI_COSIGN_DATA, CLI_SLSA_BUNDLE_DATA) carry the verification snippets for downstream consumption.
  • finalize-release.yml: Extracts the two new comment blocks with the same sed range+fence pattern already used for CLI_VERIFICATION_DATA, renders them as "CLI Binary Signatures" and "CLI Provenance Bundle" subsections, and strips the comment blocks from the final body.
  • Docs (CLAUDE.md, docs/security.md, docs/architecture/tech-stack.md): Updated to describe all three verification paths (cosign, gh attestation verify, cosign verify-blob-attestation).
  • The --type slsaprovenance1 flag is now present in the .sigstore.json verification command, addressing the previously flagged verify-blob-attestation predicate-version mismatch.
  • The "CLI Binary Signatures" section heading in finalize-release.yml is slightly misleading — only checksums.txt is signed by cosign, not the binary archives themselves.
  • cosign sign-blob has no post-signing guard: if Fulcio is unreachable the command can exit zero with empty output files that are then uploaded silently.

Confidence Score: 4/5

  • Safe to merge; the two open items are a slightly misleading heading and a missing post-sign sanity check, neither of which blocks the feature or causes a regression.
  • The workflow logic is structurally sound: step ordering is correct, permissions include id-token: write for keyless signing, the bundle-path output is referenced via a properly-named id: attest-checksums step, the cleanup pipeline in finalize-release removes all three new comment blocks, and the --type slsaprovenance1 flag resolves the previously-noted cosign predicate-version issue. The two style-level findings (misleading section title, missing emptiness guard on .sig/.pem) are low-risk but worth fixing before the first real tag release exercises the full path.
  • .github/workflows/cli.yml (post-sign emptiness guard) and .github/workflows/finalize-release.yml (section heading).

Important Files Changed

Filename Overview
.github/workflows/cli.yml Adds cosign keyless signing of checksums.txt (.sig+.pem) and a separate attest-build-provenance step that attests checksums.txt itself to harvest a .sigstore.json bundle — both uploaded to the draft release. Step ordering is correct: install cosign → GoReleaser → validate → sign → upload → attest binaries → attest checksums → upload bundle → append notes. The embedded CLI_COSIGN_DATA and CLI_SLSA_BUNDLE_DATA HTML comments provide verification snippets for finalize-release. Minor: a post-sign emptiness check on .sig/.pem before upload would guard against silent Fulcio failures.
.github/workflows/finalize-release.yml Extracts CLI_COSIGN_DATA and CLI_SLSA_BUNDLE_DATA from embedded HTML comments using the same sed range/fence pattern as the pre-existing CLI_VERIFICATION_DATA extraction, rendering them as "CLI Binary Signatures" and "CLI Provenance Bundle" subsections in the combined Verification section. Cleanup correctly removes both new comment blocks before re-appending. The "CLI Binary Signatures" heading is slightly misleading — only checksums.txt is signed, not the binary archives.
CLAUDE.md Documentation updated to describe cosign keyless signing of checksums.txt, SLSA L3 attestations for binaries and the checksums file, and the .sigstore.json bundle. Also expands the Finalize Release entry to mention the extraction of CLI cosign/SLSA data. Accurate and consistent with the workflow changes.
docs/security.md Expands the "CLI binaries" entry in the Signed Artifacts list to enumerate the three verification methods: cosign verify-blob (.sig+.pem), gh attestation verify (SLSA L3), and cosign verify-blob-attestation (.sigstore.json bundle). Accurately reflects the new pipeline.
docs/architecture/tech-stack.md Two table cells updated to mention cosign keyless signing of the checksums file and the .sigstore.json bundle on releases. Accurate and consistent with the new signing pipeline.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/finalize-release.yml
Line: 159

Comment:
**Misleading section heading for cosign data**

`"### CLI Binary Signatures"` implies the binary archives (`.tar.gz`/`.zip`) are individually signed with cosign, but only `checksums.txt` is signed. A user who reads this heading and then runs `cosign verify-blob` on a binary archive will get a failure. A more accurate heading would be `"### CLI Checksums Signature"` or `"### Checksums File Signature"`, making it clear that the signed artifact is `checksums.txt` (which transitively covers the binaries through their SHA-256 entries).

```suggestion
              VERIFICATION="$(printf '%s\n\n### CLI Checksums Signature\n\n%s\n' "$VERIFICATION" "$CLI_COSIGN")"
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/cli.yml
Line: 296-300

Comment:
**Consider failing explicitly if signing produces empty output files**

`cosign sign-blob --yes` exits zero on success, but if the OIDC token is unavailable or Fulcio is unreachable the command may still exit zero while producing empty `.sig`/`.pem` files. An empty certificate uploaded to the release would silently break verification for every user.

Adding a guard after signing (similar to the existing `Validate checksums file` check) would catch this before the upload step:

```bash
cosign sign-blob --yes cli/dist/checksums.txt \
  --output-signature cli/dist/checksums.txt.sig \
  --output-certificate cli/dist/checksums.txt.pem

if [ ! -s cli/dist/checksums.txt.sig ] || [ ! -s cli/dist/checksums.txt.pem ]; then
  echo "::error::cosign produced empty signature or certificate — signing may have failed silently"
  exit 1
fi
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 5642a74

- Add .sigstore.json verification instructions (CLI_SLSA_BUNDLE_DATA
  block) to release notes and finalize-release extraction
- Add inline comments distinguishing dual attestation steps
  (subject-checksums vs subject-path)
- Use sub-bullets in docs/security.md for CLI binaries readability
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 15, 2026 11:58 — with GitHub Actions Inactive
attest-build-provenance@v4 produces SLSA v1.0 predicates, but cosign
defaults to v0.2 (slsaprovenance). Without --type slsaprovenance1 the
verification command would fail with a predicate type mismatch.
@Aureliolo Aureliolo merged commit f191a4d into main Mar 15, 2026
34 of 35 checks passed
@Aureliolo Aureliolo deleted the fix/signed-release-assets branch March 15, 2026 12:04
fi

if [ -n "$CLI_COSIGN" ]; then
VERIFICATION="$(printf '%s\n\n### CLI Binary Signatures\n\n%s\n' "$VERIFICATION" "$CLI_COSIGN")"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misleading section heading for cosign data

"### CLI Binary Signatures" implies the binary archives (.tar.gz/.zip) are individually signed with cosign, but only checksums.txt is signed. A user who reads this heading and then runs cosign verify-blob on a binary archive will get a failure. A more accurate heading would be "### CLI Checksums Signature" or "### Checksums File Signature", making it clear that the signed artifact is checksums.txt (which transitively covers the binaries through their SHA-256 entries).

Suggested change
VERIFICATION="$(printf '%s\n\n### CLI Binary Signatures\n\n%s\n' "$VERIFICATION" "$CLI_COSIGN")"
VERIFICATION="$(printf '%s\n\n### CLI Checksums Signature\n\n%s\n' "$VERIFICATION" "$CLI_COSIGN")"
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/finalize-release.yml
Line: 159

Comment:
**Misleading section heading for cosign data**

`"### CLI Binary Signatures"` implies the binary archives (`.tar.gz`/`.zip`) are individually signed with cosign, but only `checksums.txt` is signed. A user who reads this heading and then runs `cosign verify-blob` on a binary archive will get a failure. A more accurate heading would be `"### CLI Checksums Signature"` or `"### Checksums File Signature"`, making it clear that the signed artifact is `checksums.txt` (which transitively covers the binaries through their SHA-256 entries).

```suggestion
              VERIFICATION="$(printf '%s\n\n### CLI Checksums Signature\n\n%s\n' "$VERIFICATION" "$CLI_COSIGN")"
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +296 to +300
- name: Sign checksums with cosign (keyless)
run: |
cosign sign-blob --yes cli/dist/checksums.txt \
--output-signature cli/dist/checksums.txt.sig \
--output-certificate cli/dist/checksums.txt.pem
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider failing explicitly if signing produces empty output files

cosign sign-blob --yes exits zero on success, but if the OIDC token is unavailable or Fulcio is unreachable the command may still exit zero while producing empty .sig/.pem files. An empty certificate uploaded to the release would silently break verification for every user.

Adding a guard after signing (similar to the existing Validate checksums file check) would catch this before the upload step:

cosign sign-blob --yes cli/dist/checksums.txt \
  --output-signature cli/dist/checksums.txt.sig \
  --output-certificate cli/dist/checksums.txt.pem

if [ ! -s cli/dist/checksums.txt.sig ] || [ ! -s cli/dist/checksums.txt.pem ]; then
  echo "::error::cosign produced empty signature or certificate — signing may have failed silently"
  exit 1
fi
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/cli.yml
Line: 296-300

Comment:
**Consider failing explicitly if signing produces empty output files**

`cosign sign-blob --yes` exits zero on success, but if the OIDC token is unavailable or Fulcio is unreachable the command may still exit zero while producing empty `.sig`/`.pem` files. An empty certificate uploaded to the release would silently break verification for every user.

Adding a guard after signing (similar to the existing `Validate checksums file` check) would catch this before the upload step:

```bash
cosign sign-blob --yes cli/dist/checksums.txt \
  --output-signature cli/dist/checksums.txt.sig \
  --output-certificate cli/dist/checksums.txt.pem

if [ ! -s cli/dist/checksums.txt.sig ] || [ ! -s cli/dist/checksums.txt.pem ]; then
  echo "::error::cosign produced empty signature or certificate — signing may have failed silently"
  exit 1
fi
```

How can I resolve this? If you propose a fix, please make it concise.

@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 15, 2026 12:09 — with GitHub Actions Inactive
Aureliolo added a commit that referenced this pull request Mar 15, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.2.4](v0.2.3...v0.2.4)
(2026-03-15)


### Bug Fixes

* attach cosign signatures and provenance bundle to release assets
([#438](#438))
([f191a4d](f191a4d))
* create git tag explicitly for draft releases
([#432](#432))
([1f5120e](1f5120e))
* docker healthcheck, CI optimization, and container hardening
([#436](#436))
([4d32bca](4d32bca))
* ensure security headers on all HTTP responses
([#437](#437))
([837f2fc](837f2fc))
* make install scripts usable immediately without terminal restart
([#433](#433))
([b45533c](b45533c))
* migrate pids_limit to deploy.resources.limits.pids
([#439](#439))
([66b94fd](66b94fd))


### Refactoring

* redesign release notes layout
([#434](#434))
([239aaf7](239aaf7))


### Maintenance

* **site:** replace hero CTA with license link and scroll arrow
([#440](#440))
([56af41c](56af41c))
* **web:** adopt @vue/tsconfig preset
([#435](#435))
([7d4b214](7d4b214))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Aureliolo added a commit that referenced this pull request Mar 15, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.2.4](v0.2.3...v0.2.4)
(2026-03-15)


### Bug Fixes

* attach cosign signatures and provenance bundle to release assets
([#438](#438))
([f191a4d](f191a4d))
* create git tag explicitly for draft releases
([#432](#432))
([1f5120e](1f5120e))
* docker healthcheck, CI optimization, and container hardening
([#436](#436))
([4d32bca](4d32bca))
* ensure security headers on all HTTP responses
([#437](#437))
([837f2fc](837f2fc))
* make install scripts usable immediately without terminal restart
([#433](#433))
([b45533c](b45533c))
* migrate pids_limit to deploy.resources.limits.pids
([#439](#439))
([66b94fd](66b94fd))
* use cosign --bundle flag for checksums signing
([#443](#443))
([19735b9](19735b9))


### Refactoring

* redesign release notes layout
([#434](#434))
([239aaf7](239aaf7))


### Maintenance

* **main:** release 0.2.4
([#431](#431))
([63b03c4](63b03c4))
* remove stale v0.2.4 changelog section from failed release
([#446](#446))
([769de10](769de10))
* reset version to 0.2.3 for re-release
([#444](#444))
([8579993](8579993))
* **site:** replace hero CTA with license link and scroll arrow
([#440](#440))
([56af41c](56af41c))
* **web:** adopt @vue/tsconfig preset
([#435](#435))
([7d4b214](7d4b214))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant