Skip to content

fix(security): pin actions to SHAs, add token floor, stop tag interpolation - #152

Merged
imran-siddique merged 1 commit into
mainfrom
sec/supply-chain-hardening
Sep 5, 2026
Merged

fix(security): pin actions to SHAs, add token floor, stop tag interpolation#152
imran-siddique merged 1 commit into
mainfrom
sec/supply-chain-hardening

Conversation

@imran-siddique

Copy link
Copy Markdown
Member

Part of a proactive security sweep across agentrust-io.

Action pinning (19 refs)

Mutable tags on the release path, including docker/login-action@v4 (registry credentials), sigstore/cosign-installer@v3 (signing) and actions/attest-build-provenance@v4 (id-token: write). All now pin a commit SHA with the version in a trailing comment.

Token scope

ci.yml, docker.yml, release-drafter.yml and sbom.yml had no top-level permissions: block, so any job without its own block inherited the repository default. Added contents: read as the floor. docker.yml and sbom.yml already declare job-level packages: write / id-token: write / attestations: write and keep them, so no job loses a capability it was using.

Shell injection

release.yml embedded the tag name inside two python -c single-quoted strings, and in gh release upload; release-drafter.yml did the same in gh release create. Expression substitution happens before bash or python parses the line, so a tag name containing a quote was code rather than a value. All four sites now read the value from the environment.

Defence in depth rather than a live hole: creating a tag already needs write access. It removes the primitive.

Workflow-only. ci.yml in this repo has mixed line endings, so the edits were applied byte-precisely to keep the diff to the 11 lines that actually changed rather than reflowing the file.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t

…lation

Supply chain. 19 action refs ran from mutable tags, including
docker/login-action, cosign-installer, attest-build-provenance and
build-push-action on the release path. All now pin a commit SHA.

Token scope. ci.yml, docker.yml, release-drafter.yml and sbom.yml had no
top-level permissions block, so any job without its own block inherited
the repository default. contents: read is now the floor; the jobs that
declare packages: write or id-token: write keep them.

Shell injection. release.yml embedded github.ref_name inside two
python -c strings and a gh release upload, and release-drafter.yml put it
in gh release create. ${{ }} expands before the shell or python parses
the line, so a crafted tag name was code. All four sites read the value
from the environment instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t
@imran-siddique
imran-siddique requested a review from a team as a code owner September 5, 2026 21:08
@imran-siddique
imran-siddique merged commit a3916f7 into main Sep 5, 2026
16 checks passed
@imran-siddique
imran-siddique deleted the sec/supply-chain-hardening branch September 5, 2026 21:12
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