mirror of
https://github.com/step-security/harden-runner
synced 2026-08-09 13:11:02 +00:00
Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
accfb74a43 | ||
|
|
446798f821 | ||
|
|
156268b1c7 | ||
|
|
f0d3b1eb1b | ||
|
|
b7880a2f96 | ||
|
|
dade49eade | ||
|
|
d6248bed80 | ||
|
|
4330132d7e | ||
|
|
247a5c6fb1 | ||
|
|
782d84337f | ||
|
|
f5f18f8c5e | ||
|
|
951b48540b | ||
|
|
49711f22fe | ||
|
|
5c7944e73c | ||
|
|
c79be451ee | ||
|
|
deb3383c4d | ||
|
|
23c8215e78 | ||
|
|
727d06a16d | ||
|
|
f0db2aa8a5 | ||
|
|
1938ffc008 | ||
|
|
8e7dd2c82b | ||
|
|
f2823ee7dd | ||
|
|
5f95e051ab | ||
|
|
0fe20c9a7d | ||
|
|
89c04c1cae | ||
|
|
d7cf128fba | ||
|
|
657cae2a4a | ||
|
|
0d381219dd | ||
|
|
29e9ae1229 | ||
|
|
9d596cfe4e | ||
|
|
6d3c2fe731 | ||
|
|
c2e63d350e | ||
|
|
547a5cc003 | ||
|
|
a5e1dca4fb | ||
|
|
3d32f8d8b2 | ||
|
|
891104cb4f | ||
|
|
17d0e2bd7d | ||
|
|
bb112d061b | ||
|
|
f4f3f445f3 | ||
|
|
7a946b57df | ||
|
|
75a01c2f00 | ||
|
|
53413f1a91 |
@@ -22,7 +22,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v1
|
||||
- uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v1
|
||||
with:
|
||||
egress-policy: audit
|
||||
allowed-endpoints:
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
pull-requests: read
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
|
||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4
|
||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde
|
||||
with:
|
||||
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@cdcdbb579706841c47f7063dda365e292e5cad7a
|
||||
uses: github/codeql-action/init@2d790406f505036ef40ecba973cc774a50395aac
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@cdcdbb579706841c47f7063dda365e292e5cad7a
|
||||
uses: github/codeql-action/autobuild@2d790406f505036ef40ecba973cc774a50395aac
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -75,4 +75,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@cdcdbb579706841c47f7063dda365e292e5cad7a
|
||||
uses: github/codeql-action/analyze@2d790406f505036ef40ecba973cc774a50395aac
|
||||
|
||||
@@ -17,11 +17,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
|
||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@7bbfa034e752445ea40215fff1c3bf9597993d3f # v3.1.3
|
||||
uses: actions/dependency-review-action@0c155c5e8556a497adf53f2c18edabf945ed8e70 # v4.3.2
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4
|
||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde
|
||||
with:
|
||||
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4
|
||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde
|
||||
with:
|
||||
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4
|
||||
- uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde
|
||||
with:
|
||||
egress-policy: audit
|
||||
allowed-endpoints:
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
|
||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # tag=v1.1.1
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # tag=v1.1.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3.0.0
|
||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # tag=v3.0.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -62,6 +62,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # tag=v1.0.26
|
||||
uses: github/codeql-action/upload-sarif@2d790406f505036ef40ecba973cc774a50395aac # tag=v1.0.26
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
|
||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: audit
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
run: npm test -- --coverage
|
||||
- uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4
|
||||
- name: Publish Test Results
|
||||
uses: step-security/publish-unit-test-result-action@v1
|
||||
uses: step-security/publish-unit-test-result-action@v2
|
||||
if: always()
|
||||
with:
|
||||
files: |
|
||||
|
||||
@@ -13,43 +13,94 @@
|
||||
|
||||
</div>
|
||||
|
||||
## Harden Github-hosted and self-hosted runners
|
||||
## Table of Contents
|
||||
|
||||
Harden-Runner provides network egress filtering and runtime security for GitHub-hosted and self-hosted runners.
|
||||
- [Introduction](#introduction)
|
||||
- [3,500+ open source projects use Harden-Runner](#3500-open-source-projects-use-harden-runner)
|
||||
- [Trusted By](#trusted-by)
|
||||
- [Case Studies](#case-studies)
|
||||
- [Why use Harden-Runner](#why-use-harden-runner)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Hardening GitHub-Hosted Runners](#hardening-github-hosted-runners)
|
||||
- [Hands-On Tutorials](#hands-on-tutorials)
|
||||
- [Support for Private Repositories](#support-for-private-repositories)
|
||||
- [Hardening Self-Hosted Runners](#hardening-self-hosted-runners)
|
||||
- [Self-Hosted Actions Runner Controller (ARC) Runners](#self-hosted-actions-runner-controller-arc-runners)
|
||||
- [Self-Hosted VM Runners (e.g. on EC2)](#self-hosted-vm-runners-eg-on-ec2)
|
||||
- [Features at a glance](#features-at-a-glance)
|
||||
- [View outbound network traffic at the job level](#view-outbound-network-traffic-at-the-job-level)
|
||||
- [View outbound network traffic at the organization level](#view-outbound-network-traffic-at-the-organization-level)
|
||||
- [View outbound HTTPS traffic at the job level](#view-outbound-https-traffic-at-the-job-level)
|
||||
- [Detect anomalous outbound network traffic](#detect-anomalous-outbound-network-traffic)
|
||||
- [Filter outbound network traffic to allowed endpoints](#filter-outbound-network-traffic-to-allowed-endpoints)
|
||||
- [Determine minimum GITHUB_TOKEN permissions using Harden-Runner](#determine-minimum-github_token-permissions-using-harden-runner)
|
||||
- [View the name and path of every file written during the build process](#view-the-name-and-path-of-every-file-written-during-the-build-process)
|
||||
- [View process names and arguments](#view-process-names-and-arguments)
|
||||
- [Detect tampering of source code during build](#detect-tampering-of-source-code-during-build)
|
||||
- [Run your job without sudo access](#run-your-job-without-sudo-access)
|
||||
- [Get real-time security alerts](#get-real-time-security-alerts)
|
||||
- [Discussions](#discussions)
|
||||
- [How does it work?](#how-does-it-work)
|
||||
- [GitHub-Hosted Runners](#github-hosted-runners-1)
|
||||
- [Self-Hosted Actions Runner Controller (ARC) Runners](#self-hosted-actions-runner-controller-arc-runners-1)
|
||||
- [Self-Hosted VM Runners (e.g. on EC2)](#self-hosted-vm-runners-eg-on-ec2-1)
|
||||
- [Limitations](#limitations)
|
||||
- [GitHub-Hosted Runners](#github-hosted-runners-2)
|
||||
- [Self-Hosted Actions Runner Controller (ARC) Runners](#self-hosted-actions-runner-controller-arc-runners-2)
|
||||
- [Self-Hosted VM Runners (e.g. on EC2)](#self-hosted-vm-runners-eg-on-ec2-2)
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
Harden-Runner provides network egress filtering and runtime security for GitHub-hosted and self-hosted runners. It is called Harden-Runner because it `hardens` the `runner` on which GitHub Actions workflows run.
|
||||
|
||||
Learn how Harden-Runner works through the video below, which shows how it detected a supply chain attack on a Google open-source project.
|
||||
|
||||
<a href="https://youtu.be/Yz72qAOrN9s" target="_blank"><img src="images/case-study-thumbnail1.png" alt="Harden-Runner detected supply chain attack in a Google open-source project" title="This case study video shows how StepSecurity Harden-Runner detected a CI/CD supply chain attack in real-time in Google’s open-source project Flank"></a>
|
||||
|
||||
## 3,000+ open source projects use Harden-Runner
|
||||
## 3,500+ open source projects use Harden-Runner
|
||||
|
||||
| [](https://app.stepsecurity.io/github/cisagov/skeleton-generic/actions/runs/7588528684) | [](https://app.stepsecurity.io/github/microsoft/ebpf-for-windows/actions/runs/7587031851) | [](https://app.stepsecurity.io/github/GoogleCloudPlatform/functions-framework-ruby/actions/runs/7576989995) | [](https://app.stepsecurity.io/github/DataDog/stratus-red-team/actions/runs/7446169664) | [](https://app.stepsecurity.io/github/intel/cve-bin-tool/actions/runs/7590975903) | [](https://app.stepsecurity.io/github/kubernetes-sigs/cluster-api-provider-azure/actions/runs/7591172950) | [](https://app.stepsecurity.io/github/nodejs/node/actions/runs/7591405720) | [](https://app.stepsecurity.io/github/aws/aperf/actions/runs/7631366761) |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **CISA**<br>[Explore](https://app.stepsecurity.io/github/cisagov/skeleton-generic/actions/runs/7588528684) | **Microsoft**<br>[Explore](https://app.stepsecurity.io/github/microsoft/ebpf-for-windows/actions/runs/7587031851) | **Google**<br>[Explore](https://app.stepsecurity.io/github/GoogleCloudPlatform/functions-framework-ruby/actions/runs/7576989995) | **DataDog**<br>[Explore](https://app.stepsecurity.io/github/DataDog/stratus-red-team/actions/runs/7446169664) | **Intel**<br>[Explore](https://app.stepsecurity.io/github/intel/cve-bin-tool/actions/runs/7590975903) | **Kubernetes**<br>[Explore](https://app.stepsecurity.io/github/kubernetes-sigs/cluster-api-provider-azure/actions/runs/7591172950) | **Node.js**<br>[Explore](https://app.stepsecurity.io/github/nodejs/node/actions/runs/7591405720) | **AWS**<br>[Explore](https://app.stepsecurity.io/github/aws/aperf/actions/runs/7631366761) |
|
||||
Harden-Runner is trusted by leading open source projects and enterprises to secure their CI/CD pipelines.
|
||||
|
||||
## Why
|
||||
### Trusted by
|
||||
|
||||
|
||||
| [](https://app.stepsecurity.io/github/cisagov/skeleton-generic/actions/runs/9947319332?jobid=27479776091&tab=network-events) | [](https://app.stepsecurity.io/github/microsoft/ebpf-for-windows/actions/runs/7587031851) | [](https://app.stepsecurity.io/github/GoogleCloudPlatform/functions-framework-ruby/actions/runs/7576989995) | [](https://app.stepsecurity.io/github/DataDog/stratus-red-team/actions/runs/7446169664) | [](https://app.stepsecurity.io/github/intel/cve-bin-tool/actions/runs/7590975903) | [](https://app.stepsecurity.io/github/kubernetes-sigs/cluster-api-provider-azure/actions/runs/7591172950) | [](https://app.stepsecurity.io/github/nodejs/node/actions/runs/7591405720) | [](https://app.stepsecurity.io/github/aws/aperf/actions/runs/7631366761) |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **CISA**<br>[Explore](https://app.stepsecurity.io/github/cisagov/skeleton-generic/actions/runs/9947319332?jobid=27479776091&tab=network-events) | **Microsoft**<br>[Explore](https://app.stepsecurity.io/github/microsoft/ebpf-for-windows/actions/runs/7587031851) | **Google**<br>[Explore](https://app.stepsecurity.io/github/GoogleCloudPlatform/functions-framework-ruby/actions/runs/7576989995) | **DataDog**<br>[Explore](https://app.stepsecurity.io/github/DataDog/stratus-red-team/actions/runs/7446169664) | **Intel**<br>[Explore](https://app.stepsecurity.io/github/intel/cve-bin-tool/actions/runs/7590975903) | **Kubernetes**<br>[Explore](https://app.stepsecurity.io/github/kubernetes-sigs/cluster-api-provider-azure/actions/runs/7591172950) | **Node.js**<br>[Explore](https://app.stepsecurity.io/github/nodejs/node/actions/runs/7591405720) | **AWS**<br>[Explore](https://app.stepsecurity.io/github/aws/aperf/actions/runs/7631366761) |
|
||||
|
||||
### Case Studies
|
||||
|
||||
- [Harden-Runner Detects CI/CD Supply Chain Attack in Google’s Open-Source Project Flank](https://www.stepsecurity.io/case-studies/flank)
|
||||
- [Kapiche secures their GitHub Actions software supply chain with Harden-Runner](https://www.stepsecurity.io/case-studies/kapiche)
|
||||
- [Arcjet Enhances CI/CD Security with Harden-Runner](https://www.stepsecurity.io/case-studies/arcjet)
|
||||
|
||||
|
||||
## Why use Harden-Runner
|
||||
|
||||
There are two main threats from compromised workflows, dependencies, and build tools in a CI/CD environment:
|
||||
|
||||
1. Exfiltration of CI/CD credentials and source code
|
||||
2. Tampering of source code, dependencies, or artifacts during the build to inject a backdoor
|
||||
|
||||
Harden-Runner monitors process, file, and network activity to:
|
||||
|
||||
| | Countermeasure | Prevent Security Breach |
|
||||
| --- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1. | Monitor and block outbound network traffic at the DNS, HTTPS (Layer 7), and network layers (Layers 3 and 4) to prevent exfiltration of code and CI/CD credentials | To prevent the [Codecov breach](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/ExfiltratingCICDSecrets.md) scenario |
|
||||
| 2. | Detect if source code is being tampered during the build process to inject a backdoor | To detect the [XZ Utils](https://www.stepsecurity.io/blog/analysis-of-backdoored-xz-utils-build-process-with-harden-runner) and [SolarWinds incident](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/TamperingDuringBuild.md) scenario |
|
||||
| 3. | Detect poisoned workflows and compromised dependencies | To detect [Dependency confusion](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/ExfiltratingCICDSecrets.md#dependency-confusion-attacks) and [Malicious dependencies](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/ExfiltratingCICDSecrets.md#compromised-dependencies) |
|
||||
| | Countermeasure | Prevent Security Breach |
|
||||
| --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1. | Monitor and block outbound network traffic at the DNS, HTTPS (Layer 7), and network layers (Layers 3 and 4) to prevent exfiltration of code and CI/CD credentials | To prevent the [Codecov breach](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/ExfiltratingCICDSecrets.md) scenario |
|
||||
| 2. | Detect if source code is being tampered during the build process to inject a backdoor | To detect the [XZ Utils](https://www.stepsecurity.io/blog/analysis-of-backdoored-xz-utils-build-process-with-harden-runner) and [SolarWinds incident](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/TamperingDuringBuild.md) scenarios |
|
||||
| 3. | Detect poisoned workflows and compromised dependencies that exhibit suspicious behavior | To detect [Dependency confusion](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/ExfiltratingCICDSecrets.md#dependency-confusion-attacks) and [Malicious dependencies](https://github.com/step-security/github-actions-goat/blob/main/docs/Vulnerabilities/ExfiltratingCICDSecrets.md#compromised-dependencies) scenarios |
|
||||
| 4. | Determine minimum GITHUB_TOKEN permissions by monitoring HTTPS calls to GitHub APIs | To set [minimum GITHUB_TOKEN permissions](https://www.stepsecurity.io/blog/determine-minimum-github-token-permissions-using-ebpf-with-stepsecurity-harden-runner) to reduce the impact of exfiltration |
|
||||
|
||||
## How
|
||||
## Getting Started
|
||||
|
||||
### GitHub-Hosted Runners
|
||||
### Hardening GitHub-Hosted Runners
|
||||
|
||||
1. Add the `step-security/harden-runner` GitHub Action to your GitHub Actions workflow file as the first step in each job.
|
||||
1. Add the `step-security/harden-runner` GitHub Action to your GitHub Actions workflow file as the first step in each job. You can automate adding Harden-Runner Action to your workflow file by pasting your workflow in the [StepSecurity online tool](https://app.stepsecurity.io/secureworkflow).
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
|
||||
- uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
```
|
||||
@@ -72,7 +123,7 @@ Harden-Runner monitors process, file, and network activity to:
|
||||
<img src="images/recommended-policy1.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
## Hands-On Tutorials
|
||||
#### Hands-On Tutorials
|
||||
|
||||
You can use [GitHub Actions Goat](https://github.com/step-security/github-actions-goat) to try Harden-Runner. You only need a GitHub Account and a web browser.
|
||||
|
||||
@@ -81,17 +132,21 @@ Hands-on Tutorials for GitHub Actions Runtime Security:
|
||||
1. [Filter Egress Network Traffic](https://github.com/step-security/github-actions-goat/blob/main/docs/Solutions/RestrictOutboundTraffic.md)
|
||||
2. [Detect File Tampering](https://github.com/step-security/github-actions-goat/blob/main/docs/Solutions/MonitorSourceCode.md)
|
||||
|
||||
## Support for Self-Hosted Runners and Private Repositories
|
||||
### Support for Private Repositories
|
||||
|
||||
Hardening for self-hosted runners and GitHub-hosted runners used in private repositories is supported with a commercial license. Check out the [documentation](https://docs.stepsecurity.io/stepsecurity-platform/billing) for more details.
|
||||
Hardening of runners used in private repositories is supported with a commercial license. Check out the [documentation](https://docs.stepsecurity.io/stepsecurity-platform/billing) for more details.
|
||||
|
||||
- To use Harden-Runner in a `Private` repository, you must install the [StepSecurity Actions Security GitHub App](https://github.com/apps/stepsecurity-actions-security).
|
||||
- This is needed to access the GitHub Actions API and to authenticate users to access the insights URL for private repositories.
|
||||
- To use Harden-Runner in a `Private` repository, you must install the [StepSecurity GitHub App](https://github.com/apps/stepsecurity-actions-security).
|
||||
- This is needed to access the GitHub Actions API and to authenticate users to access the dashboard for private repositories.
|
||||
- If you use Harden-Runner GitHub Action in a private repository, the generated insights URL is NOT public. Only those who have access to the repository can view it.
|
||||
|
||||
Read this [case study on how Kapiche uses Harden-Runner](https://www.stepsecurity.io/case-studies/kapiche/) to improve software supply chain security in their private repositories.
|
||||
|
||||
### Self-Hosted Actions Runner Controller (ARC) Runners
|
||||
### Hardening Self-Hosted Runners
|
||||
|
||||
Hardening of self-hosted runners is supported with a commercial license. Check out the [documentation](https://docs.stepsecurity.io/stepsecurity-platform/billing) for more details. For hardening of self-hosted runners you must install the [StepSecurity GitHub App](https://github.com/apps/stepsecurity-actions-security).
|
||||
|
||||
#### Self-Hosted Actions Runner Controller (ARC) Runners
|
||||
|
||||
> Explore demo workflows using self-hosted ARC Runner and ARC Harden-Runner [here](https://docs.stepsecurity.io/harden-runner/how-tos/enable-runtime-security-arc).
|
||||
|
||||
@@ -99,21 +154,21 @@ Actions Runner Controller (ARC) is a Kubernetes operator that orchestrates self-
|
||||
|
||||
- Instead of adding the Harden-Runner GitHub Action in each job, you'll need to install the ARC Harden-Runner daemonset on your Kubernetes cluster.
|
||||
- Upon installation, the ARC Harden-Runner daemonset monitors all jobs run on the cluster; you do NOT need to add the Harden-Runner GitHub Action to each job for `audit` mode. You do need to add the Harden-Runner GitHub Action to jobs where you want to enable `block` mode.
|
||||
- Please email support@stepsecurity.io for instructions on how to install the ARC-Harden-Runner daemonset on your Kubernetes cluster.
|
||||
- The instructions for installing the ARC-Harden-Runner daemonset are shown in the dashboard. To enable access to these instructions, please email support@stepsecurity.io.
|
||||
|
||||
### Self-Hosted VM Runners (e.g. on EC2)
|
||||
#### Self-Hosted VM Runners (e.g. on EC2)
|
||||
|
||||
> Explore demo workflows using self-hosted VM Runners and Harden-Runner [here](https://docs.stepsecurity.io/harden-runner/how-tos/enable-runtime-security-vm).
|
||||
|
||||
- Instead of adding the Harden-Runner GitHub Action in each job, you'll need to install the Harden-Runner agent on your runner image (e.g. AMI). This is typically done using packer or as a post-install step when using the https://github.com/philips-labs/terraform-aws-github-runner project to setup runners.
|
||||
- The Harden-Runner agent monitors all jobs run on the VM, both ephemeral and persistent runners are supported; you do NOT need to add the Harden-Runner GitHub Action to each job for `audit` mode. You do need to add the Harden-Runner GitHub Action to jobs where you want to enable `block` mode.
|
||||
- Please email support@stepsecurity.io for instructions on how to install the Harden-Runner agent on your self-hosted VM runners. This agent is different than the one used for GitHub-hosted runners.
|
||||
- The instructions for installing the Harden-Runner agent on your self-hosted VM runners are shown in the dashboard. To enable access to these instructions, please email support@stepsecurity.io. This agent is different than the one used for GitHub-hosted runners.
|
||||
|
||||
## Features at a glance
|
||||
|
||||
For details, check out the documentation at https://docs.stepsecurity.io
|
||||
|
||||
### 📶 View outbound network traffic
|
||||
### View outbound network traffic at the job level
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
@@ -123,35 +178,62 @@ Harden-Runner monitors all outbound traffic from each job at the DNS and network
|
||||
- For self-hosted runners, no changes are needed to workflow files to monitor egress traffic
|
||||
- A filtering (block) egress policy is suggested in the insights page based on the current and past job runs
|
||||
|
||||
### 🌐 View outbound HTTPS traffic
|
||||
<p align="left">
|
||||
<img src="images/network-events1.png" alt="Insights from harden-runner" >
|
||||
</p>
|
||||
|
||||
> Applies to GitHub-hosted and self-hosted VM runners
|
||||
### View outbound network traffic at the organization level
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
You can view all unique network destinations from all workflow runs in your organization on the `Runtime Security` tab.
|
||||
|
||||
- The `All Observed Endpoints` menu provides a detailed list of all network destinations contacted by your Actions runners.
|
||||
- For each listed endpoint, the `View Sample Workflow Runs` option enables you to examine individual GitHub Actions workflow runs that interacted with the endpoint.
|
||||
|
||||
For more details refer [Unified Network Egress View: Centralize GitHub Actions Network Destinations for Your Enterprise](https://www.stepsecurity.io/blog/unified-network-egress-view-centralize-github-actions-network-destinations-for-your-enterprise)
|
||||
|
||||
<p align="left">
|
||||
<img src="images/org-level.png" width="400" alt="View outbound network traffic at the organization level" >
|
||||
</p>
|
||||
|
||||
### View outbound HTTPS traffic at the job level
|
||||
|
||||
> Applies to GitHub-hosted and self-hosted VM runners
|
||||
|
||||
Harden-Runner can monitor outbound HTTPS requests. This feature is supported with a commercial license.
|
||||
|
||||
- HTTPS events are monitored using eBPF (no MITM proxy is used)
|
||||
- If a HTTP PUT/ POST/ PATCH call is made to `github.com` or `api.github.com` hosts to a HTTP Path with a different organization than where the workflow is running, the call is marked as anomalous
|
||||
- As of now, only HTTPS calls to `github.com` and `api.github.com` hosts are monitoried.
|
||||
- If a HTTP PUT/ POST/ PATCH call is made to GitHub APIs to a HTTP Path with a different organization than where the workflow is running, the call is marked as anomalous
|
||||
- As of now, only HTTPS calls to `github.com`, `api.github.com`, `*.pkg.github.com`, and `ghcr.io` hosts are monitoried.
|
||||
|
||||
<p align="left">
|
||||
<img src="images/https-events.png" alt="Policy recommended by harden-runner" >
|
||||
<img src="images/https-events.png" alt="View outbound HTTPS traffic at the job level" >
|
||||
</p>
|
||||
|
||||
### ⚠️ Detect anomalous outbound network traffic
|
||||
### Detect anomalous outbound network traffic
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
Harden-Runner creates a baseline of outbound traffic for each job during the first few runs that it monitors
|
||||
You can detect suspicious/ anomalous traffic using this feature even in `egress-policy:audit` mode.
|
||||
|
||||
- After the baseline is created, any new outbound destinations are marked as anomalous in the insights page
|
||||
- Anomaly detection feature creates a machine learning model of outbound network calls by analyzing the historical data of the same workflow in previous runs
|
||||
- After the baseline is created, any anomalous outbound destinations are marked as anomalous in the insights page, and real-time alerts are triggered
|
||||
- You can view the list of all anomalous outbound network traffic in the `Runtime detections` page on the dashboard
|
||||
|
||||
For more details, refer to [Anomalous Outbound Call Detection Using Machine Learning](https://www.stepsecurity.io/blog/announcing-anomalous-outbound-call-detection-using-machine-learning)
|
||||
|
||||
### 🚦 Filter outbound network traffic to allowed endpoints
|
||||
### Filter outbound network traffic to allowed endpoints
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
Once allowed endpoints are set in the policy in the workflow file, or in the [Policy Store](https://docs.stepsecurity.io/harden-runner/how-tos/block-egress-traffic#2-add-the-policy-using-the-policy-store)
|
||||
You can see recommended egress block policy in the `Recommendations` tab for each job. This is based on observed traffic across multiple runs of the job.
|
||||
|
||||
<p align="left">
|
||||
<img src="images/recommended-policy1.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
Once you set these allowed endpoints in the workflow file, or in the [Policy Store](https://docs.stepsecurity.io/harden-runner/how-tos/block-egress-traffic#2-add-the-policy-using-the-policy-store) and switch to using `egress-policy:block`
|
||||
|
||||
- Harden-Runner blocks egress traffic at the DNS (Layer 7) and network layers (Layers 3 and 4)
|
||||
- It blocks DNS exfiltration, where attacker tries to send data out using DNS resolution
|
||||
@@ -161,7 +243,25 @@ Once allowed endpoints are set in the policy in the workflow file, or in the [Po
|
||||
<img src="images/blocked-outbound-call-3.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
### 📋 View the name and path of every file written during the build process
|
||||
### Determine minimum GITHUB_TOKEN permissions using Harden-Runner
|
||||
|
||||
> Applies to GitHub-hosted runners
|
||||
|
||||
Harden-Runner monitors outbound HTTPS requests using eBPF and uses the PATHs and VERBs of these HTTPS calls to recommend the minimum GITHUB_TOKEN permissions for each job in your workflow. This feature is supported with a commercial license.
|
||||
|
||||
- GITHUB_TOKEN is an automatically generated secret used to authenticate to GitHub APIs from GitHub Actions workflows.
|
||||
- Harden-Runner can monitor the VERBs (e.g., `GET`, `POST`) and PATHs (e.g., `/repos/owner/repo/issues`) for calls made to the GitHub APIs from the runner.
|
||||
- Each GitHub Actions API call requires a corresponding GITHUB_TOKEN permission. For instance, a GET request to the `/repos/org/repo/info/refs?service=git-upload-pack` endpoint requires the `contents: read` permission.
|
||||
- The recommendation for the minimum GITHUB_TOKEN permissions are show in the `Recommendations` tab.
|
||||
|
||||
For more details, refer to [Determine Minimum GITHUB_TOKEN Permissions Using eBPF with Harden-Runner.
|
||||
](https://www.stepsecurity.io/blog/determine-minimum-github-token-permissions-using-ebpf-with-stepsecurity-harden-runner)
|
||||
|
||||
<p align="left">
|
||||
<img src="images/token-perms-recommendation.png" alt="View recommendation for minimum GITHUB_TOKEN permissions" >
|
||||
</p>
|
||||
|
||||
### View the name and path of every file written during the build process
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
@@ -175,21 +275,21 @@ View the name and path of every file that was written during the build process.
|
||||
<img src="images/file-write-events.png" alt="View the name and path of every file written during the build process" >
|
||||
</p>
|
||||
|
||||
### 🔄 View process names and arguments
|
||||
### View process names and arguments
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
View process names, PIDs, and process arguments. This feature is supported with a commercial license.
|
||||
|
||||
- Harden-Runner tracks every process that is run during the build process.
|
||||
- Clicking on any file reveals a list of processes that wrote to it.
|
||||
- You can walk up the process tree and view process arguments to understand the build process and detect suspicious activity.
|
||||
- Clicking on any process ID (PID) in the network events, file events, or HTTPS events shows the process that caused the event, along with the process arguments.
|
||||
- You can walk up the process tree by clicking `View Parent Process` to understand the build process and detect suspicious activity.
|
||||
|
||||
<p align="left">
|
||||
<img src="images/process-events-3.png" alt="View process names and arguments" >
|
||||
</p>
|
||||
|
||||
### 📁 Detect tampering of source code during build
|
||||
### Detect tampering of source code during build
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
@@ -204,7 +304,7 @@ Harden-Runner monitors file writes and can detect if a file is overwritten.
|
||||
<img src="images/file-events.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
### 🚫 Run your job without sudo access
|
||||
### Run your job without sudo access
|
||||
|
||||
> Applies to GitHub-hosted runners
|
||||
|
||||
@@ -215,14 +315,18 @@ GitHub-hosted runner uses passwordless sudo for running jobs.
|
||||
recommendation to disable sudo in the insights page
|
||||
- When you set `disable-sudo` to `true`, the job steps run without sudo access to the GitHub-hosted Ubuntu VM
|
||||
|
||||
### 🔔 Get security alerts
|
||||
<p align="left">
|
||||
<img src="images/recommended-policy1.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
### Get real-time security alerts
|
||||
|
||||
> Applies to both GitHub-hosted and self-hosted runners
|
||||
|
||||
Install the [StepSecurity Actions Security GitHub App](https://github.com/apps/stepsecurity-actions-security) to get security alerts.
|
||||
Install the [StepSecurity GitHub App](https://github.com/apps/stepsecurity-actions-security) to get security alerts/ notifications.
|
||||
|
||||
- Email and Slack notifications are supported
|
||||
- Notifications are sent when outbound traffic is blocked or source code is overwritten
|
||||
- Email, Slack, and Teams notifications are supported
|
||||
- Notifications are sent when anomalous outbound network/ HTTPS traffic is detected, outbound traffic is blocked, or source code is overwritten
|
||||
- Notifications are not repeated for the same alert for a given workflow
|
||||
|
||||
## Discussions
|
||||
|
||||
Vendored
+13
-3
@@ -2866,8 +2866,13 @@ const processLogLine = (line, tableEntries) => {
|
||||
const matches = line.match(/ip address:port ([\d.:]+), domain: ([\w.-]+), pid: (\d+), process: (\w+)/);
|
||||
if (matches) {
|
||||
const [ipAddress, domain, pid, process] = matches.slice(1);
|
||||
// Check if all values are non-empty
|
||||
if (pid && process && domain && ipAddress) {
|
||||
// Check if all values are non-empty and domain does not end with specified patterns
|
||||
if (pid &&
|
||||
process &&
|
||||
domain &&
|
||||
ipAddress &&
|
||||
!domain.endsWith(".actions.githubusercontent.com.") &&
|
||||
!domain.endsWith(".blob.core.windows.net.")) {
|
||||
const status = ipAddress.startsWith("54.185.253.63")
|
||||
? "❌ Blocked"
|
||||
: "✅ Allowed";
|
||||
@@ -2973,7 +2978,8 @@ const CONTAINER_MESSAGE = "This job is running in a container. Harden Runner doe
|
||||
const UBUNTU_MESSAGE = "This job is not running in a GitHub Actions Hosted Runner Ubuntu VM. Harden Runner is only supported on Ubuntu VM. This job will not be monitored.";
|
||||
const SELF_HOSTED_NO_AGENT_MESSAGE = "This job is running on a self-hosted runner, but the runner does not have Harden-Runner installed. This job will not be monitored.";
|
||||
const HARDEN_RUNNER_UNAVAILABLE_MESSAGE = "Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
|
||||
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner";
|
||||
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner.";
|
||||
const ARM64_RUNNER_MESSAGE = "ARM runners are not supported in the Harden-Runner community tier.";
|
||||
|
||||
;// CONCATENATED MODULE: external "node:fs"
|
||||
const external_node_fs_namespaceObject = require("node:fs");
|
||||
@@ -3023,6 +3029,7 @@ var src_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _argu
|
||||
|
||||
|
||||
(() => src_awaiter(void 0, void 0, void 0, function* () {
|
||||
console.log("[harden-runner] main-step");
|
||||
if (process.platform !== "linux") {
|
||||
console.log(UBUNTU_MESSAGE);
|
||||
return;
|
||||
@@ -3036,6 +3043,9 @@ var src_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _argu
|
||||
console.log(HARDEN_RUNNER_UNAVAILABLE_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (process.env.STATE_isTLS === "false" && process.arch === "arm64") {
|
||||
return;
|
||||
}
|
||||
if (lib_core.getBooleanInput("disable-telemetry") &&
|
||||
lib_core.getInput("egress-policy") === "block") {
|
||||
console.log("Telemetry will not be sent to StepSecurity API as disable-telemetry is set to true");
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+13
-3
@@ -2868,8 +2868,13 @@ const processLogLine = (line, tableEntries) => {
|
||||
const matches = line.match(/ip address:port ([\d.:]+), domain: ([\w.-]+), pid: (\d+), process: (\w+)/);
|
||||
if (matches) {
|
||||
const [ipAddress, domain, pid, process] = matches.slice(1);
|
||||
// Check if all values are non-empty
|
||||
if (pid && process && domain && ipAddress) {
|
||||
// Check if all values are non-empty and domain does not end with specified patterns
|
||||
if (pid &&
|
||||
process &&
|
||||
domain &&
|
||||
ipAddress &&
|
||||
!domain.endsWith(".actions.githubusercontent.com.") &&
|
||||
!domain.endsWith(".blob.core.windows.net.")) {
|
||||
const status = ipAddress.startsWith("54.185.253.63")
|
||||
? "❌ Blocked"
|
||||
: "✅ Allowed";
|
||||
@@ -2972,7 +2977,8 @@ const CONTAINER_MESSAGE = "This job is running in a container. Harden Runner doe
|
||||
const UBUNTU_MESSAGE = "This job is not running in a GitHub Actions Hosted Runner Ubuntu VM. Harden Runner is only supported on Ubuntu VM. This job will not be monitored.";
|
||||
const SELF_HOSTED_NO_AGENT_MESSAGE = "This job is running on a self-hosted runner, but the runner does not have Harden-Runner installed. This job will not be monitored.";
|
||||
const HARDEN_RUNNER_UNAVAILABLE_MESSAGE = "Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
|
||||
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner";
|
||||
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner.";
|
||||
const ARM64_RUNNER_MESSAGE = "ARM runners are not supported in the Harden-Runner community tier.";
|
||||
|
||||
;// CONCATENATED MODULE: external "node:fs"
|
||||
const external_node_fs_namespaceObject = require("node:fs");
|
||||
@@ -3071,6 +3077,7 @@ var cleanup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _
|
||||
|
||||
|
||||
(() => cleanup_awaiter(void 0, void 0, void 0, function* () {
|
||||
console.log("[harden-runner] post-step");
|
||||
if (process.platform !== "linux") {
|
||||
console.log(UBUNTU_MESSAGE);
|
||||
return;
|
||||
@@ -3088,6 +3095,9 @@ var cleanup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _
|
||||
if (process.env.STATE_selfHosted === "true") {
|
||||
return;
|
||||
}
|
||||
if (process.env.STATE_isTLS === "false" && process.arch === "arm64") {
|
||||
return;
|
||||
}
|
||||
if (String(process.env.STATE_monitorStatusCode) ===
|
||||
STATUS_HARDEN_RUNNER_UNAVAILABLE) {
|
||||
console.log(HARDEN_RUNNER_UNAVAILABLE_MESSAGE);
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+129
-75
@@ -71276,8 +71276,13 @@ const processLogLine = (line, tableEntries) => {
|
||||
const matches = line.match(/ip address:port ([\d.:]+), domain: ([\w.-]+), pid: (\d+), process: (\w+)/);
|
||||
if (matches) {
|
||||
const [ipAddress, domain, pid, process] = matches.slice(1);
|
||||
// Check if all values are non-empty
|
||||
if (pid && process && domain && ipAddress) {
|
||||
// Check if all values are non-empty and domain does not end with specified patterns
|
||||
if (pid &&
|
||||
process &&
|
||||
domain &&
|
||||
ipAddress &&
|
||||
!domain.endsWith(".actions.githubusercontent.com.") &&
|
||||
!domain.endsWith(".blob.core.windows.net.")) {
|
||||
const status = ipAddress.startsWith("54.185.253.63")
|
||||
? "❌ Blocked"
|
||||
: "✅ Allowed";
|
||||
@@ -71383,31 +71388,8 @@ const CONTAINER_MESSAGE = "This job is running in a container. Harden Runner doe
|
||||
const UBUNTU_MESSAGE = "This job is not running in a GitHub Actions Hosted Runner Ubuntu VM. Harden Runner is only supported on Ubuntu VM. This job will not be monitored.";
|
||||
const SELF_HOSTED_NO_AGENT_MESSAGE = "This job is running on a self-hosted runner, but the runner does not have Harden-Runner installed. This job will not be monitored.";
|
||||
const HARDEN_RUNNER_UNAVAILABLE_MESSAGE = "Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
|
||||
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner";
|
||||
|
||||
// EXTERNAL MODULE: ./node_modules/@actions/tool-cache/lib/tool-cache.js
|
||||
var tool_cache = __nccwpck_require__(7784);
|
||||
// EXTERNAL MODULE: external "crypto"
|
||||
var external_crypto_ = __nccwpck_require__(6417);
|
||||
;// CONCATENATED MODULE: ./src/checksum.ts
|
||||
|
||||
|
||||
|
||||
function verifyChecksum(downloadPath, is_tls) {
|
||||
const fileBuffer = external_fs_.readFileSync(downloadPath);
|
||||
const checksum = external_crypto_.createHash("sha256")
|
||||
.update(fileBuffer)
|
||||
.digest("hex"); // checksum of downloaded file
|
||||
let expectedChecksum = "ceb925c78e5c79af4f344f08f59bbdcf3376d20d15930a315f9b24b6c4d0328a"; // checksum for v0.13.5
|
||||
if (is_tls) {
|
||||
expectedChecksum =
|
||||
"846ae66c6cfab958fe61736cec0b58bdb7651b36af04c279405c7114675d7033"; // checksum for tls_agent
|
||||
}
|
||||
if (checksum !== expectedChecksum) {
|
||||
lib_core.setFailed(`Checksum verification failed, expected ${expectedChecksum} instead got ${checksum}`);
|
||||
}
|
||||
lib_core.debug("Checksum verification passed.");
|
||||
}
|
||||
const ARC_RUNNER_MESSAGE = "Workflow is currently being executed in ARC based runner.";
|
||||
const ARM64_RUNNER_MESSAGE = "ARM runners are not supported in the Harden-Runner community tier.";
|
||||
|
||||
;// CONCATENATED MODULE: external "node:fs"
|
||||
const external_node_fs_namespaceObject = require("node:fs");
|
||||
@@ -71620,8 +71602,100 @@ function isTLSEnabled(owner) {
|
||||
});
|
||||
}
|
||||
function isGithubHosted() {
|
||||
const runnerName = process.env.RUNNER_NAME || "";
|
||||
return runnerName.startsWith("GitHub Actions");
|
||||
const runnerEnvironment = process.env.RUNNER_ENVIRONMENT || "";
|
||||
return runnerEnvironment === "github-hosted";
|
||||
}
|
||||
|
||||
// EXTERNAL MODULE: ./node_modules/@actions/tool-cache/lib/tool-cache.js
|
||||
var tool_cache = __nccwpck_require__(7784);
|
||||
// EXTERNAL MODULE: external "crypto"
|
||||
var external_crypto_ = __nccwpck_require__(6417);
|
||||
;// CONCATENATED MODULE: ./src/checksum.ts
|
||||
|
||||
|
||||
|
||||
const CHECKSUMS = {
|
||||
tls: {
|
||||
amd64: "0bd500769646f0a90c0dfe9ac59699d5165bed549a9870c031b861146af337b2",
|
||||
arm64: "c2448ac205fd90f46abba31c13cf34c3b997824881502f736315fb08ac0a5a5c",
|
||||
},
|
||||
non_tls: {
|
||||
amd64: "a9f1842e3d7f3d38c143dbe8ffe1948e6c8173cd04da072d9f9d128bb400844a", // v0.13.7
|
||||
},
|
||||
};
|
||||
function verifyChecksum(downloadPath, isTLS, variant) {
|
||||
const fileBuffer = external_fs_.readFileSync(downloadPath);
|
||||
const checksum = external_crypto_.createHash("sha256")
|
||||
.update(fileBuffer)
|
||||
.digest("hex"); // checksum of downloaded file
|
||||
let expectedChecksum = "";
|
||||
if (isTLS) {
|
||||
expectedChecksum = CHECKSUMS["tls"][variant];
|
||||
}
|
||||
else {
|
||||
expectedChecksum = CHECKSUMS["non_tls"][variant];
|
||||
}
|
||||
if (checksum !== expectedChecksum) {
|
||||
lib_core.setFailed(`Checksum verification failed, expected ${expectedChecksum} instead got ${checksum}`);
|
||||
}
|
||||
lib_core.debug("Checksum verification passed.");
|
||||
}
|
||||
|
||||
;// CONCATENATED MODULE: ./src/install-agent.ts
|
||||
var install_agent_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function installAgent(isTLS, configStr) {
|
||||
return install_agent_awaiter(this, void 0, void 0, function* () {
|
||||
// Note: to avoid github rate limiting
|
||||
const token = lib_core.getInput("token", { required: true });
|
||||
const auth = `token ${token}`;
|
||||
const variant = process.arch === "x64" ? "amd64" : "arm64";
|
||||
let downloadPath;
|
||||
external_fs_.appendFileSync(process.env.GITHUB_STATE, `isTLS=${isTLS}${external_os_.EOL}`, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
if (isTLS) {
|
||||
downloadPath = yield tool_cache.downloadTool(`https://packages.stepsecurity.io/github-hosted/harden-runner_1.3.2_linux_${variant}.tar.gz`);
|
||||
}
|
||||
else {
|
||||
if (variant === "arm64") {
|
||||
console.log(ARM64_RUNNER_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
downloadPath = yield tool_cache.downloadTool("https://github.com/step-security/agent/releases/download/v0.13.7/agent_0.13.7_linux_amd64.tar.gz", undefined, auth);
|
||||
}
|
||||
verifyChecksum(downloadPath, isTLS, variant);
|
||||
const extractPath = yield tool_cache.extractTar(downloadPath);
|
||||
let cmd = "cp", args = [external_path_.join(extractPath, "agent"), "/home/agent/agent"];
|
||||
external_child_process_.execFileSync(cmd, args);
|
||||
external_child_process_.execSync("chmod +x /home/agent/agent");
|
||||
external_fs_.writeFileSync("/home/agent/agent.json", configStr);
|
||||
cmd = "sudo";
|
||||
args = [
|
||||
"cp",
|
||||
external_path_.join(__dirname, "agent.service"),
|
||||
"/etc/systemd/system/agent.service",
|
||||
];
|
||||
external_child_process_.execFileSync(cmd, args);
|
||||
external_child_process_.execSync("sudo systemctl daemon-reload");
|
||||
external_child_process_.execSync("sudo service agent start", { timeout: 15000 });
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
;// CONCATENATED MODULE: ./src/setup.ts
|
||||
@@ -71653,10 +71727,10 @@ var setup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
||||
|
||||
|
||||
|
||||
|
||||
(() => setup_awaiter(void 0, void 0, void 0, function* () {
|
||||
var _a, _b;
|
||||
try {
|
||||
console.log("[harden-runner] pre-step");
|
||||
if (process.platform !== "linux") {
|
||||
console.log(UBUNTU_MESSAGE);
|
||||
return;
|
||||
@@ -71682,6 +71756,7 @@ var setup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
||||
private: ((_b = (_a = github.context === null || github.context === void 0 ? void 0 : github.context.payload) === null || _a === void 0 ? void 0 : _a.repository) === null || _b === void 0 ? void 0 : _b.private) || false,
|
||||
is_github_hosted: isGithubHosted(),
|
||||
is_debug: lib_core.isDebug(),
|
||||
one_time_key: "",
|
||||
};
|
||||
let policyName = lib_core.getInput("policy");
|
||||
if (policyName !== "") {
|
||||
@@ -71790,6 +71865,7 @@ var setup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
||||
});
|
||||
if (statusCode === 200 && responseData) {
|
||||
console.log(`Runner IP Address: ${responseData.runner_ip_address}`);
|
||||
confg.one_time_key = responseData.one_time_key;
|
||||
addSummary = responseData.monitoring_started ? "true" : "false";
|
||||
}
|
||||
}
|
||||
@@ -71807,54 +71883,32 @@ var setup_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _ar
|
||||
const confgStr = JSON.stringify(confg);
|
||||
external_child_process_.execSync("sudo mkdir -p /home/agent");
|
||||
external_child_process_.execSync("sudo chown -R $USER /home/agent");
|
||||
// Note: to avoid github rate limiting
|
||||
let token = lib_core.getInput("token");
|
||||
let auth = `token ${token}`;
|
||||
let downloadPath;
|
||||
if (yield isTLSEnabled(github.context.repo.owner)) {
|
||||
downloadPath = yield tool_cache.downloadTool("https://packages.stepsecurity.io/github-hosted/harden-runner_1.2.0_linux_amd64.tar.gz");
|
||||
verifyChecksum(downloadPath, true); // NOTE: verifying tls_agent's checksum, before extracting
|
||||
}
|
||||
else {
|
||||
downloadPath = yield tool_cache.downloadTool("https://github.com/step-security/agent/releases/download/v0.13.5/agent_0.13.5_linux_amd64.tar.gz", undefined, auth);
|
||||
verifyChecksum(downloadPath, false); // NOTE: verifying agent's checksum, before extracting
|
||||
}
|
||||
const extractPath = yield tool_cache.extractTar(downloadPath);
|
||||
let cmd = "cp", args = [external_path_.join(extractPath, "agent"), "/home/agent/agent"];
|
||||
external_child_process_.execFileSync(cmd, args);
|
||||
external_child_process_.execSync("chmod +x /home/agent/agent");
|
||||
external_fs_.writeFileSync("/home/agent/agent.json", confgStr);
|
||||
cmd = "sudo";
|
||||
args = [
|
||||
"cp",
|
||||
external_path_.join(__dirname, "agent.service"),
|
||||
"/etc/systemd/system/agent.service",
|
||||
];
|
||||
external_child_process_.execFileSync(cmd, args);
|
||||
external_child_process_.execSync("sudo systemctl daemon-reload");
|
||||
external_child_process_.execSync("sudo service agent start", { timeout: 15000 });
|
||||
// Check that the file exists locally
|
||||
var statusFile = "/home/agent/agent.status";
|
||||
var logFile = "/home/agent/agent.log";
|
||||
var counter = 0;
|
||||
while (true) {
|
||||
if (!external_fs_.existsSync(statusFile)) {
|
||||
counter++;
|
||||
if (counter > 30) {
|
||||
console.log("timed out");
|
||||
if (external_fs_.existsSync(logFile)) {
|
||||
var content = external_fs_.readFileSync(logFile, "utf-8");
|
||||
console.log(content);
|
||||
let isTLS = yield isTLSEnabled(github.context.repo.owner);
|
||||
const agentInstalled = yield installAgent(isTLS, confgStr);
|
||||
if (agentInstalled) {
|
||||
// Check that the file exists locally
|
||||
var statusFile = "/home/agent/agent.status";
|
||||
var logFile = "/home/agent/agent.log";
|
||||
var counter = 0;
|
||||
while (true) {
|
||||
if (!external_fs_.existsSync(statusFile)) {
|
||||
counter++;
|
||||
if (counter > 30) {
|
||||
console.log("timed out");
|
||||
if (external_fs_.existsSync(logFile)) {
|
||||
var content = external_fs_.readFileSync(logFile, "utf-8");
|
||||
console.log(content);
|
||||
}
|
||||
break;
|
||||
}
|
||||
yield setup_sleep(300);
|
||||
} // The file *does* exist
|
||||
else {
|
||||
// Read the file
|
||||
var content = external_fs_.readFileSync(statusFile, "utf-8");
|
||||
console.log(content);
|
||||
break;
|
||||
}
|
||||
yield setup_sleep(300);
|
||||
} // The file *does* exist
|
||||
else {
|
||||
// Read the file
|
||||
var content = external_fs_.readFileSync(statusFile, "utf-8");
|
||||
console.log(content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Generated
+14
-14
@@ -2803,12 +2803,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -3676,9 +3676,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
@@ -9397,12 +9397,12 @@
|
||||
}
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
@@ -10042,9 +10042,9 @@
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
|
||||
+20
-6
@@ -2,19 +2,33 @@ import * as core from "@actions/core";
|
||||
import * as crypto from "crypto";
|
||||
import * as fs from "fs";
|
||||
|
||||
export function verifyChecksum(downloadPath: string, is_tls: boolean) {
|
||||
const CHECKSUMS = {
|
||||
tls: {
|
||||
amd64: "0bd500769646f0a90c0dfe9ac59699d5165bed549a9870c031b861146af337b2", // v1.3.2
|
||||
arm64: "c2448ac205fd90f46abba31c13cf34c3b997824881502f736315fb08ac0a5a5c",
|
||||
},
|
||||
non_tls: {
|
||||
amd64: "a9f1842e3d7f3d38c143dbe8ffe1948e6c8173cd04da072d9f9d128bb400844a", // v0.13.7
|
||||
},
|
||||
};
|
||||
|
||||
export function verifyChecksum(
|
||||
downloadPath: string,
|
||||
isTLS: boolean,
|
||||
variant: string
|
||||
) {
|
||||
const fileBuffer: Buffer = fs.readFileSync(downloadPath);
|
||||
const checksum: string = crypto
|
||||
.createHash("sha256")
|
||||
.update(fileBuffer)
|
||||
.digest("hex"); // checksum of downloaded file
|
||||
|
||||
let expectedChecksum: string =
|
||||
"ceb925c78e5c79af4f344f08f59bbdcf3376d20d15930a315f9b24b6c4d0328a"; // checksum for v0.13.5
|
||||
let expectedChecksum: string = "";
|
||||
|
||||
if (is_tls) {
|
||||
expectedChecksum =
|
||||
"846ae66c6cfab958fe61736cec0b58bdb7651b36af04c279405c7114675d7033"; // checksum for tls_agent
|
||||
if (isTLS) {
|
||||
expectedChecksum = CHECKSUMS["tls"][variant];
|
||||
} else {
|
||||
expectedChecksum = CHECKSUMS["non_tls"][variant];
|
||||
}
|
||||
|
||||
if (checksum !== expectedChecksum) {
|
||||
|
||||
@@ -5,6 +5,8 @@ import isDocker from "is-docker";
|
||||
import { arcCleanUp, isArcRunner, removeStepPolicyFiles } from "./arc-runner";
|
||||
|
||||
(async () => {
|
||||
console.log("[harden-runner] post-step");
|
||||
|
||||
if (process.platform !== "linux") {
|
||||
console.log(common.UBUNTU_MESSAGE);
|
||||
return;
|
||||
@@ -25,6 +27,10 @@ import { arcCleanUp, isArcRunner, removeStepPolicyFiles } from "./arc-runner";
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.env.STATE_isTLS === "false" && process.arch === "arm64") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
String(process.env.STATE_monitorStatusCode) ===
|
||||
common.STATUS_HARDEN_RUNNER_UNAVAILABLE
|
||||
|
||||
+13
-3
@@ -35,8 +35,15 @@ export const processLogLine = (
|
||||
if (matches) {
|
||||
const [ipAddress, domain, pid, process] = matches.slice(1);
|
||||
|
||||
// Check if all values are non-empty
|
||||
if (pid && process && domain && ipAddress) {
|
||||
// Check if all values are non-empty and domain does not end with specified patterns
|
||||
if (
|
||||
pid &&
|
||||
process &&
|
||||
domain &&
|
||||
ipAddress &&
|
||||
!domain.endsWith(".actions.githubusercontent.com.") &&
|
||||
!domain.endsWith(".blob.core.windows.net.")
|
||||
) {
|
||||
const status = ipAddress.startsWith("54.185.253.63")
|
||||
? "❌ Blocked"
|
||||
: "✅ Allowed";
|
||||
@@ -173,4 +180,7 @@ export const HARDEN_RUNNER_UNAVAILABLE_MESSAGE =
|
||||
"Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
|
||||
|
||||
export const ARC_RUNNER_MESSAGE =
|
||||
"Workflow is currently being executed in ARC based runner";
|
||||
"Workflow is currently being executed in ARC based runner.";
|
||||
|
||||
export const ARM64_RUNNER_MESSAGE =
|
||||
"ARM runners are not supported in the Harden-Runner community tier.";
|
||||
|
||||
@@ -4,6 +4,8 @@ import isDocker from "is-docker";
|
||||
import { STEPSECURITY_WEB_URL } from "./configs";
|
||||
|
||||
(async () => {
|
||||
console.log("[harden-runner] main-step");
|
||||
|
||||
if (process.platform !== "linux") {
|
||||
console.log(common.UBUNTU_MESSAGE);
|
||||
return;
|
||||
@@ -21,6 +23,10 @@ import { STEPSECURITY_WEB_URL } from "./configs";
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.env.STATE_isTLS === "false" && process.arch === "arm64") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
core.getBooleanInput("disable-telemetry") &&
|
||||
core.getInput("egress-policy") === "block"
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import * as tc from "@actions/tool-cache";
|
||||
import * as core from "@actions/core";
|
||||
import * as cp from "child_process";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import { verifyChecksum } from "./checksum";
|
||||
import { EOL } from "os";
|
||||
import { ARM64_RUNNER_MESSAGE } from "./common";
|
||||
|
||||
export async function installAgent(
|
||||
isTLS: boolean,
|
||||
configStr: string
|
||||
): Promise<boolean> {
|
||||
// Note: to avoid github rate limiting
|
||||
const token = core.getInput("token", { required: true });
|
||||
const auth = `token ${token}`;
|
||||
|
||||
const variant = process.arch === "x64" ? "amd64" : "arm64";
|
||||
|
||||
let downloadPath: string;
|
||||
|
||||
fs.appendFileSync(process.env.GITHUB_STATE, `isTLS=${isTLS}${EOL}`, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
|
||||
if (isTLS) {
|
||||
downloadPath = await tc.downloadTool(
|
||||
`https://packages.stepsecurity.io/github-hosted/harden-runner_1.3.2_linux_${variant}.tar.gz`
|
||||
);
|
||||
} else {
|
||||
if (variant === "arm64") {
|
||||
console.log(ARM64_RUNNER_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
downloadPath = await tc.downloadTool(
|
||||
"https://github.com/step-security/agent/releases/download/v0.13.7/agent_0.13.7_linux_amd64.tar.gz",
|
||||
undefined,
|
||||
auth
|
||||
);
|
||||
}
|
||||
|
||||
verifyChecksum(downloadPath, isTLS, variant);
|
||||
|
||||
const extractPath = await tc.extractTar(downloadPath);
|
||||
|
||||
let cmd = "cp",
|
||||
args = [path.join(extractPath, "agent"), "/home/agent/agent"];
|
||||
|
||||
cp.execFileSync(cmd, args);
|
||||
|
||||
cp.execSync("chmod +x /home/agent/agent");
|
||||
|
||||
fs.writeFileSync("/home/agent/agent.json", configStr);
|
||||
|
||||
cmd = "sudo";
|
||||
args = [
|
||||
"cp",
|
||||
path.join(__dirname, "agent.service"),
|
||||
"/etc/systemd/system/agent.service",
|
||||
];
|
||||
cp.execFileSync(cmd, args);
|
||||
cp.execSync("sudo systemctl daemon-reload");
|
||||
cp.execSync("sudo service agent start", { timeout: 15000 });
|
||||
return true;
|
||||
}
|
||||
@@ -12,6 +12,7 @@ export interface Configuration {
|
||||
is_github_hosted: boolean;
|
||||
private: string;
|
||||
is_debug: boolean;
|
||||
one_time_key: string;
|
||||
}
|
||||
|
||||
export interface PolicyResponse {
|
||||
|
||||
@@ -40,6 +40,7 @@ test("merge configs", async () => {
|
||||
private: "true",
|
||||
is_github_hosted: true,
|
||||
is_debug: false,
|
||||
one_time_key: "",
|
||||
};
|
||||
let policyResponse: PolicyResponse = {
|
||||
owner: "h0x0er",
|
||||
@@ -65,6 +66,7 @@ test("merge configs", async () => {
|
||||
private: "true",
|
||||
is_github_hosted: true,
|
||||
is_debug: false,
|
||||
one_time_key: "",
|
||||
};
|
||||
|
||||
localConfig = mergeConfigs(localConfig, policyResponse);
|
||||
|
||||
+29
-61
@@ -5,8 +5,6 @@ import * as httpm from "@actions/http-client";
|
||||
import * as path from "path";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import * as common from "./common";
|
||||
import * as tc from "@actions/tool-cache";
|
||||
import { verifyChecksum } from "./checksum";
|
||||
import isDocker from "is-docker";
|
||||
import { context } from "@actions/github";
|
||||
import { EOL } from "os";
|
||||
@@ -25,14 +23,18 @@ import * as utils from "@actions/cache/lib/internal/cacheUtils";
|
||||
import { isArcRunner, sendAllowedEndpoints } from "./arc-runner";
|
||||
import { STEPSECURITY_API_URL, STEPSECURITY_WEB_URL } from "./configs";
|
||||
import { isGithubHosted, isTLSEnabled } from "./tls-inspect";
|
||||
import { installAgent } from "./install-agent";
|
||||
|
||||
interface MonitorResponse {
|
||||
runner_ip_address?: string;
|
||||
one_time_key?: string;
|
||||
monitoring_started?: boolean;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log("[harden-runner] pre-step");
|
||||
|
||||
if (process.platform !== "linux") {
|
||||
console.log(common.UBUNTU_MESSAGE);
|
||||
return;
|
||||
@@ -60,6 +62,7 @@ interface MonitorResponse {
|
||||
private: context?.payload?.repository?.private || false,
|
||||
is_github_hosted: isGithubHosted(),
|
||||
is_debug: core.isDebug(),
|
||||
one_time_key: "",
|
||||
};
|
||||
|
||||
let policyName = core.getInput("policy");
|
||||
@@ -200,6 +203,7 @@ interface MonitorResponse {
|
||||
|
||||
if (statusCode === 200 && responseData) {
|
||||
console.log(`Runner IP Address: ${responseData.runner_ip_address}`);
|
||||
confg.one_time_key = responseData.one_time_key;
|
||||
addSummary = responseData.monitoring_started ? "true" : "false";
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -223,70 +227,34 @@ interface MonitorResponse {
|
||||
cp.execSync("sudo mkdir -p /home/agent");
|
||||
cp.execSync("sudo chown -R $USER /home/agent");
|
||||
|
||||
// Note: to avoid github rate limiting
|
||||
let token = core.getInput("token");
|
||||
let auth = `token ${token}`;
|
||||
let isTLS = await isTLSEnabled(context.repo.owner);
|
||||
|
||||
let downloadPath: string;
|
||||
const agentInstalled = await installAgent(isTLS, confgStr);
|
||||
|
||||
if (await isTLSEnabled(context.repo.owner)) {
|
||||
downloadPath = await tc.downloadTool(
|
||||
"https://packages.stepsecurity.io/github-hosted/harden-runner_1.2.0_linux_amd64.tar.gz"
|
||||
);
|
||||
verifyChecksum(downloadPath, true); // NOTE: verifying tls_agent's checksum, before extracting
|
||||
} else {
|
||||
downloadPath = await tc.downloadTool(
|
||||
"https://github.com/step-security/agent/releases/download/v0.13.5/agent_0.13.5_linux_amd64.tar.gz",
|
||||
undefined,
|
||||
auth
|
||||
);
|
||||
|
||||
verifyChecksum(downloadPath, false); // NOTE: verifying agent's checksum, before extracting
|
||||
}
|
||||
|
||||
const extractPath = await tc.extractTar(downloadPath);
|
||||
|
||||
let cmd = "cp",
|
||||
args = [path.join(extractPath, "agent"), "/home/agent/agent"];
|
||||
|
||||
cp.execFileSync(cmd, args);
|
||||
|
||||
cp.execSync("chmod +x /home/agent/agent");
|
||||
|
||||
fs.writeFileSync("/home/agent/agent.json", confgStr);
|
||||
|
||||
cmd = "sudo";
|
||||
args = [
|
||||
"cp",
|
||||
path.join(__dirname, "agent.service"),
|
||||
"/etc/systemd/system/agent.service",
|
||||
];
|
||||
cp.execFileSync(cmd, args);
|
||||
cp.execSync("sudo systemctl daemon-reload");
|
||||
cp.execSync("sudo service agent start", { timeout: 15000 });
|
||||
|
||||
// Check that the file exists locally
|
||||
var statusFile = "/home/agent/agent.status";
|
||||
var logFile = "/home/agent/agent.log";
|
||||
var counter = 0;
|
||||
while (true) {
|
||||
if (!fs.existsSync(statusFile)) {
|
||||
counter++;
|
||||
if (counter > 30) {
|
||||
console.log("timed out");
|
||||
if (fs.existsSync(logFile)) {
|
||||
var content = fs.readFileSync(logFile, "utf-8");
|
||||
console.log(content);
|
||||
if (agentInstalled) {
|
||||
// Check that the file exists locally
|
||||
var statusFile = "/home/agent/agent.status";
|
||||
var logFile = "/home/agent/agent.log";
|
||||
var counter = 0;
|
||||
while (true) {
|
||||
if (!fs.existsSync(statusFile)) {
|
||||
counter++;
|
||||
if (counter > 30) {
|
||||
console.log("timed out");
|
||||
if (fs.existsSync(logFile)) {
|
||||
var content = fs.readFileSync(logFile, "utf-8");
|
||||
console.log(content);
|
||||
}
|
||||
break;
|
||||
}
|
||||
await sleep(300);
|
||||
} // The file *does* exist
|
||||
else {
|
||||
// Read the file
|
||||
var content = fs.readFileSync(statusFile, "utf-8");
|
||||
console.log(content);
|
||||
break;
|
||||
}
|
||||
await sleep(300);
|
||||
} // The file *does* exist
|
||||
else {
|
||||
// Read the file
|
||||
var content = fs.readFileSync(statusFile, "utf-8");
|
||||
console.log(content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
+2
-2
@@ -24,6 +24,6 @@ export async function isTLSEnabled(owner: string): Promise<boolean> {
|
||||
}
|
||||
|
||||
export function isGithubHosted() {
|
||||
const runnerName = process.env.RUNNER_NAME || "";
|
||||
return runnerName.startsWith("GitHub Actions");
|
||||
const runnerEnvironment = process.env.RUNNER_ENVIRONMENT || "";
|
||||
return runnerEnvironment === "github-hosted";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user