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`).