This repository is an isolated GitHub Actions policy lab for testing active enforcement of full-SHA action pinning when workflows call local composite actions.
The test cases are intentionally small and dispatch-only. Run each workflow manually from the same branch after the target Actions policy is enabled, then record whether GitHub permits the workflow to run and where any enforcement error is reported.
GitHub's documentation states that when it comes to Actions policies enforced by an enterprise (GHEC):
Policies never restrict access to local actions on the runner filesystem (where the uses: path start with ./).
This leaves it slightly ambiguous to what extent Actions policies apply to local actions. (A similar statement regarding repositories under Free, Pro, or Team plans could not be found in the documentation.)
In particular:
If repository settings require the use of full SHA-pinned actions, does this requirement cascade to local actions not defined in the workflow file itself?
The pinned controls use these latest release tag targets, resolved when the test cases were created:
actions/checkout@v6.0.3:df4cb1c069e1874edd31b4311f1884172cec0e10actions/github-script@v9.0.0:3a2844b7e9c422d3c10d287c895573f7108da1b3
The unpinned controls deliberately use actions/github-script@v9.0.0 by tag.
Workflow: .github/workflows/direct-local-only.yml
The workflow checks out the repository with a pinned actions/checkout ref and then calls a local composite action at ./.github/actions/local-shell. The local action only runs a shell command and does not call any remote action.
This probes whether an active full-SHA policy restricts a direct local action reference where the uses: path starts with ./. Based on the documentation, we would not expect any restrictions on this case.
Workflow: .github/workflows/direct-remote-unpinned-control.yml
The workflow checks out the repository with a pinned actions/checkout ref and then calls actions/github-script@v9.0.0 directly by tag.
This probes active enforcement for a direct remote action reference that is not pinned to a full commit SHA.
Workflow: .github/workflows/local-wrapper-remote-unpinned.yml
The workflow checks out the repository with a pinned actions/checkout ref and then calls a local composite action at ./.github/actions/wrapper-remote-unpinned. The local composite action calls actions/github-script@v9.0.0 by tag.
This probes whether active full-SHA policy enforcement applies to a remote action reference nested inside a local composite action.
Workflow: .github/workflows/direct-remote-sha-control.yml
The workflow checks out the repository with a pinned actions/checkout ref and then calls actions/github-script directly by full commit SHA.
This probes the baseline behavior for a direct remote action reference that is pinned to a full commit SHA.
Workflow: .github/workflows/local-wrapper-remote-sha.yml
The workflow checks out the repository with a pinned actions/checkout ref and then calls a local composite action at ./.github/actions/wrapper-remote-sha. The local composite action calls actions/github-script by full commit SHA.
This probes the baseline behavior for the proposed generated-template wrapper shape when the wrapper's nested remote action reference is pinned to a full commit SHA.
The repository was tested with the following repository-level settings:
- Allow reponomics, and select non-reponomics, actions and reusable workflows
- Allow actions created by GitHub
- Require actions to be pinned to a full-length commit SHA
| case | outcome | status | interpretation |
|---|---|---|---|
00-baseline |
PASS | Success | The repository policy did not restrict the local action reference itself when the workflow used uses: ./.github/actions/local-shell. |
01-control |
FAIL | Startup failure | A direct remote action reference by tag was rejected before normal job execution, confirming active full-SHA enforcement for ordinary remote action references. |
01-test |
FAIL | Failure | The local composite action was allowed to run, but its nested remote action reference by tag was still subject to policy enforcement. |
02-control |
PASS | Success | A direct remote action reference pinned to a full commit SHA was accepted. |
02-test |
PASS | Success | A local composite wrapper that invokes a remote action pinned to a full commit SHA was accepted. |
Overall, the tested policy does not restrict access to local actions on the runner filesystem, but remote actions invoked from inside those local composite actions are still evaluated against the active GitHub Actions policy. In practical terms, uses: ./... is permitted as a local action reference, but any nested steps[*].uses entry that points at a remote action must independently satisfy the repository, organization, or enterprise policy. This is probably the expected outcome, given a natural reading of the documentation.