Skip to content

[BUG][P1][SECURITY] Pin GitHub Actions dependencies to immutable commit SHAs #352

Description

@Joncallim

Parent hardening: #348
Related programme: #333
Execution mode: implementation
Depends on: #348
Blocks: #357

Bug Summary

Forge uses mutable GitHub Action release tags in workflows that provide repository, security and merge-gate evidence, even though the trusted MCP host-boundary workflow already uses exact commit-SHA pins.

Current Behaviour

Examples include actions/checkout@v7.0.0, actions/setup-node@v6.4.0 and actions/upload-artifact@v7.0.1 in normal CI/agent/issue workflows. By contrast, mcp-host-boundary-trusted.yml pins checkout to an immutable commit SHA with a readable version comment.

Once #348 makes Web CI/PR Contract required merge gates, mutable Action refs are part of the repository trust root.

Expected Behaviour

External Actions used by required, privileged, repository-write, issue-command, release or security workflows are pinned to exact immutable commit SHAs with readable version comments and a reviewed update path. Prefer applying the rule repository-wide for consistency.

Reproduction Steps

  1. Search .github/workflows/*.yml for external uses: references.
  2. Observe required/agent/issue workflows using @v* mutable tags.
  3. Compare with the already SHA-pinned trusted host-boundary workflow.

Impact

A required check is only as trustworthy as the code it executes. Mutable refs allow upstream action identity to change without a Forge repository commit, weakening reproducibility and the supply-chain boundary #348 establishes.

Severity

High - supply-chain weakness in required/privileged repository workflows.

Implementation Sequence

  1. Consume [BUG][P0][SECURITY] Enforce Forge release gates with GitHub main-branch protection/ruleset #348 policy inventory — enumerate exact workflows/checks now inside the trusted repository boundary plus other privileged/repository-write workflows worth pinning consistently.
  2. Inventory every external uses: — action owner/repo, current release tag, immutable SHA, permissions/event context and artifact/network behavior.
  3. Resolve trusted immutable SHAs — use official upstream release/tag/commit metadata; preserve readable # vX.Y.Z comments. Do not guess SHA values.
  4. Pin required/privileged workflows first — Web CI, PR Contract, agent command/dispatch/handoff, issue intake and artifact actions; extend repository-wide unless a documented exception exists.
  5. Least-privilege pass — while touching each workflow, re-evaluate permissions:, checkout credential persistence, fork/untrusted-event execution and writable token exposure; do not broaden permissions.
  6. Policy test — parse .github/workflows/*.yml and fail if an external action ref is not a full immutable commit SHA unless present in a tiny explicit reviewed allowlist.
  7. Update path — configure/review Dependabot github-actions or document equivalent reviewed pin-update procedure; updates must show old/new SHA + version.
  8. Full workflow regression — PR Contract/Web CI/issue/agent fixture behavior remains functional; give [OTHER][RELEASE] Complete S6 external-controller trust binding and live release evidence #357 exact dependency/action identity evidence for its external controller manifest.

Primary Code / Control Seams To Inspect First

  • .github/workflows/*.yml
  • .github/dependabot.yml or equivalent update configuration if present
  • workflow-policy tests under web/__tests__ / scripts
  • PR Contract / GitHub agent workflow code executed by the workflows
  • trusted host-boundary workflow as the immutable-pin reference pattern

Orthogonal Checkpoints

  1. Supply-chain identity: SHA truly corresponds to intended upstream release; no short/moving refs.
  2. Permissions: contents/issues/PR/actions permissions, checkout credentials, artifact token exposure.
  3. Untrusted events: pull requests/forks/issue comments cannot run attacker-controlled code with writable token/secrets.
  4. Artifact/data handling: upload/download actions, output quarantine boundaries and accidental sensitive artifact expansion.
  5. Maintenance: Dependabot/update process cannot silently change major behavior or widen permissions.
  6. Policy-test robustness: local/reusable workflows vs external actions, comments/YAML anchors, malicious near-match syntax.
  7. Required-check regression: [BUG][P0][SECURITY] Enforce Forge release gates with GitHub main-branch protection/ruleset #348's exact required checks still run/report expected identities after pinning.
  8. S6 handoff: [OTHER][RELEASE] Complete S6 external-controller trust binding and live release evidence #357 can digest/prefetch exact external Action identities without discovering an unpinned dependency.

Acceptance Criteria

  • [BUG][P0][SECURITY] Enforce Forge release gates with GitHub main-branch protection/ruleset #348 is closed and its exact required-check/ruleset policy is known before this issue starts.
  • No required/security/release/privileged workflow uses mutable external Action refs (@v*, @main, @master, etc.).
  • Web CI and PR Contract Check use immutable Action SHAs.
  • Agent command/dispatch/handoff and issue-intake external Actions are SHA-pinned.
  • Artifact upload/download actions are pinned.
  • Every pin has a readable release/version comment or equivalent dependency metadata.
  • GitHub Actions dependencies have a reviewed automated/documented update path.
  • Workflow permissions/event/checkout-credential behavior is reviewed for least privilege and no privilege expansion is introduced.
  • A repository policy test rejects new mutable external Action refs unless explicitly allowlisted/reviewed.
  • Normal Web CI, PR Contract and representative issue/agent workflows remain functional after pinning.
  • [OTHER][RELEASE] Complete S6 external-controller trust binding and live release evidence #357 receives exact immutable Action/dependency identities suitable for its external-controller release manifest.

Out of Scope

Implementation Scope

Medium - workflow supply-chain/permission hardening plus one policy guard; target 2-3 small PRs or one tightly reviewed workflow PR if change volume remains mechanical.

Environment

  • Repository: Joncallim/Forge.
  • Baseline: current main after ADR 0014.
  • Reference pattern: exact checkout SHA already used by mcp-host-boundary-trusted.yml.

Technical Notes

This issue owns external Action identity and workflow-permission hardening only. Do not fold #348 ruleset policy or #357 external controller/host provisioning into the same change.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions