ci: add Checkov baseline (warning-only) — Phase A (#549)

Introduce Checkov IaC/container/Actions scanning in non-blocking (Phase A) mode per the DevSecOps Guardrails epic. - Add Checkov workflow (.github/workflows/checkov.yml) pinned to checkov 3.2.533, scanning github_actions/dockerfile/secrets frameworks with --soft-fail and continue-on-error so it never fails the build. Uploads SARIF to Code Scanning and as an artifact. - Document the baseline (github_actions: 540 passed / 4 failed CKV_GHA_7; 0 CRITICAL/HIGH) and local usage in docs/devsecops/checkov-baseline.md. No findings are fixed (Phase B) or enforced (Phase C) in this change. Closes #541 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Juan Manuel Servera committed Jun 26, 2026 at 23:47 UTC 01f03fbe2e93efd8e7e042c9374d8cd269cfd588
2 files changed +151
.github/workflows/checkov.yml new
+87
@@ -0,0 +1,87 @@
1 +# Checkov lint — Phase A (warning-only / non-blocking)
2 +#
3 +# DevSecOps Guardrails epic (jmservera/SquadScope-Coordinator#33), issue #541.
4 +# Scans IaC, containers and GitHub Actions workflows for misconfigurations.
5 +# Phase A is NON-BLOCKING: the job uses --soft-fail and continue-on-error, and
6 +# uploads SARIF to Code Scanning for visibility. Findings are not fixed
7 +# (Phase B) nor enforced (Phase C) here.
8 +
9 +name: Checkov
10 +
11 +on:
12 + push:
13 + branches:
14 + - main
15 + pull_request:
16 + branches:
17 + - main
18 +
19 +permissions:
20 + contents: read
21 +
22 +concurrency:
23 + group: ${{ github.workflow }}-${{ github.ref }}
24 + cancel-in-progress: true
25 +
26 +jobs:
27 + checkov:
28 + name: Checkov IaC/container scan (warning-only)
29 + runs-on: ubuntu-latest
30 + # Phase A: non-blocking. Report only — never fail the build.
31 + continue-on-error: true
32 + permissions:
33 + contents: read
34 + security-events: write
35 + steps:
36 + - name: Checkout code
37 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
38 + with:
39 + persist-credentials: false
40 +
41 + - name: Set up Python
42 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
43 + with:
44 + python-version: "3.12"
45 +
46 + - name: Install Checkov (pinned)
47 + run: python -m pip install checkov==3.2.533
48 +
49 + - name: Run Checkov (soft-fail, SARIF)
50 + run: |
51 + checkov \
52 + --directory . \
53 + --framework github_actions dockerfile secrets \
54 + --skip-path node_modules \
55 + --skip-path .venv \
56 + --skip-path public \
57 + --skip-path resources \
58 + --skip-path themes \
59 + --compact \
60 + --soft-fail \
61 + --output cli \
62 + --output sarif \
63 + --output-file-path console,checkov-results.sarif
64 +
65 + - name: Checkov baseline summary
66 + if: always()
67 + run: |
68 + {
69 + echo "### Checkov baseline (warning-only)"
70 + echo ""
71 + echo "See the job log for the full report. Findings are non-blocking in Phase A."
72 + } >> "$GITHUB_STEP_SUMMARY"
73 +
74 + - name: Upload SARIF to GitHub Code Scanning
75 + if: always()
76 + uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
77 + with:
78 + sarif_file: checkov-results.sarif
79 + category: checkov
80 +
81 + - name: Upload SARIF as artifact
82 + if: always()
83 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
84 + with:
85 + name: checkov-sarif
86 + path: checkov-results.sarif
87 + retention-days: 30
docs/devsecops/checkov-baseline.md new
+64
@@ -0,0 +1,64 @@
1 +# Checkov Baseline (Phase A — warning-only)
2 +
3 +> Issue: jmservera/SquadScope#541 · Epic: jmservera/SquadScope-Coordinator#33
4 +> Mode: **warning-only / non-blocking** (`--soft-fail`). Do not fix (Phase B) or enforce (Phase C) yet.
5 +
6 +Checkov scans IaC, container, and GitHub Actions configuration for
7 +misconfigurations. SquadScope currently has **no Dockerfiles, Terraform/Bicep,
8 +docker-compose, or k8s manifests** — the only in-scope targets today are the
9 +GitHub Actions workflows under `.github/workflows/`. The CI job is wired to also
10 +cover `dockerfile` and `secrets` frameworks so coverage extends automatically
11 +when container/IaC files are added.
12 +
13 +## CI behaviour
14 +
15 +`.github/workflows/checkov.yml` runs Checkov with `--soft-fail` and
16 +`continue-on-error: true` (non-blocking), uploads SARIF to GitHub Code Scanning,
17 +and attaches the SARIF as a build artifact.
18 +
19 +## Baseline snapshot
20 +
21 +- **Tool:** checkov 3.2.533
22 +- **Date:** 2026-06-26
23 +- **Frameworks:** github_actions, dockerfile, secrets
24 +- **github_actions:** 540 passed, **4 failed**, 0 skipped
25 +- **CRITICAL/HIGH:** 0 (the failing GHA checks carry no CRITICAL/HIGH severity tag)
26 +
27 +### Failing checks (counts by check ID)
28 +
29 +| Count | Check ID | Description |
30 +|------:|----------|-------------|
31 +| 4 | CKV_GHA_7 | `workflow_dispatch` inputs should be empty (build output must not be affected by user parameters) |
32 +
33 +Affected workflows (deferred to Phase B):
34 +
35 +- `.github/workflows/restore-publish-backup.yml`
36 +- `.github/workflows/squad-promote.yml`
37 +- `.github/workflows/trigger-podcast.yml`
38 +- `.github/workflows/podcaster-handoff-smoke.yml`
39 +
40 +> Note: CKV_GHA_7 flags any `workflow_dispatch` with inputs. These workflows use
41 +> inputs intentionally; triage and any suppressions belong to Phase B.
42 +
43 +## Running locally
44 +
45 +```bash
46 +# Install (pinned to match CI)
47 +pip install checkov==3.2.533
48 +
49 +# Scan the whole repo (report only)
50 +checkov --directory . \
51 + --framework github_actions dockerfile secrets \
52 + --skip-path node_modules --skip-path .venv \
53 + --skip-path public --skip-path resources --skip-path themes \
54 + --compact --soft-fail
55 +
56 +# Scan a single file/dir
57 +checkov --file .github/workflows/ci.yml
58 +```
59 +
60 +## Phase plan
61 +
62 +- **Phase A (now):** baseline + non-blocking CI + SARIF upload. ← this PR
63 +- **Phase B:** triage findings; add justified suppressions or fixes.
64 +- **Phase C:** blocking required status check for new misconfigurations.