feat(release): SOC2-03 signed release tags + per-release evidence procedure (#218)#241
Merged
Merged
Conversation
…218 sub-task) Plan for SOC2-03: extend #237's cosign-keyless pipeline with one new step (sign-blob the release tag's commit SHA), ship a per-release evidence-collection helper (`release/evidence_collect.py`), and author the operator-readable workflow doc (`docs/RELEASE_EVIDENCE_PROCEDURE.md`). Audit: round 1 PASS (L1, mechanical extension of locked substrate). Three substrate observations folded into implementation: - Wait for #237 merge before implementing (NOW SATISFIED) - Add SOC2-03 closure pointer to research brief (matches Plan D pattern) - Update publish.yml strip step for new tag-commit artifacts Closes #218 sub-task SOC2-03 (3rd of 6 epic items, after LLM-11 + OWASP-01). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`release/evidence_collect.py` — small CLI that runs gh CLI subprocess
calls to gather per-release evidence (merged PRs, CI runs, reviewer
attribution) and renders a markdown scaffold. Operators run the script
post-release via:
python -m release.evidence_collect \
--from-tag v0.13.7 --to-tag v0.13.8 \
--output dist/release-evidence-v0.13.8.md
Subprocess discipline (OWASP A03): every subprocess.run invocation
uses list-form argv with shell=False (the default). 6 functional tests
including a stub that captures cmd + kwargs to assert the contract.
Failure propagation (OWASP A04): subprocess.CalledProcessError raises
through `collect_evidence`; no silent empty-evidence fallback. Empty PR
list / empty CI list emit explicit "No PRs in window" notes — never
silent omission, which would be misleading evidence.
Razor: render_markdown originally 58 LOC, split into 3 section
helpers (_render_pr_section, _render_ci_section, _render_reviews_section)
each <20 LOC, with the orchestrator coming in at ~20 LOC.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extend the publish.yml build job with one new step: cosign sign-blob
the SHA the release tag points at. Output triple
(release-tag-commit.txt + .sig + .crt) attaches to the GitHub Release
alongside the existing artifacts (wheel, hooks-manifest, SBOM).
PyPI strip-step updated to enumerate the new tag-commit artifacts
(they sit at dist/ root, not under dist/share/, so the existing
dist/share strip wouldn't catch them and they'd incorrectly land on
PyPI alongside the wheel).
Operators verify the tag-commit signature via:
cosign verify-blob \
--certificate-identity-regexp "^https://github.com/BicameralAI/bicameral-mcp/" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--signature release-tag-commit.txt.sig \
--certificate release-tag-commit.txt.crt \
release-tag-commit.txt
Successful verification proves the workflow signed this exact commit
SHA at release-publish time — the SOC 2 CC8.1 change-control evidence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…218 SOC2-03) `docs/RELEASE_EVIDENCE_PROCEDURE.md` — operator-readable per-release evidence workflow: - Pre-release checklist (PR review status, CI green, no force-pushes) - Release-tag creation steps (git tag -a, gh release create) - Post-release verification (workflow succeeded, expected artifacts attached) - Evidence-collection invocation (`python -m release.evidence_collect ...`) - Operator narrative section (rationale, exceptions, attestation statement) - Retention policy (>=7 years SOC 2 audit window; storage operator-chosen) - Verification commands for auditor-side independent verification (cosign verify-blob for tag-commit + hooks-manifest; cosign verify-attestation for SBOM) `docs/research-brief-compliance-audit-2026-05-06.md` SOC2-03 entry gets the closure pointer matching the bidirectional pattern Plan D established for MCP-01, NIST-RMF-01, AI-ACT-02, SOC2-02. Closes #218 sub-task SOC2-03. Three of six epic items closed (LLM-11 + OWASP-01 from #237; SOC2-03 from this PR). Three remain: OWASP-03 (lockfile), OWASP-05 (RECOMMENDED_VERSION URL signing), LLM-06/#214 (skills/MANIFEST.toml). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #218 sub-task SOC2-03. Extends #237's cosign-keyless pipeline with one new step (sign-blob the release tag's commit SHA) and ships the operator-readable per-release evidence procedure + helper.
Plan / Audit
plan-C-soc2-03-signed-tags-and-release-evidence.mdWhat ships
.github/workflows/publish.ymlrelease/evidence_collect.py(new, 200 LOC)docs/RELEASE_EVIDENCE_PROCEDURE.md(new)tests/test_release_evidence_collect.py(new, 6 functional tests)docs/research-brief-compliance-audit-2026-05-06.mdTest plan
tests/test_release_evidence_collect.py)ruff check+ruff format --checkcleanmypy release/evidence_collect.pycleanInheritance from #237
This PR extends the cosign-keyless trust root that #237 bootstrapped:
BicameralAI/bicameral-mcp)token.actions.githubusercontent.com)cosign verify-blobverification command shapeCloses
docs/research-brief-compliance-audit-2026-05-06.md§ 2.2 SOC2-03 →docs/RELEASE_EVIDENCE_PROCEDURE.mdEpic #218 progress
3 of 6 sub-tasks closed:
3 remain: OWASP-03 (lockfile), OWASP-05 (RECOMMENDED_VERSION URL signing), LLM-06/#214 (skills/MANIFEST.toml).
🤖 Generated with Claude Code