ci: normalize zizmor to Phase-A warning-only baseline (#550)
Normalize the existing zizmor job to the DevSecOps Guardrails Phase-A contract (warning-only). The job is not recreated. - Annotate zizmor-scan in security-scanning.yml as Phase A: continue-on-error keeps it non-blocking; SARIF upload via advanced-security is confirmed wired. - Document the baseline in docs/devsecops/zizmor-baseline.md: default persona reports 0 actionable findings; pedantic persona records 36 (4 High excessive-permissions) deferred to Phase B, plus local usage instructions. Closes #542 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Juan Manuel Servera committed
Jun 26, 2026 at 23:47 UTC
6f9481ac1846f960f71f58b3abcde5c504ce8d78
2 files changed
+84
.github/workflows/security-scanning.yml
+4
@@ -88,6 +88,10 @@ jobs:
88
contents: read
89
security-events: write
90
actions: read
91
+ # Phase A (DevSecOps Guardrails epic, issue #542): warning-only.
92
+ # continue-on-error keeps zizmor NON-BLOCKING; findings surface as Code
93
+ # Scanning alerts/annotations only. Enforcement is deferred to Phase C.
94
+ # See docs/devsecops/zizmor-baseline.md for the current baseline.
95
continue-on-error: true
96
steps:
97
- name: Checkout repository
docs/devsecops/zizmor-baseline.md
new
+80
@@ -0,0 +1,80 @@
1
+# Zizmor Baseline (Phase A — warning-only)
2
+
3
+> Issue: jmservera/SquadScope#542 · Epic: jmservera/SquadScope-Coordinator#33
4
+> Mode: **warning-only / non-blocking**. Do not fix (Phase B) or enforce (Phase C) yet.
5
+
6
+[zizmor](https://github.com/zizmorcore/zizmor) audits GitHub Actions workflows
7
+for supply-chain risks (template injection, dangerous triggers, unpinned actions,
8
+excessive permissions). It **already exists** in
9
+`.github/workflows/security-scanning.yml` (`zizmorcore/zizmor-action`). This task
10
+normalizes it to the Phase-A contract — it does **not** recreate the job.
11
+
12
+## CI wiring (confirmed)
13
+
14
+- **Job:** `zizmor-scan` in `.github/workflows/security-scanning.yml`.
15
+- **Triggers:** push + pull_request to `main`/`dev` — so it runs on any change to
16
+ `.github/workflows/`.
17
+- **Non-blocking:** `continue-on-error: true` (Phase A warning-only).
18
+- **SARIF / annotations:** `advanced-security: true` uploads SARIF to GitHub Code
19
+ Scanning automatically.
20
+- **Scope:** all repository-owned workflows, excluding generated `squad-*` and
21
+ `sync-squad-labels` files.
22
+
23
+## Baseline snapshot
24
+
25
+- **Tool:** zizmor 1.25.2
26
+- **Date:** 2026-06-26
27
+- **Scope:** repo-owned workflows (Squad-generated files excluded)
28
+
29
+### Default (`regular`) persona — what CI surfaces today
30
+
31
+**0 actionable findings** (7 ignored, 42 suppressed). The Phase-A gate is green
32
+on the default persona; the action focuses on P0 findings (template-injection,
33
+dangerous-triggers), of which there are none.
34
+
35
+### Deep (`pedantic`) persona — full backlog for Phase B
36
+
37
+Total: **36** findings.
38
+
39
+| Count | Rule | Severity |
40
+|------:|------|----------|
41
+| 15 | anonymous-definition | Informational |
42
+| 14 | undocumented-permissions | Low |
43
+| 4 | excessive-permissions | High |
44
+| 3 | concurrency-limits | Low |
45
+
46
+By severity: High 4 · Low 17 · Informational 15.
47
+
48
+> The 4 `excessive-permissions` (High) findings are the priority items for
49
+> Phase B. The remainder are documentation/informational hardening.
50
+
51
+## Running locally
52
+
53
+```bash
54
+# Install (matches the action's toolchain family)
55
+pipx install zizmor # or: pip install zizmor
56
+
57
+# Default persona (what CI reports)
58
+zizmor .github/workflows/
59
+
60
+# Deeper audit used to build the Phase-B backlog
61
+zizmor --persona pedantic .github/workflows/
62
+
63
+# Mirror the CI input set (exclude generated Squad workflows)
64
+zizmor $(find .github/workflows -maxdepth 1 -type f \
65
+ \( -name "*.yml" -o -name "*.yaml" \) \
66
+ ! -name "squad-*.yml" ! -name "sync-squad-labels.yml" | sort)
67
+```
68
+
69
+## Findings deferred to Phase B
70
+
71
+- `excessive-permissions` (High ×4) — tighten job/workflow `permissions:` blocks.
72
+- `undocumented-permissions` (Low ×14) — add explicit minimal permissions.
73
+- `concurrency-limits` (Low ×3) — add `concurrency:` groups where missing.
74
+- `anonymous-definition` (Informational ×15) — name unnamed steps/definitions.
75
+
76
+## Phase plan
77
+
78
+- **Phase A (now):** confirm non-blocking + SARIF wiring; record baseline. ← this PR
79
+- **Phase B:** fix High-severity excessive-permissions, then Low/Informational.
80
+- **Phase C:** blocking enforcement (drop `continue-on-error`).