Secure your workflows with StepSecurity Harden Runner

Secure your workflows with StepSecurity Harden Runner


6 min read

In my previous article, Secure your .NET builds with StepSecurity and GitHub Actions, I discussed software supply chain attacks and showed how to use StepSecurity Secure Workflows to improve the security of your GitHub Actions software supply chain. In this article I show how to use the Harden Runner security agent to audit and block outbound connections to further improve workflow security.

A Quick Recap

Software supply chain attacks are an increasing threat that targets source code, build processes or update mechanisms to infect legitimate apps and distribute malware. Incidents like the SolarWinds attack have breached all types of organisation ranging from startups to Fortune 500 companies and government agencies.

Software Supply Chain Attacks

StepSecurity helps secure your software release and distribution supply chain. Secure Workflows provides remediation of vulnerabilities in GitHub Actions workflows and the Harden Runner security agent prevents exfiltration of credentials and helps detect compromised dependencies, tools or source code.

What is Harden Runner?

As seen in recent supply chain attacks, including the Codecov breach and malicious npm cryptomining packages, compromised dependencies and build tools typically make outbound calls. Restricting outbound traffic to only the endpoints needed for the workflow thwarts many software supply chain attack vectors.

When added to a job in a GitHub Actions workflow, the Harden Runner security agent can audit and block outbound traffic from the runner executing that job. There are some limitations:

  • Harden Runner only works for GitHub hosted runners, self-hosted runners are not supported.
  • Only Ubuntu runners are supported, Windows and macOS runners are being discussed.
  • Harden Runner does not support running an entire job in a container, which is unusual for GitHub Actions.

Harden Runner supports both public and private repositories. If you use Harden Runner with a private repository the generated audit report is not public, authentication is required and only those who have access to the repository can view the report.

How do I set up Harden Runner?

The easiest way to add Harden Runner to a workflow is to use the Secure Workflows app. This can set the minimum GITHUB_TOKEN permissions for the workflow, pin the Actions used by a full length commit SHA and add the Harden Runner Action to the start of each job in audit mode. Future runs of the workflow will include a link to an audit report that lists all the outbound calls made in the workflow log.

StepSecurity Harden Runner Action Log

For private repositories you also need to install the Harden Runner app on GitHub which requires actions: read permissions to your repositories. I've also installed the app for my public repositories because otherwise you have to wait 30 seconds for the results and I'm impatient.๐Ÿ˜„

How do I configure block mode?

With Harden Runner added to your workflows you continue to develop your project while it audits outbound connections. Once you have completed several runs of a workflow you can check the audit reports and build a list of allowed connections. Simple workflows like project management tasks may always make the same connections but more complicated workflows may include optional calls so it is worth checking several runs rather than relying on the results of just one audit.

The audit report lists every step in a job. If a step makes any outbound connections the domain is listed along with the name of the process that made the connection. If a workflow includes multiple jobs then each job has its own tab in the report.

StepSecurity Harden Runner Audit Report

The audit report also provides the YAML needed to configure Harden Runner to block any outbound connections from the job other than those listed in the report.

StepSecurity Harden Runner Audit Policy YAML

Once you configure Harden Runner in block mode, it will restrict outbound traffic from the workflow to only the domains listed.

What happens when a call is blocked?

Calls to any domain not allowed by Harden Runner will fail DNS resolution and cause the step that made them, and the job, to fail. So let's test that out...

I added the following step to the same CI build workflow used for the audit screenshots above:

    - name: Test Harden Runner
      run: curl -X GET

This uses curl to access a URL that is not in the list of allowed endpoints provided to Harden Runner. Immediately we can see in the pull request that there is a problem:

StepSecurity Harden Runner Blocked PR

Clicking through to the workflow summary we can see that an attempt was made to access a restricted endpoint and was blocked at the DNS level:

StepSecurity Harden Runner Blocked Action Summary

The workflow logs show it was our test step that tried to access the restricted domain:

StepSecurity Harden Runner Blocked Action Log

And, we can also see the details of the step, process and blocked endpoint in the Harden Runner report:

StepSecurity Harden Runner Blocked Report

Tips for .NET Developers

Since Harden Runner only works on an Ubuntu runner you can't use it for jobs that require a Windows or macOS runner such as building .NET Framework, Xamarin or .NET MAUI apps but it does work for building .NET Core, .NET 5 and .NET 6 apps that will build on Linux.

Disable .NET Telemetry

The .NET CLI includes telemetry that sends data back to Microsoft. When running the CLI in a build environment you should disable the telemetry because otherwise commands like dotnet build and dotnet restore will make additional calls. To disable the telemetry add the following environment variables to your workflow:

  DOTNET_NOLOGO: true                     # Disable the .NET logo in the console output
  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true # Disable the .NET first time experience
  DOTNET_CLI_TELEMETRY_OPTOUT: true       # Disable sending .NET CLI telemetry to Microsoft

This should also reduce the workflow duration slightly, which is a nice bonus.

Setup .NET

In my projects the action to set up .NET (actions/setup-dotnet) is inconsistent - sometimes it makes two outbound calls and other times it makes three. This is a good example of why you need to audit multiple runs of a workflow before enabling block mode because the list of allowed connections needs to include all possible calls. From my experience the set up .NET action needs these connections:

Final Thoughts

Harden Runner requires some time to fully configure but once blocking is enabled it thwarts many common attack vectors. Between Secure Workflows and Harden Runner, StepSecurity have added two powerful tools to the DevSecOps toolkit for developers using GitHub Actions. Whether you're working on open or closed source projects I reccommend you check them out and improve the security of your software supply chain.



Cover image contains a vector created by upklyak from

Software Supply Chain Attacks chart is from Sonatype's 2021 State of the Software Supply Chain report.

Did you find this article valuable?

Support Dave Murray by becoming a sponsor. Any amount is appreciated!