GitHub is, without a doubt, the most popular version control platform on the planet. Millions of developers, companies, and institutions use it daily to collaborate and store their code.
But GitHub is not just “a place to store code.” It also offers GitHub Actions (GHA), a powerful tool that lets you build workflows simply by writing YAML files.
Thanks to this, you can automatically run tests, compile projects, or even deploy applications whenever something happens in your repo, like a push or a pull request.
These workflows run in environments called runners (Linux, Windows, or macOS) and rely on predefined actions or custom ones you create yourself.
Example
Let’s imagine we have a simple Python script called hello.py
that just prints Hello!
If we want to run it using a GHA, we’d have a workflow like this:
name: Run Hello Script
on:
workflow_dispatch:
jobs:
run-hello:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@latest
- name: Set up Python
uses: actions/setup-python@latest
with:
python-version: '3.x'
- name: Run hello.py
run: python hello.py
This workflow uses only workflow_dispatch
, so our hello.py
script will only run when we manually trigger the workflow through GitHub.
If you look closely, we’re using the checkout
and setup-python
actions with the latest
tag. This tells the workflow to always use the most recent version of those actions.
Using latest
ensures you’re always working with the newest version but it also brings two major risks related to stability and security.
⚙️ Stability
A new version might introduce breaking changes that make your workflow fail overnight.
🔒 Security
If an action gets compromised and malicious code is added to some versions, your workflow would execute it without any visible warning.
✅ The Solution
The good news is these issues are easy to fix: just pin your actions to a specific version that you’ve already tested and validated with your code.
Pinning Actions
There are three main ways to pin an action to a specific version:
Use a general version tag
uses: actions/checkout@v3
Use a more precise version tag
uses: actions/checkout@v3.5.2
Use a commit SHA
uses: actions/checkout@9e4...f2c3
The most secure and stable option is the third one, since a SHA always points to a specific, immutable commit in the repository.
It’s good practice to combine the SHA with a comment indicating which version the SHA corresponds to:
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
That way, you and your team know which version that SHA refers to, while keeping your workflow safe from unexpected changes.
How to Find the Commit SHA
Using checkout v3.6.0 as an example:
- Go to the official repo and open the Releases section.
- Find version 3.6.0 and click on the commit link.
- The commit hash will appear clearly in the URL.
Making sure your actions are pinned to a specific version is easy as long as you only have a few.
For organizations with thousands of repositories and hundreds of actions, it’s a bit more complex.
Mainly because, until recently, there was no way to enforce SHA pinning across all repositories in an organization.
In other words, each team decided whether to do it or not, and there were no native mechanisms to block the use of latest or tags like v2.
Well… that was until now.
🧩 SHA Pinning Policy in GitHub
A couple of weeks ago, GitHub released an update that lets organizations apply two key new policies:
- Block specific actions
- Enforce pinning actions to a commit SHA
🔐 SHA Pinning
Thanks to the new update, organizations can now enable a policy that disables any actions not pinned to a commit SHA.
This policy can be set at both the organization level (affecting all repos) or at the individual repository level.
Once enabled, any action not properly pinned to a SHA will automatically throw an error.
🚫 Blocking Specific Actions or Versions
The update also adds the ability to block specific actions and/or versions by adding a special ! prefix to the action identifier and version you want to block.
This prevents any repository within the organization from running that action—even if it’s pinned to a SHA.
This feature is especially useful when a vulnerability is found in a specific version of an action and you want to make sure none of your repositories can use it.
🧭 In Summary
GitHub Actions is an incredibly powerful tool, but like any tool, its security depends on how you use it.
Pinning your actions to specific versions and applying centralized control policies are key steps to keeping your workflows stable, secure, and predictable.
💬 Are you already applying these practices in your repos?
If not, now’s a great time to start.
Top comments (0)