Skip to content

fix: verify GoReleaser before privileged release execution - #96

Merged
jbeckwith-oai merged 1 commit into
mainfrom
codex/sdk-310-verify-goreleaser
Aug 18, 2026
Merged

jbeckwith-oai merged 1 commit into
mainfrom
codex/sdk-310-verify-goreleaser

Conversation

@jbeckwith-oai

Copy link
Copy Markdown
Contributor

Summary

  • replace the unverified goreleaser/goreleaser-action binary installer with a shared, repository-owned installer that verifies version- and platform-bound SHA-256 digests before extracting GoReleaser
  • install and verify the release tool before minting repository/Homebrew write tokens or exposing macOS signing/notarization secrets; install from the trusted workflow checkout so existing historical release tags remain publishable
  • exercise the same verified installer in snapshot CI and cover successful installation, tampered archives, ambiguous duplicate digests, and versions without a reviewed digest
  • document how to verify GoReleaser's upstream Sigstore signer identity and regenerate the four Linux/macOS host-archive digests when updating the pinned version

Why

Linear SDK-310 identified that SHA-pinning goreleaser/goreleaser-action does not verify the separate GoReleaser archive downloaded and executed by that action. In the release workflow, that executable receives repository/Homebrew write credentials and macOS signing/notarization secrets. Existing attestations cover our output artifacts, not the privileged build tool input.

This change establishes a fail-closed boundary before extraction or privileged execution while preserving the existing GoReleaser configuration, all release target platforms/package formats, artifact attestations, and historical-tag republishing.

Security and regression review

  • completed two independent code-review passes plus a seven-file Codex Security diff scan; fixed the identified historical-tag checkout regression before publishing
  • verified GoReleaser's upstream checksums.txt.sigstore.json against the exact goreleaser/goreleaser/.github/workflows/release.yml@refs/tags/v2.15.4 identity and GitHub Actions OIDC issuer (cosign verify-blob: Verified OK)
  • matched all four committed digests against both the upstream signed checksum manifest and GitHub release asset metadata
  • downloaded and verified the actual Linux/x86_64 runner archive and macOS/arm64 archive
  • confirmed structurally that verification occurs before historical-tag checkout, repository/Homebrew token creation, and macOS signing/notarization secret exposure

Verification

  • ./scripts/test-goreleaser-installer
  • bash -n scripts/install-goreleaser scripts/test-goreleaser-installer
  • go build ./...
  • go test ./internal/...
  • go test ./pkg/cmd -run 'Test(ValidateBaseURL|FormatJSON|MTLSClientFlags|NewMTLSHTTPClient|MultipartRequestBody|ExactLengthUpload)'
  • go mod verify
  • verified GoReleaser 2.15.4: goreleaser check
  • verified GoReleaser 2.15.4: goreleaser release --snapshot --clean --skip=publish (all nine Linux/macOS/Windows targets, existing archives/Linux packages, and Homebrew cask succeeded)
  • parsed all changed GitHub Actions YAML and checked historical release tags v1.8.0 / v1.7.1 against the corrected workflow ordering

SDK-310

Copilot AI lite review requested due to automatic review settings August 18, 2026 22:25
@jbeckwith-oai
jbeckwith-oai requested a review from a team as a code owner August 18, 2026 22:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the release pipeline by replacing the GoReleaser GitHub Action’s unverified archive installer with a repository-owned installer that verifies reviewed SHA-256 digests before extracting and running GoReleaser, and ensures this happens before any privileged tokens or signing/notarization secrets are created/exposed.

Changes:

  • Add scripts/install-goreleaser to download a pinned GoReleaser release asset and verify it against .goreleaser-checksums before extraction/installation.
  • Update CI and publish workflows to use a new composite action (./.github/actions/setup-goreleaser) and run GoReleaser via the verified installation rather than goreleaser/goreleaser-action.
  • Add a focused installer verification test script and document the digest regeneration + Sigstore verification process for updating the pinned version.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
scripts/test-goreleaser-installer Adds verification tests covering success, tampering, ambiguous digests, and missing reviewed digests.
scripts/install-goreleaser Implements a fail-closed GoReleaser installer that verifies a reviewed SHA-256 digest before extraction.
docs/releasing.md Documents how to verify upstream Sigstore identity and regenerate the reviewed host-archive digests.
.goreleaser-checksums Adds reviewed SHA-256 digests for the pinned GoReleaser host archives.
.github/workflows/publish-release.yml Installs verified GoReleaser before tag checkout and before minting write tokens / exposing secrets; runs GoReleaser directly.
.github/workflows/ci.yml Exercises the verified installer in CI and runs snapshot GoReleaser using the verified setup.
.github/actions/setup-goreleaser/action.yml Introduces a composite action wrapper for installing and adding the verified GoReleaser to PATH.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@HAYDEN-OAI HAYDEN-OAI 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.

Independently verified the upstream Sigstore release-workflow identity and all four version/platform-bound SHA-256 digests; confirmed verification happens before archive extraction, write-token creation, and signing/notarization secret exposure; reproduced fail-closed behavior for tampered archives, duplicate/missing digests, malformed versions, and interrupted downloads; validated all 12 existing historical release tags; and successfully reproduced the full nine-target release snapshot (36 artifacts). No substantive security or release-compatibility issues found.

@jbeckwith-oai
jbeckwith-oai added this pull request to the merge queue Aug 18, 2026
Merged via the queue into main with commit b3729ea Aug 18, 2026
9 checks passed
@jbeckwith-oai
jbeckwith-oai deleted the codex/sdk-310-verify-goreleaser branch August 18, 2026 22:54
@openai-sdks openai-sdks Bot mentioned this pull request Aug 18, 2026
markstuart-oai pushed a commit to fallintoplace/openai-cli that referenced this pull request Sep 6, 2026
Automated Release PR
---


## [1.9.0](openai/openai-cli@v1.8.0...v1.9.0)
(2026-08-26)


### Features

* **api:** Add residency flag and deprecate geography
([openai#136](openai#136))
([e460582](openai@e460582))


### Bug Fixes

* Add provenance-aware untrusted stdin mode
([openai#137](openai#137))
([a133707](openai@a133707))
* build CLI releases with patched Go toolchains
([openai#93](openai#93))
([a58f1cc](openai@a58f1cc))
* discard fish completion diagnostics
([openai#109](openai#109))
([4f35fc0](openai@4f35fc0))
* escape raw output controls on interactive terminals
([openai#112](openai#112))
([7601afb](openai@7601afb))
* fail closed when bootstrapping Go dependencies
([openai#94](openai#94))
([4ebe610](openai@4ebe610))
* lock and verify Steady mock tooling
([openai#95](openai#95))
([681d595](openai@681d595))
* prepare release artifacts before publishing
([openai#111](openai#111))
([4193619](openai@4193619))
* redact sensitive response headers in debug logs
([openai#106](openai#106))
([4931572](openai@4931572))
* reject invalid multipart MIME header controls
([openai#105](openai#105))
([fad98b4](openai@fad98b4))
* restrict downloaded file permissions
([openai#107](openai#107))
([7a3a7d1](openai@7a3a7d1))
* safely construct bash file completions
([openai#110](openai#110))
([b3e0946](openai@b3e0946))
* stream binary download responses
([openai#108](openai#108))
([1f3ba6c](openai@1f3ba6c))
* stream multipart uploads without buffering
([openai#65](openai#65))
([bcf0ecd](openai@bcf0ecd))
* verify GoReleaser before privileged release execution
([openai#96](openai#96))
([b3729ea](openai@b3729ea))


### Chores

* **api:** clarify image background and audio delta docs
([openai#124](openai#124))
([056f306](openai@056f306))
* **api:** No customer-visible SDK or public API changes
([openai#128](openai#128))
([12e0d28](openai@12e0d28))
* **api:** refresh image model API reference
([openai#115](openai#115))
([a771913](openai@a771913))
* **api:** Refresh the bundled OpenAPI reference
([openai#66](openai#66))
([d14387a](openai@d14387a))
* **api:** Report no customer-visible SDK or public API changes
([openai#113](openai#113))
([8da2d53](openai@8da2d53))
* **api:** update generation metadata only
([openai#138](openai#138))
([4244a62](openai@4244a62))
* configure Dependabot for Go and GitHub Actions
([openai#69](openai#69))
([f495366](openai@f495366))
* **deps:** bump actions/attest-build-provenance from 4.1.0 to 4.2.2
([openai#102](openai#102))
([6594c73](openai@6594c73))
* **deps:** bump actions/checkout from 6.0.2 to 7.0.1
([openai#103](openai#103))
([ce6a6d0](openai@ce6a6d0))
* **deps:** bump actions/checkout from 6.0.2 to 7.0.1
([openai#134](openai#134))
([f40d5f2](openai@f40d5f2))
* **deps:** bump actions/download-artifact from 4.3.0 to 8.0.1
([openai#133](openai#133))
([98ed029](openai@98ed029))
* **deps:** bump actions/github-script from 7.1.0 to 9.0.0
([openai#132](openai#132))
([978ce47](openai@978ce47))
* **deps:** bump actions/setup-go in /
([openai#101](openai#101))
([5564982](openai@5564982))
* **deps:** bump actions/upload-artifact from 4.6.2 to 7.0.1
([openai#104](openai#104))
([b3ac15a](openai@b3ac15a))
* **deps:** bump github.com/charmbracelet/bubbles from 0.21.0 to 1.0.0
([openai#99](openai#99))
([7ac7035](openai@7ac7035))
* **deps:** bump github.com/urfave/cli/v3 from 3.4.1 to 3.10.1 in the
go-minor-and-patch group across 1 directory
([openai#130](openai#130))
([ddc612e](openai@ddc612e))
* **deps:** bump the charmbracelet group across 1 directory with 2
updates ([openai#97](openai#97))
([2137b80](openai@2137b80))
* **deps:** bump the codeql group across 1 directory with 2 updates
([openai#100](openai#100))
([c95ac0a](openai@c95ac0a))
* **deps:** bump the codeql group across 1 directory with 2 updates
([openai#131](openai#131))
([58e3bdd](openai@58e3bdd))
* **deps:** bump the go-minor-and-patch group across 1 directory with 5
updates ([openai#98](openai#98))
([74822be](openai@74822be))
* **deps:** update openai-go to v3.51.0
([openai#63](openai#63))
([68e3e70](openai@68e3e70))
* **deps:** update openai-go to v3.52.0
([openai#67](openai#67))
([7d87ee2](openai@7d87ee2))
* set a 1,000-line custom-code budget
([openai#126](openai#126))
([016bfb2](openai@016bfb2))


### Documentation

* add secure CLI agent and contributor guidance
([openai#72](openai#72))
([09ec087](openai@09ec087))
* standardize CLI vulnerability disclosure policy
([openai#71](openai#71))
([d082a01](openai@d082a01))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: openai-sdks[bot] <284451331+openai-sdks[bot]@users.noreply.github.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.

3 participants