Skip to content

Sign release SHA256SUMS with cosign keyless#65

Merged
toshi0806 merged 2 commits into
mainfrom
issue-69-cosign-signing
Jul 4, 2026
Merged

Sign release SHA256SUMS with cosign keyless#65
toshi0806 merged 2 commits into
mainfrom
issue-69-cosign-signing

Conversation

@toshi0806

Copy link
Copy Markdown
Member

Summary

Follow-up to the E-5 checksums (smkwlab/.github#69): SHA256SUMS proves integrity but not authenticity — it sits on the same Release as the binaries, so an attacker who can tamper with the release can swap both. This adds cosign keyless signing to close that gap.

Changes

release.yml (release job):

  • permissions: id-token: write — keyless signing via GitHub OIDC (no long-lived key/secret to manage or rotate).
  • Install cosign (sigstore/cosign-installer, SHA-pinned).
  • Sign SHA256SUMSSHA256SUMS.cosign.bundle (self-contained: signature + Fulcio cert + Rekor transparency-log proof), bound to this workflow's identity. Signing the manifest transitively covers both binaries.
  • verify-blob the bundle in-workflow so a broken signature fails the release. Uploaded by the existing release/* glob.

README — optional "Verifying authenticity (cosign)" step:

cosign verify-blob \
  --bundle SHA256SUMS.cosign.bundle \
  --certificate-identity-regexp '^https://github.com/smkwlab/tdig/\.github/workflows/release\.yml@refs/tags/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  SHA256SUMS

Verification stays optional — the binary works without it; only verifiers pay the cost.

Verification

  • actionlint clean, YAML parses.
  • ⚠️ Keyless signing needs the CI OIDC token, so it can only be exercised on a real tagged release run — it cannot be tested locally. The in-workflow verify-blob is the built-in self-check for that run. Recommend confirming on the next release (e.g. 0.4.1) before relying on it.

Refs smkwlab/.github#69 (E-5 signing follow-up).

🤖 Generated with Claude Code

SHA256SUMS proves integrity but not authenticity: it lives on the same
Release as the binaries, so anyone who can tamper with the release can swap
both. Add cosign keyless signing to close that gap.

release.yml:
- Grant the release job id-token: write (keyless signing via GitHub OIDC;
  no long-lived key/secret to manage).
- Install cosign (sigstore/cosign-installer, SHA-pinned).
- Sign SHA256SUMS -> SHA256SUMS.cosign.bundle (self-contained: signature +
  Fulcio cert + Rekor proof), and verify-blob it in-workflow so a broken
  signature fails the release. The bundle is uploaded by the existing
  `release/*` glob. Signing the manifest covers both binaries transitively.

README: add an optional "Verifying authenticity (cosign)" step with the
verify-blob command (identity = the release workflow, OIDC issuer = GitHub).

Validated: actionlint clean, YAML parses. Keyless signing needs the CI OIDC
token so it can only be exercised on a real tagged release run — the
in-workflow verify-blob is the built-in self-check for that run.

Refs smkwlab/.github#69 (E-5 signing follow-up).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JPuooHgsrboSEbfJsNf6iG

@github-actions github-actions Bot left a comment

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.

全体として、cosign keyless署名の導入は release の authenticity を担保する優れた改善です。設計・ドキュメントとも丁寧に記述されており、in-workflow の verify-blob による自己検証も適切です。いくつか正規表現の堅牢性に関する軽微な指摘があります。

Comment thread .github/workflows/release.yml Outdated
# Fail the release if the bundle we just produced does not verify.
cosign verify-blob \
--bundle SHA256SUMS.cosign.bundle \
--certificate-identity-regexp "^https://github.com/${GITHUB_REPOSITORY}/\.github/workflows/release\.yml@refs/tags/" \

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.

ℹ️ [LOW] --certificate-identity-regexp の正規表現で ${GITHUB_REPOSITORY} を直接埋め込んでいますが、リポジトリ名に正規表現のメタ文字(例: . など)が含まれる場合、意図しないマッチになる可能性があります。実際には smkwlab/tdig のように問題ないケースがほとんどですが、末尾に @refs/tags/ の後に anchor($ など)が無いため、tag部分は任意にマッチする点は意図通りか確認しておくとよいでしょう(README側にも同旨の注記あり)。厳密性を高めるなら本ワークフローの検証ではタグを固定する選択肢もあります。

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

対応しました。regexp の末尾を @refs/tags/[^/]+$ に anchor し、リリースタグ identity 1件に厳密一致させました(末尾に余分なパスが付く identity を弾く)。README の例も同様に更新。なお ${GITHUB_REPOSITORY} のメタ文字懸念は本リポ名 smkwlab/tdig にメタ文字が無いため実害はありませんが、anchor 追加で過剰マッチの余地も塞いでいます。actionlint は引き続き clean。

uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Install cosign
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3

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.

✨ [POSITIVE] cosign-installer のピン留めが SHA 固定されているのは良い実践です。keyless 署名により長期鍵の管理・ローテーションが不要になり、workflow identity に署名がバインドされる点は運用面・セキュリティ面ともに明確な改善です。

The --certificate-identity-regexp ended at `@refs/tags/` (a prefix match).
Anchor the tag portion with `[^/]+$` so it matches exactly one release-tag
identity and can't match an identity with extra trailing path segments.
Benign for real GitHub OIDC identities, but tighter is correct for a
verification regexp. Mirrored in the README example.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JPuooHgsrboSEbfJsNf6iG

@github-actions github-actions Bot left a comment

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.

cosign keyless署名の追加は、リリース成果物の真正性を担保する優れたセキュリティ強化です。ワークフロー内での自己検証(verify-blob)を組み込んでいる点も堅牢な設計です。いくつか軽微な指摘があります。

# Fail the release if the bundle we just produced does not verify.
cosign verify-blob \
--bundle SHA256SUMS.cosign.bundle \
--certificate-identity-regexp "^https://github.com/${GITHUB_REPOSITORY}/\.github/workflows/release\.yml@refs/tags/[^/]+$" \

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.

ℹ️ [LOW] in-workflowでのverify-blobはビルド時の健全性チェックとしては有効ですが、--certificate-identity-regexp.github/workflows/release.ymlにハードコードされており、ワークフローのパスやファイル名を変更した際に検証が壊れることに注意が必要です。将来のリネームに備え、コメントで依存関係を明記しておくとメンテナンス性が向上します。

uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Install cosign
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3

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.

ℹ️ [LOW] cosign-installerのバージョンピンがv3(メジャータグ)でコメントされていますが、SHA自体は固定されているため再現性は保たれています。他のアクション(checkout v4.3.1、download-artifact v4)とコメントの粒度を揃えると、レビュー時にどのパッチバージョンにピンされているか把握しやすくなります。

Comment thread README.md
# Verified OK
```

Once the manifest is verified, the `sha256sum` check above ties the binaries to

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.

✨ [POSITIVE] 検証手順の記載は明快で利用者に優しい内容です。--certificate-identity-regexpのタグ固定の代替案まで示している点は、セキュリティ意識の高い利用者への配慮として優れています。

@toshi0806
toshi0806 merged commit 3d3955c into main Jul 4, 2026
7 checks passed
@toshi0806
toshi0806 deleted the issue-69-cosign-signing branch July 4, 2026 00:11
@toshi0806 toshi0806 mentioned this pull request Jul 4, 2026
toshi0806 added a commit that referenced this pull request Jul 4, 2026
Release the cosign keyless signing of release binaries (#65). This release
also serves as the end-to-end verification of that signing step (the release
workflow signs SHA256SUMS and verify-blobs it in-CI).


Claude-Session: https://claude.ai/code/session_01JPuooHgsrboSEbfJsNf6iG

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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