Skip to content

harden(ci): pin action refs to SHA + least-privilege permissions - #63544

Merged
jung-thomas merged 2 commits into
mainfrom
harden/workflow-action-pinning
Oct 29, 2026
Merged

jung-thomas merged 2 commits into
mainfrom
harden/workflow-action-pinning

Conversation

@jung-thomas

Copy link
Copy Markdown
Contributor

Summary

Hardens GitHub Actions workflows against the mutable-action-ref → CI code execution class flagged by a security report (four independent scanners converged on label-issues.yml). Fixes two files.

Findings & fixes

1. label-issues.yml (the reported finding)

  • Before: uses: sap-tutorials/tutorial-actions@main — a mutable branch ref. Anyone able to push to tutorial-actions@main gets code execution here with GITHUB_TOKEN on the next issues: opened event (triggerable by any user). No permissions: block, so the job ran at the repo default token scope.
  • After: pinned to commit 538065eee0c5ae18cc88e430da2241a0668b9b79 (current main), plus a least-privilege block (contents: read, issues: write).

2. community-requester-id.yaml (found during the sweep — higher risk)

  • Runs under pull_request_target (writable token, runs for fork PRs) and feeds a GitHub App private key (SAP_TUTORIALS_APP_PEM_BASE64) to a third-party, archived action pinned at a mutable tag (machine-learning-apps/actions-app-token@0.21). A re-pointed tag there = full App compromise, not just GITHUB_TOKEN.
  • After: actions-app-token pinned to SHA b5f0e20; actions/checkout pinned to SHA and bumped v2 → v4 (v2 is EOL/Node 12); added permissions: contents: read (all writes go through the App token, so the ambient token needs no write scope).

Audit of the remaining 4 workflows — no action needed

Workflow Status
close_inactive_issues.yml ✅ scoped perms, actions/stale@v9
notify-tutorials-ims.yml ✅ jq-escaped payload, own PAT
tutorial-pr-checks.yml ✅ pinned @v1, scoped perms
tutorial-pr-comment.yml ✅ pinned @v1, scoped perms

Repo default workflow token is already read — this bounds (but does not remove) the label-issues exposure; the SHA pin closes the actual channel.

Residual notes

  • Org-internal actions (tutorial-actions, tutorial-ci) are pinned by SHA/tag but still depend on sap-tutorials push-access controls.
  • Consider Dependabot (package-ecosystem: github-actions) to keep SHA pins current without reintroducing mutable refs.

🤖 Generated with Claude Code

…ions

label-issues.yml used a mutable @main ref and declared no permissions block.
Pin to commit 538065e and scope the token to contents:read + issues:write.
community-requester-id.yaml runs under pull_request_target and handles a
GitHub App private key. Pin machine-learning-apps/actions-app-token@0.21
(archived, mutable tag) to SHA b5f0e20, pin+bump actions/checkout v2 -> v4
(SHA 11d5960), and add a contents:read permissions block.
@sap-tutorials-builder

Copy link
Copy Markdown
Contributor

✅ No issues found

Checked 07d036e • notify-only, does not block merge

@jung-thomas
jung-thomas merged commit f8d1fd2 into main Oct 29, 2026
1 check passed
@jung-thomas
jung-thomas deleted the harden/workflow-action-pinning branch October 29, 2026 16:01
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