Skip to content
Merged
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: 21 additions & 9 deletions .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ on:
type: string
required: false
default: ""
runner:
description: >-
Label(s) the scan jobs run on. Defaults to GitHub-hosted
`ubuntu-latest`; set to a self-hosted label (e.g. `self-hosted`)
to run on an org/repo self-hosted runner instead — useful when
GitHub-hosted minutes are exhausted. A single label string;
callers typically wire this to a repo variable so it can be
toggled without editing the workflow. Mirrors node-ci.yml's
`runner` input.
type: string
required: false
default: "ubuntu-latest"
Comment on lines +82 to +93

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file exists and relevant lines =="
cat -n .github/workflows/security-scan.yml | sed -n '1,140p'

echo
echo "== runner input occurrences =="
rg -n "inputs\.runner|runner:|container:" .github/workflows/security-scan.yml

echo
echo "== workflow files with self-hosted runner examples in workflows =="
rg -n "self-hosted|runner:|container:" .github/workflows -g '*.yml' -g '*.yaml' || true

Repository: resq-software/.github

Length of output: 7807


🌐 Web query:

GitHub Actions job container self-hosted runner Docker Linux runtime requirements

💡 Result:

To use job containers or service containers with a self-hosted GitHub Actions runner, your infrastructure must meet specific requirements primarily focused on Linux and Docker support [1][2]. Requirements: - Operating System: You must use a Linux machine [1][2]. Job containers and service containers are not supported on self-hosted runners running Windows or macOS [3]. - Docker Engine: Docker must be installed and the Docker daemon must be running [1][2]. - Docker Access: The runner user must have permission to access the Docker daemon, typically by being a member of the docker group, or by ensuring the Docker socket (e.g., /var/run/docker.sock) is accessible [3]. - Connectivity: The host machine must be able to communicate with GitHub Actions over HTTPS (typically via port 443) [1]. Additional Context: - Limitations: Docker Hub rate limits apply to self-hosted runners, unlike GitHub-hosted runners which have an agreement with Docker to avoid these limits [4]. - Customization: On Linux, GitHub Actions allows for advanced customization of container creation (e.g., using Podman or Kubernetes) via a customization script triggered by environment variables on the runner [5]. - Workflow Configuration: When using a container for a job, you define the image in your workflow file under the jobs.<job_id>.container key [4][6]. If this is not set, steps run directly on the host machine unless they specifically call an action configured to run in a container [4]. If you are using Actions Runner Controller (ARC) on Kubernetes, "Docker-in-Docker" (DinD) mode is typically required, where the runner container shares the Docker socket with a sidecar [3].

Citations:


Constrain runner to Linux/Docker-capable labels.

The documented single-label self-hosted value does not guarantee a Linux Docker runtime, but semgrep runs with a job-level container. This can fail to schedule or be intentionally unsafe if routed to Windows/macOS/Linux without Docker; use Linux/Docker-specific labels or allow multiple labels/groups in the input contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/security-scan.yml around lines 82 - 93, Update the runner
input contract and its description in the workflow’s runner configuration to
require Linux/Docker-capable labels, or explicitly support multiple
labels/groups so scheduling targets compatible self-hosted runners. Preserve the
ubuntu-latest default while removing the unsafe implication that a generic
single self-hosted label is sufficient.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow files =="
git ls-files .github/workflows || true

echo "== security-scan workflow excerpt =="
if [ -f .github/workflows/security-scan.yml ]; then
  nl -ba .github/workflows/security-scan.yml | sed -n '1,140p'
fi

echo "== workflow calls/inputs references =="
rg -n "uses:.*/security-scan|security-scan|self-hosted|runner:|secrets: inherit|pull_request|security-scan.yml|node-ci" .github/workflows -S || true

echo "== git diff stat/name =="
git diff --stat HEAD~1..HEAD 2>/dev/null || git diff --stat 2>/dev/null || true

Repository: resq-software/.github

Length of output: 656


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== all workflow files =="
git ls-files .github/workflows || true

echo "== security-scan workflow excerpt =="
if [ -f .github/workflows/security-scan.yml ]; then
  awk '{printf "%6d  %s\n", NR, $0}' .github/workflows/security-scan.yml | sed -n '1,180p'
fi

echo "== runner/secrets/pull_request references =="
rg -n "uses:.*/security-scan|security-scan|self-hosted|runner:|secrets: inherit|pull_request|security-scan.yml|node-ci|pull_request|pull_request_target|trusted" .github/workflows -S || true

echo "== git diff stat/name =="
if git rev-parse HEAD~1 >/dev/null 2>&1; then
  git diff --stat HEAD~1..HEAD
else
  git diff --stat 2>/dev/null || true
fi

Repository: resq-software/.github

Length of output: 13529


Gate self-hosted runners for PR-based security scans.

The reusable runner input defaults to GitHub-hosted but allows self-hosted labels in callers; one documented caller forwards all secrets with secrets: inherit, and other callers use secrets: inherit for their required checks. Restrict self-hosted usage for pull_request/fork scenarios to trusted/private PR sources or protected runner groups, and avoid inheriting secrets on non-ephemeral runners unless the repository and PR context are trusted. Audit-only runner hardening does not contain a compromised runner.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/security-scan.yml around lines 82 - 93, Update the
reusable workflow’s runner selection around the runner input to prevent
pull_request and fork scans from using arbitrary self-hosted labels. Allow
self-hosted runners only for trusted/private PR contexts or explicitly protected
runner groups, while retaining ubuntu-latest as the default. Review callers
using secrets: inherit and avoid passing secrets when execution targets a
non-ephemeral runner unless the repository and PR context are trusted.


# Declared so callers can forward these by name instead of `secrets:
# inherit` (which hands this workflow ALL of the caller's secrets and
Expand Down Expand Up @@ -115,7 +127,7 @@ jobs:
vet:
name: vet (OSS dependency policy)
if: ${{ inputs.enable-vet }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
permissions:
contents: read
# NOTE: write perms (pull-requests/issues) are intentionally omitted.
Expand Down Expand Up @@ -152,7 +164,7 @@ jobs:
codeql:
name: CodeQL (${{ matrix.language }})
if: ${{ inputs.languages != '' && inputs.languages != '[]' }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
permissions:
contents: read
security-events: write
Expand Down Expand Up @@ -190,7 +202,7 @@ jobs:
gitleaks:
name: gitleaks
if: ${{ inputs.enable-gitleaks }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2
Expand All @@ -208,7 +220,7 @@ jobs:
osv-scanner:
name: osv-scanner
if: ${{ inputs.enable-osv }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2
Expand Down Expand Up @@ -237,7 +249,7 @@ jobs:
dependency-review:
name: dependency-review
if: ${{ inputs.enable-dependency-review && github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2
Expand All @@ -253,7 +265,7 @@ jobs:
zizmor:
name: zizmor
if: ${{ inputs.enable-zizmor }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
permissions:
contents: read
security-events: write
Expand Down Expand Up @@ -289,7 +301,7 @@ jobs:
actionlint:
name: actionlint
if: ${{ inputs.enable-actionlint }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2
Expand All @@ -308,7 +320,7 @@ jobs:
semgrep:
name: semgrep
if: ${{ inputs.enable-semgrep }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
container:
image: semgrep/semgrep
steps:
Expand All @@ -326,7 +338,7 @@ jobs:
snyk:
name: snyk
if: ${{ inputs.enable-snyk }}
runs-on: ubuntu-latest
runs-on: ${{ inputs.runner }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2
Expand Down
Loading