supply-chain: attestation, SBOM, checksums, CodeQL + Scorecard (#178)#190
Merged
Conversation
…178) Cortex reads and persists every session transcript and installs session hooks with the user's full filesystem access; the wheel shipped with nothing a user could verify. This closes that. - release.yml: build-provenance attestation on wheel/sdist/SBOM (Sigstore); SHA-256 companion per GitHub-release asset; CycloneDX SBOM from uv.lock (torch/transformers/scipy/scikit-learn enumerated); PyPI keeps PEP 740 attestations; all actions SHA-pinned. - scorecard.yml: adopts the ecosystem's single Scorecard definition as a workflow_call CALL SITE (AP #77), not a copy; report-only baseline. - codeql.yml: Python security-and-quality on a weekly schedule + PR. - scripts/verify_release_artifact.py (+ tests): consumer-side checksum verifier that REJECTS a tampered artifact (criterion 4, §13 A3/G4). - ci.yml + 3 sync/pin workflows: remaining actions SHA-pinned so a grep for unpinned third-party actions is empty (§14 boy-scout). - SECURITY.md: states what Cortex accesses (transcripts, hooks, fs) and the assurance now offered, with verify commands and honest limits. Co-Authored-By: Claude <noreply@anthropic.com>
…ut-file) The cyclonedx-py `requirements` subcommand rejects `--outfile`; the flag is `-o/--output-file` and the format value is uppercase JSON. Validated locally against Cortex's uv.lock: SBOM generates and the ML-stack grep-assert (torch/transformers/scipy/scikit-learn) passes. Co-Authored-By: Claude <noreply@anthropic.com>
CI showed "CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled": Cortex already runs CodeQL via GitHub's default code-scanning setup (python, javascript-typescript, actions) on a schedule, which satisfies criterion 5. The advanced workflow only conflicted. SECURITY.md updated to reference default setup. Co-Authored-By: Claude <noreply@anthropic.com>
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.
Closes #178. Part of the ecosystem supply-chain sweep tracked by cdeust/enterprise-backlog#27; adapts the automatised-pipeline #77 reference pattern to Cortex's stack (uv/pip, PyPI Trusted Publishing) rather than inventing a new approach. Scorecard is adopted as a
workflow_callcall site into AP's single definition, not copied.Findings first (measured on branch, 2026-07-25)
grep -rlE "cosign|sigstore|sbom|slsa|scorecard|attest-build-provenance" .github/workflows→ no matches before this PR. Confirmed the issue's measured state.ci.yml'sdocker-smokejob builds the image withload: trueand never pushes it to a registry — it is a bare-container contract smoke test. There is therefore no published image artifact to attest; attesting a throwaway smoke build would be theater (§8). Stated inSECURITY.mdrather than fabricating a registry push.pip(verifies against PyPI's recorded hashes); the model download goes through HuggingFace Hub (its own integrity check); the supported marketplace path consumes the git tree directly (ADR-0050). The one download with no built-in check is a raw GitHub-release asset — so that is the one the newscripts/verify_release_artifact.pycovers. Criterion 4 is implemented where the gap actually is, not everywhere for symmetry.pypa/gh-action-pypi-publish,softprops/action-gh-release,docker/build-push-action,docker/setup-buildx-action),ci.ymland the three sync/pin workflows floatedactions/checkout|setup-python|cache|upload-artifact. Pinned all of them sogrepfor unpinned third-party actions is empty (§14 boy-scout, matching AP chore(deps): bump joserfc from 1.6.4 to 1.6.8 in the uv group across 1 directory #77's "zero unpinned remain").What changed
release.yml<asset>.sha256per GitHub-release asset. CycloneDX SBOM fromuv.lock(fails if torch/transformers/scipy/scikit-learn are absent). PyPI keeps PEP 740 attestations (native to Trusted Publishing). Least-privilege per-jobpermissions, widened only for OIDC. All actions SHA-pinned.scorecard.yml(new)uses: cdeust/automatised-pipeline/.github/workflows/scorecard.yml@main— call site, report-only, weekly.codeql.yml(new)security-and-quality, weekly cron + PR.scripts/verify_release_artifact.py(new)ArtifactIntegrityErroron mismatch; CLI exit codes 0/1/2.tests_py/scripts/test_verify_release_artifact.py(new)ci.yml,marketplace-pins.yml,publish-ccplugins.yml,sync-ccplugins-fork.ymlSECURITY.mdVerified pre-merge
pyright ratchet delta = 0, by construction:
pyrightconfig.jsonexcludesscripts/andtests_py/, and nomcp_server/file was touched. The two new Python files cannot move the per-rule ratchet.Release-verified-later (named steps)
Attestation, SBOM upload, and PyPI PEP 740 attestations are
tags: v*-triggered and cannot run on a PR. On the next tag, verification is:gh attestation verify hypermnesia_mcp-<v>-py3-none-any.whl --repo cdeust/Cortex→ binds to this repo + workflow.hypermnesia-mcp.cdx.json+.sha256and the SBOM contains the ML stack (the workflowgrep-asserts this and fails otherwise).python scripts/verify_release_artifact.py <asset> --checksum-file <asset>.sha256on a downloaded asset → exit 0; tamper → exit 1.Completion Ledger (§13.2)
attest-build-provenanceon wheel + sdist + SBOM. Plugin bundle = git tree (marketplace, ADR-0050): provenance is the tagged commit's attestation. Container image = smoke-only, never pushed → no artifact to attest (stated in SECURITY.md).id-token: write. No long-lived token.uv.lock; job fails unless torch/transformers/scipy/scikit-learn appear..sha256per asset;verify_release_artifact.py+ 9 tests; tamper/bit-flip/stale-checksum rejection asserted.codeql.yml, Python security-and-quality, weekly + PR.scorecard.ymlcall site, report-only, weekly.Do not merge — sweep is sequential; see enterprise-backlog#27.
🤖 Generated with Claude Code