Skip to content

feat: scan in containers#64

Merged
gilescope merged 6 commits intomainfrom
giles-checkov
Apr 17, 2026
Merged

feat: scan in containers#64
gilescope merged 6 commits intomainfrom
giles-checkov

Conversation

@gilescope
Copy link
Copy Markdown
Contributor

@gilescope gilescope commented Mar 25, 2026

Defence in depth: containerised parallel scanning

After the KICS supply chain compromise and Trivy concerns, this PR fundamentally rearchitects how scanners run — moving from direct runner execution to isolated containers orchestrated by EarthBuild.

What changes

  • Adds Checkov as an IaC scanner (replacing disabled KICS)
  • All three scanners (OpenGrep, Scorecard, Checkov) now run in parallel inside isolated containers
  • action.yml drops from 6 steps to 2: install EarthBuild, run earth +scan

Security improvements

Before After
Scanners run directly on the runner with full access to GITHUB_TOKEN and all env vars Each scanner runs in its own container with zero access to runner secrets
Binaries downloaded and executed on the runner Every binary hash-verified before execution (earthbuild, opengrep, scorecard)
Docker base images referenced by tag All base images pinned by digest
Scanners run as root Scanners run as non-root scanner user
KICS relied on a third-party GitHub Action (compromised) No third-party scanner actions — all tools installed directly
Sequential execution Parallel execution via EarthBuild
N/A New: Checkov's 90+ Python deps locked with SHA256 hashes via --require-hashes

How it works

earth "$ACTION_PATH+scan"
├── +user-source (LOCALLY — captures workspace once)
├── +opengrep    (container — SAST)
├── +scorecard   (container — supply chain)
└── +checkov     (container — IaC misconfig)
    → scan_reports/*.sarif

The +user-source LOCALLY target captures the user's code from the workspace. Each scanner copies it via COPY +user-source/src. Config files (requirements.txt, .checkov.yml, scorecard.jq) come from the action's build context. No files are written to the user's workspace — no conflict with existing Earthfiles.

Other improvements

  • Removed unused github_token input (scorecard --local mode doesn't need it)
  • Removed unused pull-requests: write permission
  • Added .gitignore for scan_reports/
  • Checkov configured with download-external-modules: false and --skip-download
  • All curl calls use --retry 3 --retry-delay 5
  • Multi-arch support (amd64 for CI, arm64 for local dev)
  • earth +checkov-requirements target regenerates the hashed requirements.txt

To update checkov

earth +checkov-requirements  # regenerates requirements.txt with hashes

Test plan

  • earth +scan succeeds locally (arm64)
  • All three SARIF files produced and valid
  • Scanners run as non-root user
  • CI passes on this PR (amd64)

Signed-off-by: Giles Cope <gilescope@gmail.com>
@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Copy link
Copy Markdown
Contributor

@adamreynolds-io adamreynolds-io left a comment

Choose a reason for hiding this comment

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

GO!

Copy link
Copy Markdown
Contributor

@adamreynolds-io adamreynolds-io left a comment

Choose a reason for hiding this comment

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

Security Review

The containerisation approach is a strong security improvement over direct runner execution — good response to the KICS supply chain incident. Hash verification, digest-pinned base images, non-root execution, and secret isolation are all well done.

Verified clean:

  • EarthBuild binary hash matches the v0.8.17 GitHub release asset digest exactly
  • No ${{ }} injection vectors — github.action_path is safe in this context
  • No secrets or tokens passed into scanner containers
  • Checkov hardened with download-external-modules: false and --skip-download
  • requirements.txt is pip-compile generated with 2036 lines of SHA256-hashed deps
  • Renovate comments present for automated updates on all pinned versions

Findings (see inline comments):

  • 1 HIGHpip-tools installed without hash verification in the requirements generation target
  • 3 MEDIUM — workspace capture includes .git/; || true swallows all failures; continue-on-error hides total outages
  • 1 LOW — GPG signature available but unused for EarthBuild binary

Comment thread Earthfile
Comment thread Earthfile
Comment thread Earthfile
Comment thread action.yml
Comment thread action.yml
Copy link
Copy Markdown
Contributor

@adamreynolds-io adamreynolds-io left a comment

Choose a reason for hiding this comment

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

Requesting changes on the items flagged in the inline comments — primarily the unhashed pip-tools install and the inconsistent error handling across scanner targets. See inline comments for details and suggested fixes.

cosmir17 and others added 2 commits March 25, 2026 09:23
Co-authored-by: Adam Reynolds <adam.reynolds@shielded.io>
Signed-off-by: Sean Kwak <sean.kwak@iohk.io>
- Fix broken checkov-requirements target (restore pip-compile, hash-verify pip-tools)
- Replace || true with exit code checks (exit <= 1 is findings, > 1 is error)
- Add .earthlyignore to exclude .git, .env, node_modules from build context
- Add scan output verification step to catch total scanner outages
@cosmir17
Copy link
Copy Markdown
Contributor

Thanks for the thorough review Adam. Giles asked me to help out due to his busy schedule. I've pushed a commit (e37645e) addressing your findings:

  • HIGH (pip-tools): Fixed — pip-tools now installed with --require-hashes using the actual PyPI SHA256 hash. Restored pip-compile and CHECKOV_VERSION ARG that were broken by the earlier suggestion acceptance.
  • MEDIUM (.git/): Added .earthlyignore excluding .git, .env, node_modules, etc.
  • MEDIUM (|| true): Replaced with exit code checks (rc=$?; [ $rc -le 1 ] || exit $rc) on both OpenGrep and Scorecard. Checkov already uses soft-fail: true — all three are now consistent.
  • MEDIUM (continue-on-error): Added "Verify scan output" step that fails if zero SARIF files are produced.
  • LOW (GPG): Left for a follow-up PR.

Signed-off-by: Squirrel <giles.cope@shielded.io>
@gilescope gilescope marked this pull request as ready for review March 30, 2026 17:29
@gilescope gilescope requested review from a team as code owners March 30, 2026 17:29
cosmir17
cosmir17 previously approved these changes Mar 30, 2026
Copy link
Copy Markdown
Contributor

@cosmir17 cosmir17 left a comment

Choose a reason for hiding this comment

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

LGTM from my side.

@adamreynolds-io's security review was thorough and I've addressed his findings in my earlier commit. Deferring to Adam's re-approval before merging (if @gilescope still wants his approval)

Comment thread action.yml Outdated
Copy link
Copy Markdown
Contributor

@adamreynolds-io adamreynolds-io left a comment

Choose a reason for hiding this comment

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

All previous review findings addressed. Security posture is a clear improvement — containerized isolation, hash-verified binaries, non-root execution. The open scorecard_checks passthrough question from @cosmir17 should be resolved before merge (follow-up PR is fine).

Signed-off-by: Giles Cope <gilescope@gmail.com>
@gilescope gilescope dismissed stale reviews from adamreynolds-io and cosmir17 via 31172c0 April 1, 2026 16:31
Comment thread action.yml Fixed
@cosmir17
Copy link
Copy Markdown
Contributor

cosmir17 commented Apr 1, 2026

Waiting on code owner review from midnightntwrk/mn-security and/or midnightntwrk/mn-sre.

My approval is not enough. We need an approval from mn-security or midnightntwrk/mn-sre?

@gilescope gilescope merged commit 47a6b67 into main Apr 17, 2026
6 checks passed
@gilescope gilescope deleted the giles-checkov branch April 17, 2026 10:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants