Table of Contents

GitHub Actions is a powerful tool to automate your CI/CD pipelines like creating builds, code quality checks, or deployments. However, it might contain sensitive data like API keys or cloud admin credentials, making them vulnerable to CI/CD malware injection threats.  

Thus, it’s crucial to implement security best practices like pinning GitHub Actions using version tags or commit SHAs in your workflows to avoid code compromises.  

Before we move ahead, check out our previous blogs in GitHub Actions security series:

Now let’s explore all things GitHub Actions pinning in this blog.  

What is GitHub Actions Pinning?

Action pinning in GitHub Actions is the practice of pointing to a specific version of an action used in a workflow, allowing the execution of the same code every time the GitHub Actions workflow is pulled, irrespective of any updates made to the action itself.

Pinning to a Full-Length Commit SHA

With this method, you can point to the specific commit SHA for the desired version of the action. This guarantees that the exact code you've pinned is used, even if the version tag or the action's code is modified later. Commit SHA offers the highest level of security as it tags to a specific point in time within the action's codebase using a unique identifier (the commit SHA).  For example, it could look like "actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332".

Try StepSecurity for Free

Why Pin GitHub Actions?

Supply chain attacks commonly target dependencies within projects. Malicious actors might attack a seemingly trusted action repository and inject malicious code. Pinning actions ensures you're using a specific version of the code that you've previously audited and trusted. Even if the GitHub action gets somehow compromised later, the attacker won’t be able to tamper with the code that you've already pinned.

Action pinning with specific commit hash SHAs leverages the concept of immutability. Once a commit SHA is pinned, it guarantees that the specific code version cannot be altered. This offers significant security benefits compared to relying on version tags, which can be changed to point to different code versions.

Example of Vulnerable Workflow and Attack Scenario

To further understand why pinning actions is crucial for securing workflows, let’s explore a vulnerable workflow with unpinned actions and how it behaves in an attack scenario:

Workflow file (vulnerable.yml):

name: Build and Deploy
on: push
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3 # Unpinned action
- uses: someuser/build-action@main # Unpinned action (main branch)
- uses: anotheruser/deploy-action@v1.2.3 # Unpinned to a version tag
# Build and deploy application logic here

Attack Scenario in the Absence of a Pinned GitHub Actions
We have a workflow that is not pinned to a specific commit SHA (having unintended information). An attacker gains access to the user/build-action repository and injects malicious code into the build-action that steals confidential information from the codebase during the build process. The attacker then updates all existing version tags to point to the Action code with their malicious code.

During workflow execution, the injected malicious code within the build-action can steal sensitive secrets (like API keys or access tokens). The author re-tags the action as “anotheruser/deploy-action@v1.2.3,” causing everyone to use “user/deploy-action@v1.2.3” to run the malicious code. This helps the attacker to gain access and steal secrets to further compromise other systems or accounts.

However, if the vulnerable.yml workflow had pinned the someuser/build-action to a secure commit SHA beforehand (i.e. anotheruser/deploy-action@<commit-SHA>), the workflow would have been immune to this attack. The workflow would further continue to use the trusted, pre-compromised version, preventing malicious code injection and protecting secrets.

How to Pin GitHub Actions

Now that we know why pinning is crucial for GitHub Action workflows, let’s learn how to pin GitHub Actions. Here's a step-by-step guide on how you can pin GitHub Actions to specific commit SHAs:

1. Finding the Commit SHA

  • Identify the release version you want to pin to and find the corresponding commit. To do this, click on the Releases link in the repository and find the commit corresponding to the git tag.
  • Navigate to the action repository you want to pin. You can find this on the GitHub Marketplace or using the action name. For example, the repository for the action actions/checkout is https://github.com/actions/checkout
Image for Choosing the Release Version
                                                        Choosing the Release Version 
Image for Finding the Specific Commit in GitHub Actions
                                                       Finding the Specific Commit in GitHub Actions
Image for Opening the Specific Commit in GitHub Actions
                                                          Opening the Specific Commit in GitHub Actions
  • Copy the SHA of the commit you want to pin to. The specific commit hash SHA is a long alphanumeric string next to each commit. This will display the details of that specific code version.

2. Updating Your Workflow to Use the Commit SHA

  • Open your workflow YAML file within your GitHub repos.
  • Locate the "uses" statement for the action you want to pin. It typically follows this format:
uses: <owner>/<repo>@<version>

  • Replace the <version> part with the commit SHA you obtained in step 1. The final line should look similar to this:
uses: <owner>/<repo>@<commit-SHA>

Example with Code Snippets

Scenario: You want to pin the actions/checkout@v3 action to the commit SHA example “378343a27a77b2cfc354f4e84b1b4b29b34f08c2”.

Original Workflow (Unpinned GitHub Action):

name: My Workflow
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# ... other steps in your workflow

Updated Workflow (Pinned GitHub Action):

name: My Workflow
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@378343a27a77b2cfc354f4e84b1b4b29b34f08c2 # Pinned to specific commit SHA
# ... other steps in your workflow

Best Practices for Pinning GitHub Actions

Now that you know how to manually pin GitHub Actions, let’s explore best practices to follow while pinning to ensure maximum effectiveness:

1. Prioritize High-Risk Actions with commit SHAs

  • Start with identifying actions (falling under "high-risk" actions) that handle sensitive data or have access to vital resources within your workflows. To perform risk analysis on a GitHub actions security, consider using StepSecurity’s GitHub Action Advisor hosted here: https://app.stepsecurity.io/action-advisor
  • Maximum control and immutability can be assured by always pinning high-risk third-party actions (developed by external maintainers) to specific commit hash SHAs.  
  • Also, if you manage multiple GitHub Action workflows across multiple repositories, use reusable workflows to centrally manage pinned action SHAs. This promotes consistency and simplifies updates.

2. Enable Dependabot/ Renovatebot updates for pinned Actions

i. Pinning with Dependabot

  • Create dependabot.yml file.  
  • Place this file in the .github directory of your repository.
  • Configure Dependabot: Add the following configuration to the dependabot.yml file:
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily" #Change the schedule as per requirements

ii. Pinning with Renovatebot:

  • Create renovate.json file.
  • Place this file in the root of your repository.
  • Configure Renovatebot: Add the following configuration to the renovate.json file as the frequency schedule:
{
"extends": [
"config:base"
],
"packageRules": [
{
"managers": ["github-actions"],
"schedule": ["daily"] #Change the schedule as per requirements
}
]
}

iii. Automated Updates using Comments (Best Practice):

When using these configurations, you might also want to include comments in your GitHub Actions workflows folder to clarify that dependencies are tracked by commit SHAs.

name: Node.js Package
on:
release:
types: [created]
jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3

3. Use Version Tags for Trustworthy Organizations

  • For actions maintained by well-known organizations with a strong security track record in the GitHub community, you may consider using version tags for pinning. With this practice, you can take advantage of minor bug fixes and enhancements in updated tagged versions.  
  • A balance between security and flexibility is the key to a streamlined CI/CD. That’s why, prioritize pinning high-risk actions and choosing trusted sources only for version tags.
  • Regularly keep an eye on these trusted actions for any reported vulnerabilities and update the pinned version tag accordingly.

4. Regular Review and Updates

Update pinned commit SHAs whenever possible to ensure you're using secure and up-to-date code. Consider using automation tools for efficiency in this process for large workflows.

Challenges and Solutions with Pinning GitHub Action

While action pinning offers significant security benefits, it does not come without its challenges. Here's a glance at common issues and potential solutions:

Common Challenges in Pinning Actions

  • Manual Updates: Keeping track of numerous pinned commit SHAs and updating them manually can be time-consuming and error-prone, especially for complex workflows with many actions.
  • Challenges in maintaining pinned actions in allowlist: If you use GitHub actions Allowlist feature to only allow specific actions versions in your organization. You would have to update the allowlist every time you update the pinned hash for an allowed action.  

Solutions and Automation Tools

Fortunately, there are some solutions and tools to tackle these challenges:

  • Automated Updates: Tools like Dependabot and Renovate can integrate with GitHub repos and automate the process of identifying secure updates for pinned actions in your dependencies. These tools suggest updates based on security vulnerabilities or new tagged versions released by trusted maintainers.
  • Reusable Workflows: Utilize reusable workflows to manage pinned actions centrally across multiple repositories. This streamlines updates and ensures consistency.
  • Security Review: Leverage StepSecurity Action Advisor to reduce time to review each action.  

Automating GitHub Actions Pinning with StepSecurity

Keeping your GitHub Actions workflows secure can be a time-consuming task, especially with the need to manually review and pin actions. StepSecurity simplifies this process by automating various security best practices, including setting minimum token permissions, integrating Dependabot, action pinning, and more, through its integration with your GitHub repository.  

StepSecurity automates action pinning by scanning workflows and generating pull requests that suggest any sort of security compliances, including pinning actions to secure commit SHAs, hence eliminating manual configuration.

Benefits of Automating Action Pinning with StepSecurity

  • Save Time and Effort: StepSecurity analyzes your workflows and automatically generates pull requests suggesting security improvements. This eliminates the need for manual review and configuration of action pinning.
  • Reduced Risk: StepSecurity ensures your workflows adhere to security best practices, minimizing the chance of vulnerabilities and attacks.
  • Improved Consistency: Automated pinning ensures all workflows use secure, pinned actions, leading to consistent and reliable workflow execution.

Community Tier

For our community tier users, StepSecurity offers a feature called Secure Workflow, which helps you automatically apply industry best practices to your GitHub Actions workflow files, including pinning actions to full commit SHAs.
To use this feature follow this steps:

Step 1: Visit  StepSecurity Secure Workflow

Step 2: Copy your GitHub Actions workflow file and paste it into the editor on the StepSecurity tool interface.

                                                              StepSecurity Secure Workflow Page with Original Workflow

Step 3: Click the “Secure Workflow” button and the tool will automatically enhance the security of your workflow by applying recommended settings:

  • Restrict permissions for [[GITHUB_TOKEN]].
  • Add Harden-Runner for the GitHub-hosted runner.
  • Pin actions to full-length commit SHAs.

Step 4: Review and apply the suggested changes using the tool’s diff view, which highlights improvements between your original and secured workflow.

                                                        StepSecurity Workflow with Updated Workflow

Key enhancements include:

  • Adjusted permissions to follow the principle of least privilege.
  • Integration of the StepSecurity Harden Runner with an audit egress policy.
  • Pinning all GitHub Actions to specific commit SHAs for better security
StepSecurity also offers another feature known as Secure Repo that helps you automatically secure all the workflows in your repositories

Enterprise Tier

For Enterprise Tier users, in addition to Secure Workflow and Secure Repo—which automatically secure your workflows and repositories—they also have access to the Overview Dashboard. This dashboard provides a list of security controls.

One of those controls is "Actions should be pinned to a full-length commit SHA".

                                                              StepSecurity Overview Dashboard

If this control fails, it means that some GitHub Actions in your repositories are not pinned to specific commit SHAs, which poses a security risk. Clicking on the control will show you which repository contains the vulnerable workflow, along with an automatic remediation option.

Click the “Fix PR” button, and Secure Repo will open a pull request to apply the necessary fixes, pinning all actions securely.

                                                                     StepSecurity Control Dashboard

Conclusion

Pinning GitHub Actions is a crucial step in securing your CI/CD workflows. It helps prevent supply chain attacks, ensures consistency, and reinforces the overall security of your automation pipeline.

Instead of doing this manually, let StepSecurity handle it for you.

🔐 Secure your GitHub Actions in minutes — try StepSecurity for free today and harden your workflows with just a few clicks.

Try StepSecurity for Free

Frequently Asked Questions

1. What are the differences between pinning to a tag vs. a commit SHA?

Pinning to a tag, such as v1.0, refers to a named version of the action that can be updated by the author. This means the underlying code can be updated to introduce new features or fixes. The possibility of code update in the pinned version to a tag leaves a gap for possible vulnerabilities or virus injections. However, pinning to a specific commit SHA enables your workflow to use an exact, immutable version of the action's code. A commit SHA uniquely identifies a specific state of the repository, catering to higher security and consistency as the code version cannot be altered once pinned.

2. How often should you update pinned actions?

Updating pinned actions should be done periodically to benefit from new features, bug fixes, and security patches. However, the frequency also depends on the type of criticality of the action and your project's security dependencies. Regular reviews are good GitHub Actions security practice. Not to mention, we recommend testing updated actions prior to deployment to production to ensure compatibility and stability.  

3. Are there any tools to help manage pinned actions?

Yes, tools like StepSecurity can automate the management of pinned actions. StepSecurity scans your workflows, identifies unpinned actions, and generates pull requests with recommendations to pin actions to secure commit SHAs. This reduces manual effort and helps maintain a secure and consistent workflow environment.

4. Other than Action pinning, are there any other GitHub Actions security best practices I should implement to enhance the security of my GitHub Actions workflow?

Yes, other than pinning GitHub Actions, you must set minimum token permissions, integrate Dependabot, integrate Harden-Runner for runtime security and much more. For a comprehensive guide on GitHub Actions security best practices, check out our blog: 7 GitHub Actions Security Best Practices (With Checklist)

Blog

Explore Related Posts