Skip to content

Harden PyPI and GitHub release trust - #105

Merged
ChelseaKR merged 1 commit into
mainfrom
agent/harden-release-trust
Aug 5, 2026
Merged

Harden PyPI and GitHub release trust#105
ChelseaKR merged 1 commit into
mainfrom
agent/harden-release-trust

Conversation

@ChelseaKR

Copy link
Copy Markdown
Owner

Summary

  • Verifies signed tags from reviewed main, builds the exact commit, and rechecks tag identity before PyPI and GitHub publication.
  • pins the maintainer SSH signer in the repository
  • documents the release-boundary change in the changelog

Validation

  • portfolio conformance release_workflow: PASS
  • actionlint: PASS
  • zizmor offline, medium+ findings: none
  • YAML parse and git diff --check: PASS

@ChelseaKR

Copy link
Copy Markdown
Owner Author

Drain-prep review 2026-07-31: MERGE-READY (pending un-draft — owner: @ChelseaKR)

Reviewed the full 252-line diff. This is a sound hardening of the release control plane:

  • Trigger moves from tag-push to workflow_dispatch from reviewed main — the verify job asserts GITHUB_REF == refs/heads/main and head == origin/main before touching the tag.
  • Closes the REL-08 identity gap the old workflow honestly documented: .github/allowed_signers pins the maintainer SSH key and git verify-tag now checks the signer, not just signature presence.
  • Ancestry check (merge-base --is-ancestor against origin/main), strict vX.Y.Z regex, and immutable tag-object re-verification immediately before both the PyPI publish and the GitHub Release create — good TOCTOU hygiene; --verify-tag retained.
  • All downstream jobs build the exact resolved release commit via ref:, and the publish jobs stay least-privilege.

All 16 checks green. Two conscious trade-offs to confirm when un-drafting: (1) releases now require a manual dispatch — no tag-push automation; (2) a signer-key rotation now requires a repo commit. Both seem intended. Also see #103 (pypi-publish 1.14.1) which touches the same publish step — carry the newer pin in whichever lands second. Advances #80, though PyPI Trusted Publisher registration remains a user action.

🤖 Generated with Claude Code

@ChelseaKR

Copy link
Copy Markdown
Owner Author

Rebase check (automated sprint pass): this branch is 14 commits behind main and conflicts on merge. I did a trial rebase locally — one real conflict, in .github/workflows/release.yml, where this branch's new "recheck immutable tag object before PyPI publication" step landed next to main's dependabot bump of pypa/gh-action-pypi-publish (1.14.0 → 1.14.2). Resolved by keeping the new step and taking main's newer pin; all other action pins already matched main exactly. Also had to hand-merge CHANGELOG.md — both sides added a ### Fixed bullet to ## [Unreleased] in non-conflicting positions, which produced two ### Fixed headers; consolidated into one.

Verified after rebase: YAML parses, zizmor (no findings), actionlint (clean).

Per this repo's "never force-push" guardrail I did not overwrite agent/harden-release-trust. The rebased result is pushed to agent/harden-release-trust-rebased-2026-08-04 for review — if it looks right, force-push it onto this branch (or I can if asked explicitly) to actually update this PR.

🤖 Generated with Claude Code

@ChelseaKR
ChelseaKR force-pushed the agent/harden-release-trust branch from 0667b37 to dce7bc0 Compare August 5, 2026 15:57
@ChelseaKR
ChelseaKR marked this pull request as ready for review August 5, 2026 16:00
@ChelseaKR
ChelseaKR merged commit aaa833a into main Aug 5, 2026
18 checks passed
@ChelseaKR
ChelseaKR deleted the agent/harden-release-trust branch August 5, 2026 16:00
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