Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8454efe5d | ||
|
|
8f144f8401 | ||
|
|
5dfad97a98 | ||
|
|
b696244f12 | ||
|
|
10aedff7e5 | ||
|
|
4660e36515 | ||
|
|
6dc7d6afef | ||
|
|
6519f4ce27 | ||
|
|
18bf8ad2ca | ||
|
|
ce7687506a | ||
|
|
8a1ef77ccd | ||
|
|
55ac879a10 | ||
|
|
df4ea7360e | ||
|
|
1a7bdcd92a | ||
|
|
6e39bc0fe3 | ||
|
|
96d83b34a6 | ||
|
|
717b0e7500 | ||
|
|
266a5d6a50 | ||
|
|
ec78446d4c | ||
|
|
ad94cd124f | ||
|
|
0a5820a2ec | ||
|
|
38875807f8 | ||
|
|
e016e30675 | ||
|
|
b4401455ef | ||
|
|
77dc0c0be4 | ||
|
|
e283d58236 | ||
|
|
83919944a4 | ||
|
|
3c507732a9 | ||
|
|
ebacdc22ef | ||
|
|
f28b626429 | ||
|
|
620cac5711 | ||
|
|
118e4001a7 | ||
|
|
aca403bc5d | ||
|
|
3888ae1b9f | ||
|
|
1e3c2df856 | ||
|
|
5e53a6998f | ||
|
|
33d798180a | ||
|
|
5565dcdcb7 | ||
|
|
d5b1e9d8ee | ||
|
|
97d9729ae2 | ||
|
|
fdc6ce99e6 | ||
|
|
28278524d0 | ||
|
|
8869f0d5cb | ||
|
|
1c042b365b | ||
|
|
90755e0aee | ||
|
|
8e7e3dcca4 | ||
|
|
154371358e | ||
|
|
56b75a26f8 | ||
|
|
7ff6fc6501 | ||
|
|
1c4489aab2 | ||
|
|
6f6b0e0d2a | ||
|
|
7fd97fe4e1 | ||
|
|
1fae6dfd7b | ||
|
|
b8a619fa13 | ||
|
|
1e0cb5cd5c | ||
|
|
728d479ca5 |
@@ -22,13 +22,13 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: step-security/harden-runner@dd2c410b088af7c0dc8046f3ac9a8f4148492a95 # v1
|
||||
- uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v1
|
||||
with:
|
||||
allowed-endpoints:
|
||||
api.github.com:443
|
||||
github.com:443
|
||||
|
||||
- uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v2
|
||||
- name: Update the rc tag
|
||||
uses: step-security/publish-action@b438f840875fdcb7d1de4fc3d1d30e86cf6acb5d
|
||||
with:
|
||||
|
||||
@@ -41,16 +41,16 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dd2c410b088af7c0dc8046f3ac9a8f4148492a95
|
||||
uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518
|
||||
with:
|
||||
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d171c3b028d844f2bf14e9fdec0c58114451e4bf
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@b398f525a5587552e573b247ac661067fafa920b
|
||||
uses: github/codeql-action/init@515828d97454b8354517688ddc5b48402b723750
|
||||
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@b398f525a5587552e573b247ac661067fafa920b
|
||||
uses: github/codeql-action/autobuild@515828d97454b8354517688ddc5b48402b723750
|
||||
|
||||
# ℹ️ 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@b398f525a5587552e573b247ac661067fafa920b
|
||||
uses: github/codeql-action/analyze@515828d97454b8354517688ddc5b48402b723750
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@dd2c410b088af7c0dc8046f3ac9a8f4148492a95
|
||||
uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518
|
||||
with:
|
||||
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: step-security/harden-runner@dd2c410b088af7c0dc8046f3ac9a8f4148492a95
|
||||
- uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518
|
||||
with:
|
||||
allowed-endpoints:
|
||||
api.github.com:443
|
||||
github.com:443
|
||||
|
||||
- uses: actions/checkout@d171c3b028d844f2bf14e9fdec0c58114451e4bf
|
||||
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
|
||||
- name: Update the rc tag
|
||||
uses: step-security/publish-action@b438f840875fdcb7d1de4fc3d1d30e86cf6acb5d
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
name: Scorecards supply-chain security
|
||||
on:
|
||||
# Only the default branch is supported.
|
||||
branch_protection_rule:
|
||||
schedule:
|
||||
# Weekly on Saturdays.
|
||||
- cron: "30 1 * * 6"
|
||||
push:
|
||||
branches: [main, master]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecards analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Used to receive a badge. (Upcoming feature)
|
||||
id-token: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # tag=v1.1.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) Read-only PAT token. Uncomment the `repo_token` line below if:
|
||||
# - you want to enable the Branch-Protection check on a *public* repository, or
|
||||
# - you are installing Scorecards on a *private* repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
|
||||
# repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
|
||||
|
||||
# Publish the results for public repositories to enable scorecard badges. For more details, see
|
||||
# https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories, `publish_results` will automatically be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# 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@0b7f8abb1508181956e8e162db84b466c27e18ce # tag=v3.0.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@515828d97454b8354517688ddc5b48402b723750 # tag=v1.0.26
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -0,0 +1,36 @@
|
||||
name: Test
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main # to update code coverage
|
||||
|
||||
permissions: # added using https://github.com/step-security/secure-workflows
|
||||
contents: read
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
codecov.io:443
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
storage.googleapis.com:443
|
||||
uploader.codecov.io:443
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Run coverage
|
||||
run: npm test -- --coverage
|
||||
- uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1
|
||||
@@ -1,34 +1,42 @@
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: light)" srcset="images/banner.png" width="400">
|
||||
<img src="images/banner.png" width="400">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://stepsecurity.io/?utm_source=github&utm_medium=organic_oss&utm_campaign=harden-runner)
|
||||
[](https://api.securityscorecards.dev/projects/github.com/step-security/harden-runner)
|
||||
[](https://raw.githubusercontent.com/step-security/harden-runner/main/LICENSE)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
Harden-Runner GitHub Action installs a security agent on the GitHub-hosted runner (Ubuntu VM) to
|
||||
|
||||
1. Prevent exfiltration of credentials
|
||||
2. Detect compromised dependencies and build tools
|
||||
3. Detect tampering of source code during build
|
||||
2. Detect tampering of source code during build
|
||||
3. Detect compromised dependencies and build tools
|
||||
|
||||
<p align="left">
|
||||
<img src="https://github.com/step-security/supply-chain-goat/blob/main/images/harden-runner/HardenRunnerGIFV.gif" alt="Demo using GIF" >
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="images/demo.gif" alt="Harden Runner demo">
|
||||
</p>
|
||||
|
||||
## Why
|
||||
|
||||
Compromised dependencies and build tools typically make outbound calls to exfiltrate data or credentials, or may tamper source code, dependencies, or artifacts during the build.
|
||||
Compromised dependencies and build tools typically make outbound calls to exfiltrate credentials, or may tamper source code, dependencies, or artifacts during the build.
|
||||
|
||||
Harden-Runner GitHub Actions installs a daemon that monitors process, file, and network activity to:
|
||||
|
||||
| |Countermeasure |Threat|
|
||||
|--|----------|----------------|
|
||||
|1.| Block outbound calls that are not in the allowed list to prevent exfiltration of credentials |To prevent [Codecov breach](https://github.com/step-security/supply-chain-goat/blob/main/RestrictOutboundTraffic.md) scenario|
|
||||
|2.| Detect if source code is being overwritten during the build process to inject a backdoor | To detect [SolarWinds incident scenario](https://github.com/step-security/supply-chain-goat/blob/main/MonitorSourceCode.md)|
|
||||
|3.| Detect compromised dependencies that make unexpected outbound network calls | To detect [Dependency confusion](https://github.com/step-security/supply-chain-goat/blob/main/DNSExfiltration.md) and [Malicious dependencies](https://github.com/step-security/supply-chain-goat/blob/main/CompromisedDependency.md)
|
||||
| | Countermeasure | Threat |
|
||||
| --- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1. | Block outbound calls that are not in the allowed list to prevent exfiltration of credentials | To prevent [Codecov breach](https://github.com/step-security/attack-simulator/blob/main/docs/RestrictOutboundTraffic.md) scenario |
|
||||
| 2. | Detect if source code is being overwritten during the build process to inject a backdoor | To detect [SolarWinds incident scenario](https://github.com/step-security/attack-simulator/blob/main/docs/MonitorSourceCode.md) |
|
||||
| 3. | Detect compromised dependencies that make unexpected outbound network calls | To detect [Dependency confusion](https://github.com/step-security/attack-simulator/blob/main/docs/DNSExfiltration.md) and [Malicious dependencies](https://github.com/step-security/attack-simulator/blob/main/docs/CompromisedDependency.md) |
|
||||
|
||||
Read this [case study](https://infosecwriteups.com/detecting-malware-packages-in-github-actions-7b93a9985635) on how Harden-Runner detected malicious packages in the NPM registry.
|
||||
|
||||
@@ -38,37 +46,82 @@ Read this [case study](https://infosecwriteups.com/detecting-malware-packages-in
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: step-security/harden-runner@dd2c410b088af7c0dc8046f3ac9a8f4148492a95
|
||||
- uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
```
|
||||
|
||||
2. In the workflow logs, you will see a link to security insights and recommendations.
|
||||
|
||||
<p align="left">
|
||||
<img src="https://github.com/step-security/supply-chain-goat/blob/main/images/harden-runner/ActionLog.png" alt="Link in build log" >
|
||||
</p>
|
||||
<p align="left">
|
||||
<img src="images/buildlog1.png" alt="Link in build log" >
|
||||
</p>
|
||||
|
||||
3. Click on the link ([example link](https://app.stepsecurity.io/github/ossf/scorecard/actions/runs/2265028928)). You will see a process monitor view of what activities happened as part of each step.
|
||||
3. Click on the link ([example link](https://app.stepsecurity.io/github/ossf/scorecard/actions/runs/2265028928)). You will see a process monitor view of file and network activities correlated with each step of the job.
|
||||
|
||||
<p align="left">
|
||||
<img src="images/insights2.png" alt="Insights from harden-runner" >
|
||||
</p>
|
||||
|
||||
4. Below the insights, you will see the recommended policy. Update your workflow file with the recommended policy.
|
||||
|
||||
<p align="left">
|
||||
<img src="images/rec-policy1.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
## Features at a glance
|
||||
|
||||
For details, check out the documentation at https://docs.stepsecurity.io
|
||||
|
||||
<p align="left">
|
||||
<img src="https://github.com/step-security/supply-chain-goat/blob/main/images/harden-runner/OutboundCalls2.png" alt="Insights from harden-runner" >
|
||||
<img src="images/main-screenshot1.png" alt="Policy recommended by harden-runner">
|
||||
</p>
|
||||
|
||||
4. Below the insights, you will see the recommended policy. Add the recommended outbound endpoints to your workflow file, and only traffic to these endpoints will be allowed. When you use `egress-policy: block` mode, you can also set `disable-telemetry: true` to not send telemetry to the StepSecurity API.
|
||||
### Restrict egress traffic to allowed endpoints
|
||||
|
||||
Once allowed endpoints are set in the workflow file,
|
||||
|
||||
- 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
|
||||
- Blocks outbound traffic using IP tables
|
||||
|
||||
<p align="left">
|
||||
<img src="https://github.com/step-security/supply-chain-goat/blob/main/images/harden-runner/RecomPolicy1.png" alt="Policy recommended by harden-runner" >
|
||||
<img src="images/block-outbound-call.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
5. If outbound network call is made to an endpoint not in the allowed list or if source code is tampered, you will see an annotation in the workflow run.
|
||||
### Detect tampering of source code during build
|
||||
|
||||
Harden-Runner monitors file writes and can detect if a file is overwritten.
|
||||
|
||||
- Source code overwrite is not expected in a release build
|
||||
- All source code files are monitored, which means even changes to IaC files (Kubernetes manifest, Terraform) are detected
|
||||
- You can enable notifications to get one-time alert when source code is overwritten
|
||||
|
||||
<p align="left">
|
||||
<img src="https://github.com/step-security/supply-chain-goat/blob/main/images/harden-runner/SourceCodeOverwrite.png" alt="Policy recommended by harden-runner" >
|
||||
<img src="images/fileoverwrite.png" alt="Policy recommended by harden-runner" >
|
||||
</p>
|
||||
|
||||
### Run your job without sudo access
|
||||
|
||||
GitHub-hosted runner uses passwordless sudo for running jobs.
|
||||
|
||||
- This means compromised build tools or dependencies can install attack tools
|
||||
- If your job does not need sudo access, you see a policy
|
||||
recommendation to disable sudo in the insights page
|
||||
- When you set `disable-sudo` to `true`, the job steps run without sudo access to the Ubuntu VM
|
||||
|
||||
### Get security alerts
|
||||
|
||||
Install the [Harden Runner App](https://github.com/marketplace/harden-runner-app) to get security alerts.
|
||||
|
||||
- Email and Slack notifications are supported
|
||||
- Notifications are sent when outbound traffic is blocked or source code is overwritten
|
||||
- Notifications are not repeated for the same alert for a given workflow
|
||||
|
||||
## Support for private repositories
|
||||
|
||||
Private repositories are supported if they have a commercial license. Check out the [documentation](https://docs.stepsecurity.io/harden-runner/installation/business-enterprise-license) for more details.
|
||||
|
||||
Install the [Harden Runner App](https://github.com/marketplace/harden-runner-app) to use Harden-Runner GitHub Action for `Private` repositories.
|
||||
|
||||
- If you use Harden-Runner GitHub Action in a private repository, the generated insights URL is NOT public.
|
||||
@@ -105,7 +158,7 @@ Some important workflows using harden-runner:
|
||||
| |Repository |Link to insights|
|
||||
|--|----------|----------------|
|
||||
|1.|[nvm-sh/nvm](https://github.com/nvm-sh/nvm/blob/master/.github/workflows/lint.yml)|[Link to insights](https://app.stepsecurity.io/github/nvm-sh/nvm/actions/runs/1757959262)|
|
||||
|2.|[yannickcr/eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react/blob/master/.github/workflows/release.yml)|[Link to insights](https://app.stepsecurity.io/github/yannickcr/eslint-plugin-react/actions/runs/1930818585)
|
||||
|2.|[jsx-eslint/eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/.github/workflows/release.yml)|[Link to insights](https://app.stepsecurity.io/github/yannickcr/eslint-plugin-react/actions/runs/1930818585)
|
||||
|3.|[microsoft/msquic](https://github.com/microsoft/msquic/blob/main/.github/workflows/docker-publish.yml)|[Link to insights](https://app.stepsecurity.io/github/microsoft/msquic/actions/runs/1759010243)
|
||||
|4.|[ossf/scorecard](https://github.com/ossf/scorecard/blob/main/.github/workflows/codeql-analysis.yml)|[Link to insights](https://app.stepsecurity.io/github/ossf/scorecard/actions/runs/2006162141)
|
||||
|5.|[Automattic/vip-go-mu-plugins](https://github.com/Automattic/vip-go-mu-plugins/blob/master/.github/workflows/e2e.yml)|[Link to insights](https://app.stepsecurity.io/github/Automattic/vip-go-mu-plugins/actions/runs/1758760957)
|
||||
@@ -116,8 +169,4 @@ Harden-Runner GitHub Action downloads and installs the StepSecurity Agent.
|
||||
|
||||
- The code to monitor file, process, and network activity is in the Agent.
|
||||
- The agent is written in Go and is open source at https://github.com/step-security/agent
|
||||
- The agent's build is reproducible. You can view the steps to reproduce the build [here](http://app.stepsecurity.io/github/step-security/agent/releases/latest).
|
||||
|
||||
## 1-minute Demo Video
|
||||
|
||||
https://user-images.githubusercontent.com/25015917/156026587-79356450-9b35-4254-9c2e-7f2cc8d81059.mp4
|
||||
- The agent's build is reproducible. You can view the steps to reproduce the build [here](http://app.stepsecurity.io/github/step-security/agent/releases/latest)
|
||||
|
||||
@@ -16,6 +16,14 @@ inputs:
|
||||
description: "Disable sending telemetry to StepSecurity API, can be set to true or false. This can only be set to true when egress-policy is set to block"
|
||||
required: false
|
||||
default: "false"
|
||||
disable-sudo:
|
||||
description: "Disable sudo access for the runner account"
|
||||
required: false
|
||||
default: "false"
|
||||
disable-file-monitoring:
|
||||
description: "Disable file monitoring"
|
||||
required: false
|
||||
default: "false"
|
||||
branding:
|
||||
icon: "check-square"
|
||||
color: "green"
|
||||
|
||||
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 456 KiB |
|
After Width: | Height: | Size: 57 KiB |
@@ -0,0 +1,5 @@
|
||||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "step-security-harden-runner",
|
||||
"version": "1.5.0",
|
||||
"version": "2.2.0",
|
||||
"description": "Security agent for GitHub-hosted runner to monitor the build process",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -8,7 +8,8 @@
|
||||
"main": "ncc build src/index.ts --source-map",
|
||||
"pre": "ncc build src/setup.ts --source-map -o dist/pre",
|
||||
"post": "ncc build src/cleanup.ts --source-map -o dist/post",
|
||||
"lint": "eslint src/**/*.ts"
|
||||
"lint": "eslint src/**/*.ts",
|
||||
"test": "jest"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -34,16 +35,16 @@
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.2",
|
||||
"@typescript-eslint/parser": "^4.29.2",
|
||||
"@vercel/ncc": "^0.30.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"jest": ">=27.4.7",
|
||||
"jest": "^29.3.1",
|
||||
"jest-junit": ">=13.0.0",
|
||||
"ts-jest": ">=27.1.3",
|
||||
"ts-jest": "^29.0.3",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function verifyChecksum(downloadPath: string) {
|
||||
.digest("hex"); // checksum of downloaded file
|
||||
|
||||
const expectedChecksum: string =
|
||||
"7027c15a988395f3dde5e77d9a58889669adbda52fbd527ae8216e6d81dd8b1a"; // checksum for v0.11.0
|
||||
"10fd5587cfeba6aac4125be78ee32f60d5e780de10929f454525670c4c16935d"; // checksum for v0.12.2
|
||||
|
||||
if (checksum !== expectedChecksum) {
|
||||
core.setFailed(
|
||||
|
||||
@@ -17,6 +17,14 @@ import path from "path";
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
String(process.env.STATE_monitorStatusCode) ===
|
||||
common.STATUS_HARDEN_RUNNER_UNAVAILABLE
|
||||
) {
|
||||
console.log(common.HARDEN_RUNNER_UNAVAILABLE_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
"/home/agent/post_event.json",
|
||||
JSON.stringify({ event: "post" })
|
||||
@@ -62,12 +70,14 @@ import path from "path";
|
||||
});
|
||||
}
|
||||
|
||||
// Always log the service log
|
||||
var journalLog = cp.execSync("sudo journalctl -u agent.service", {
|
||||
encoding: "utf8",
|
||||
});
|
||||
console.log("Service log:");
|
||||
console.log(journalLog);
|
||||
var disable_sudo = core.getBooleanInput("disable-sudo");
|
||||
if (!disable_sudo) {
|
||||
var journalLog = cp.execSync("sudo journalctl -u agent.service", {
|
||||
encoding: "utf8",
|
||||
});
|
||||
console.log("Service log:");
|
||||
console.log(journalLog);
|
||||
}
|
||||
|
||||
if (isValidEvent()) {
|
||||
try {
|
||||
@@ -80,6 +90,12 @@ import path from "path";
|
||||
console.log(exception);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await common.addSummary();
|
||||
} catch (exception) {
|
||||
console.log(exception);
|
||||
}
|
||||
})();
|
||||
|
||||
function sleep(ms) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { addSummary } from "./common";
|
||||
import * as cp from "child_process";
|
||||
|
||||
test("adding stepsecurity summary in github_summary", async () => {
|
||||
let expected = `<hr>
|
||||
<img src="https://github.com/step-security/harden-runner/raw/main/images/banner.png" alt="StepSecurity Harden-Runner" width="200">
|
||||
<a href="https://app.stepsecurity.io/github/step-security/test/actions/runs/12345">View security insights and recommended policy</a>
|
||||
<hr>
|
||||
`;
|
||||
|
||||
const github_summary = "/tmp/github_summary";
|
||||
cp.execSync(`touch ${github_summary}`);
|
||||
|
||||
process.env["STATE_monitorStatusCode"] = "200";
|
||||
process.env["GITHUB_STEP_SUMMARY"] = github_summary;
|
||||
process.env["GITHUB_REPOSITORY"] = "step-security/test";
|
||||
process.env["GITHUB_RUN_ID"] = "12345";
|
||||
|
||||
await addSummary();
|
||||
|
||||
let output = cp.execSync(`cat ${github_summary}`).toString();
|
||||
cp.execSync(`rm ${github_summary}`);
|
||||
|
||||
expect(output).toMatch(expected);
|
||||
|
||||
});
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as core from "@actions/core";
|
||||
export function printInfo(web_url) {
|
||||
console.log(
|
||||
"\x1b[32m%s\x1b[0m",
|
||||
@@ -8,9 +9,31 @@ export function printInfo(web_url) {
|
||||
`${web_url}/github/${process.env["GITHUB_REPOSITORY"]}/actions/runs/${process.env["GITHUB_RUN_ID"]}`
|
||||
);
|
||||
}
|
||||
export async function addSummary() {
|
||||
if (process.env.STATE_monitorStatusCode === "200") {
|
||||
const web_url = "https://app.stepsecurity.io";
|
||||
const insights_url = `${web_url}/github/${process.env["GITHUB_REPOSITORY"]}/actions/runs/${process.env["GITHUB_RUN_ID"]}`;
|
||||
|
||||
await core.summary
|
||||
.addSeparator()
|
||||
.addImage(
|
||||
"https://github.com/step-security/harden-runner/raw/main/images/banner.png",
|
||||
"StepSecurity Harden-Runner",
|
||||
{ width: "200" }
|
||||
)
|
||||
.addLink("View security insights and recommended policy", insights_url)
|
||||
.addSeparator()
|
||||
.write();
|
||||
}
|
||||
}
|
||||
|
||||
export const STATUS_HARDEN_RUNNER_UNAVAILABLE = "409";
|
||||
|
||||
export const CONTAINER_MESSAGE =
|
||||
"This job is running in a container. Harden Runner does not run in a container as it needs sudo access to run. This job will not be monitored.";
|
||||
|
||||
export 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.";
|
||||
|
||||
export const HARDEN_RUNNER_UNAVAILABLE_MESSAGE =
|
||||
"Sorry, we are currently experiencing issues with the Harden Runner installation process. It is currently unavailable.";
|
||||
|
||||
@@ -12,6 +12,14 @@ import isDocker from "is-docker";
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
String(process.env.STATE_monitorStatusCode) ===
|
||||
common.STATUS_HARDEN_RUNNER_UNAVAILABLE
|
||||
) {
|
||||
console.log(common.HARDEN_RUNNER_UNAVAILABLE_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
core.getBooleanInput("disable-telemetry") &&
|
||||
core.getInput("egress-policy") === "block"
|
||||
|
||||
@@ -8,6 +8,8 @@ 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";
|
||||
import {
|
||||
cacheFile,
|
||||
cacheKey,
|
||||
@@ -32,8 +34,6 @@ import {
|
||||
var api_url = `https://${env}.api.stepsecurity.io/v1`;
|
||||
var web_url = "https://app.stepsecurity.io";
|
||||
|
||||
console.log(`Step Security Job Correlation ID: ${correlation_id}`);
|
||||
|
||||
const confg = {
|
||||
repo: process.env["GITHUB_REPOSITORY"],
|
||||
run_id: process.env["GITHUB_RUN_ID"],
|
||||
@@ -43,8 +43,51 @@ import {
|
||||
allowed_endpoints: core.getInput("allowed-endpoints"),
|
||||
egress_policy: core.getInput("egress-policy"),
|
||||
disable_telemetry: core.getBooleanInput("disable-telemetry"),
|
||||
disable_sudo: core.getBooleanInput("disable-sudo"),
|
||||
disable_file_monitoring: core.getBooleanInput("disable-file-monitoring"),
|
||||
private: context.payload.repository.private,
|
||||
};
|
||||
|
||||
if (confg.egress_policy !== "audit" && confg.egress_policy !== "block") {
|
||||
core.setFailed("egress-policy must be either audit or block");
|
||||
}
|
||||
|
||||
if (confg.egress_policy === "block" && confg.allowed_endpoints === "") {
|
||||
core.warning(
|
||||
"egress-policy is set to block (default) and allowed-endpoints is empty. No outbound traffic will be allowed for job steps."
|
||||
);
|
||||
}
|
||||
|
||||
if (confg.disable_telemetry !== true && confg.disable_telemetry !== false) {
|
||||
core.setFailed("disable-telemetry must be a boolean value");
|
||||
}
|
||||
|
||||
let _http = new httpm.HttpClient();
|
||||
let statusCode;
|
||||
_http.requestOptions = { socketTimeout: 3 * 1000 };
|
||||
try {
|
||||
const resp: httpm.HttpClientResponse = await _http.get(
|
||||
`${api_url}/github/${process.env["GITHUB_REPOSITORY"]}/actions/runs/${process.env["GITHUB_RUN_ID"]}/monitor`
|
||||
);
|
||||
statusCode = resp.message.statusCode; // adding error code to check whether agent is getting installed or not.
|
||||
fs.appendFileSync(
|
||||
process.env.GITHUB_STATE,
|
||||
`monitorStatusCode=${statusCode}${EOL}`,
|
||||
{
|
||||
encoding: "utf8",
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(`error in connecting to ${api_url}: ${e}`);
|
||||
}
|
||||
|
||||
console.log(`Step Security Job Correlation ID: ${correlation_id}`);
|
||||
|
||||
if (String(statusCode) === common.STATUS_HARDEN_RUNNER_UNAVAILABLE) {
|
||||
console.log(common.HARDEN_RUNNER_UNAVAILABLE_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isValidEvent()) {
|
||||
try {
|
||||
const cacheEntry = await getCacheEntry([cacheKey], [cacheFile], {
|
||||
@@ -63,32 +106,6 @@ import {
|
||||
}
|
||||
}
|
||||
|
||||
if (confg.egress_policy !== "audit" && confg.egress_policy !== "block") {
|
||||
core.setFailed("egress-policy must be either audit or block");
|
||||
}
|
||||
|
||||
if (confg.egress_policy === "block" && confg.allowed_endpoints === "") {
|
||||
core.warning(
|
||||
"egress-policy is set to block (default) and allowed-endpoints is empty. No outbound traffic will be allowed for job steps."
|
||||
);
|
||||
}
|
||||
|
||||
if (confg.disable_telemetry !== true && confg.disable_telemetry !== false) {
|
||||
core.setFailed("disable-telemetry must be a boolean value");
|
||||
}
|
||||
|
||||
if (!confg.disable_telemetry) {
|
||||
let _http = new httpm.HttpClient();
|
||||
_http.requestOptions = { socketTimeout: 3 * 1000 };
|
||||
try {
|
||||
await _http.get(
|
||||
`${api_url}/github/${process.env["GITHUB_REPOSITORY"]}/actions/runs/${process.env["GITHUB_RUN_ID"]}/monitor`
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(`error in connecting to ${api_url}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
const confgStr = JSON.stringify(confg);
|
||||
cp.execSync("sudo mkdir -p /home/agent");
|
||||
cp.execSync("sudo chown -R $USER /home/agent");
|
||||
@@ -98,7 +115,7 @@ import {
|
||||
let auth = `token ${token}`;
|
||||
|
||||
const downloadPath: string = await tc.downloadTool(
|
||||
"https://github.com/step-security/agent/releases/download/v0.11.0/agent_0.11.0_linux_amd64.tar.gz",
|
||||
"https://github.com/step-security/agent/releases/download/v0.12.2/agent_0.12.2_linux_amd64.tar.gz",
|
||||
undefined,
|
||||
auth
|
||||
);
|
||||
|
||||