Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
contents: read
checks: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
Expand All @@ -40,6 +45,11 @@ jobs:
contents: read
security-events: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
Expand All @@ -57,6 +67,11 @@ jobs:
actions: read
security-events: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
Expand All @@ -76,6 +91,11 @@ jobs:
contents: read
pull-requests: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
Expand All @@ -93,6 +113,11 @@ jobs:
permissions:
contents: read
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
Expand All @@ -109,6 +134,11 @@ jobs:
permissions:
contents: read
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
Expand Down
105 changes: 105 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,111 @@ steps:

The action will fail the job if `terramate generate` produces uncommitted output, ensuring generated files are always in sync with the source of truth.

## Consuming repo CI setup

Public and private repos use different subsets of these actions. The key differences are `harden-runner` (sends egress telemetry to StepSecurity — omit on private repos) and `scorecard` (requires public visibility to produce meaningful scores).

### Public repo

```yaml
name: CI
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 6 * * 1'
permissions:
contents: read
jobs:
actionlint:
runs-on: ubuntu-latest
permissions: { contents: read, checks: write }
steps:
- uses: step-security/harden-runner@<SHA>
with: { egress-policy: audit }
- uses: actions/checkout@<SHA>
with: { persist-credentials: false }
- uses: sparkgeo/github-actions/.github/actions/github-actionlint@<SHA>

zizmor:
runs-on: ubuntu-latest
permissions: { contents: read, security-events: write }
steps:
- uses: step-security/harden-runner@<SHA>
with: { egress-policy: audit }
- uses: actions/checkout@<SHA>
with: { persist-credentials: false }
- uses: sparkgeo/github-actions/.github/actions/zizmor@<SHA>

scorecard: # public repos only — checks degrade on private repos
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
permissions: { contents: read, actions: read, security-events: write }
steps:
- uses: step-security/harden-runner@<SHA>
with: { egress-policy: audit }
- uses: actions/checkout@<SHA>
with: { persist-credentials: false }
- uses: sparkgeo/github-actions/.github/actions/scorecard@<SHA>

dependency-review:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions: { contents: read, pull-requests: write }
steps:
- uses: step-security/harden-runner@<SHA>
with: { egress-policy: audit }
- uses: actions/checkout@<SHA>
with: { persist-credentials: false }
- uses: sparkgeo/github-actions/.github/actions/dependency-review@<SHA>
```

### Private repo

Same structure — drop `harden-runner` from every job and drop the `scorecard` job entirely:

```yaml
name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
actionlint:
runs-on: ubuntu-latest
permissions: { contents: read, checks: write }
steps:
# harden-runner omitted — sends egress telemetry to StepSecurity (third party)
- uses: actions/checkout@<SHA>
with: { persist-credentials: false }
- uses: sparkgeo/github-actions/.github/actions/github-actionlint@<SHA>

zizmor:
runs-on: ubuntu-latest
permissions: { contents: read, security-events: write }
# security-events: write requires GitHub Advanced Security on private repos
steps:
- uses: actions/checkout@<SHA>
with: { persist-credentials: false }
- uses: sparkgeo/github-actions/.github/actions/zizmor@<SHA>

# scorecard omitted — most checks require public repo visibility

dependency-review:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions: { contents: read, pull-requests: write }
steps:
- uses: actions/checkout@<SHA>
with: { persist-credentials: false }
- uses: sparkgeo/github-actions/.github/actions/dependency-review@<SHA>
```

See [docs/approved-actions.md](docs/approved-actions.md) for full data handling and telemetry details.

## Security

This repo is part of the Sparkgeo GitHub Actions security programme. The pillars are:
Expand Down
38 changes: 37 additions & 1 deletion docs/approved-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ This is enforced at: **Org Settings → Actions → General → Allow selected a
| `zizmorcore/zizmor-action` | zizmorcore | `5f14fd08` (v0.5.6) | `zizmor` | Zizmor static security analysis; uploads SARIF | 2026-05-21 |
| `opentofu/setup-opentofu` | OpenTofu | `847eaa4a` (v2.0.1) | `terramate-opentofu-setup` | Install OpenTofu CLI | 2026-05-21 |
| `terramate-io/terramate-action` | Terramate | `c5a13758` (v3.0.0) | `terramate-opentofu-setup` | Install Terramate CLI | 2026-05-21 |
| `step-security/harden-runner` | StepSecurity | `9af89fc7` (v2.19.4) | `ci.yml` (all jobs) | Runner egress monitor — audits outbound network calls; baseline for enforce mode | 2026-06-01 |

## Data handling and third-party telemetry

### step-security/harden-runner

`harden-runner` sends network egress telemetry to StepSecurity's platform (app.stepsecurity.io). This is the mechanism that powers the dashboard — it is not a side effect.

**Data sent to StepSecurity:**
- Repository name and organisation
- Workflow run ID, job name, step name
- Outbound connection metadata: destination hostname/IP, port, process name, timestamp

**Data NOT sent:** secrets, environment variables, source code, file contents.

**Implications by repo visibility:**

| Repo type | Risk | Recommendation |
|---|---|---|
| Public | Low — repo name/structure already public | Acceptable; use `egress-policy: audit` to build endpoint allowlist |
| Private | Medium — org name + CI topology exposed to StepSecurity | Review [StepSecurity privacy policy](https://www.stepsecurity.io/privacy) and data processing terms before adopting; if org policy prohibits third-party CI telemetry, omit this action |

There is no mode that suppresses telemetry while keeping the dashboard — if data leaving GitHub is unacceptable, remove `harden-runner` entirely and enforce egress via network-level controls instead.

### Decision: private repo usage

For private repos, the recommendation is to **omit `harden-runner` entirely** from consuming workflows. There is no configuration option that suppresses telemetry while keeping monitoring — the two are inseparable.

Alternatives for private repos that need egress control:

- **GitHub Enterprise Cloud (GHEC) Actions network configurations** — network-layer egress control; data stays within GitHub/Azure infrastructure; requires a GHEC subscription (approximately $21/user/month).
- **Self-hosted runners with firewall rules** — egress data stays in your own infrastructure; trades StepSecurity dependency for additional ops overhead managing the runner fleet.
- **StepSecurity Enterprise (self-hosted backend)** — licensed product where the runner agent connects to your own server rather than app.stepsecurity.io; eliminates third-party data sharing but requires procuring and operating the backend.

For static pre-run security analysis on private repos, **zizmor + actionlint** (already included in this repo) provide workflow security coverage without any outbound egress, and should be considered sufficient for the static analysis layer.

## Security review criteria

Expand Down Expand Up @@ -54,7 +89,7 @@ Before approving a new action, verify all of the following:
"github_owned_allowed": true,
"verified_allowed": false,
"patterns_allowed": [
"ossf/*", "reviewdog/*", "zizmorcore/*", "opentofu/*", "terramate-io/*",
"ossf/*", "reviewdog/*", "zizmorcore/*", "opentofu/*", "terramate-io/*", "step-security/*",
"<new-publisher>/*"
]
}
Expand All @@ -74,6 +109,7 @@ reviewdog/*
zizmorcore/*
opentofu/*
terramate-io/*
step-security/*
```

GitHub-owned actions (`actions/*`, `github/*`) are covered by `github_owned_allowed: true` and do not need explicit patterns.