83 lines
4.4 KiB
Markdown
83 lines
4.4 KiB
Markdown
---
|
|
phase: 16-ci-dependency-audit-and-security-checks
|
|
plan: "05"
|
|
subsystem: ci
|
|
tags: [gitea-ci, gitleaks, security, pnpm-audit, dependency-audit, gate]
|
|
dependency_graph:
|
|
requires: ["16-02", "16-03", "16-04"]
|
|
provides: ["security job in ci.yml", "gate wired with security check"]
|
|
affects: [".gitea/workflows/ci.yml"]
|
|
tech_stack:
|
|
added: []
|
|
patterns: ["security CI job parallel to fast-checks", "individual needs.X.result check (Gitea #31007)", "base.sha probe with git merge-base fallback"]
|
|
key_files:
|
|
modified:
|
|
- path: .gitea/workflows/ci.yml
|
|
role: CI workflow — security job added; gate aggregator updated
|
|
decisions:
|
|
- "D-12: gitleaks always runs on every PR via unconditional steps (no job-level if:); only pnpm audit/outdated are code-gated at step level"
|
|
- "D-14/D-15: security wired into gate with individual needs.security.result check — must be 'success', not 'success-or-skipped', because gitleaks always runs"
|
|
- "A2/OQ-1: base.sha probe step with git merge-base fallback guards against empty base.sha on some Gitea versions"
|
|
metrics:
|
|
duration: 7
|
|
completed: "2026-06-13T12:23:36Z"
|
|
tasks_completed: 2
|
|
files_modified: 1
|
|
---
|
|
|
|
# Phase 16 Plan 05: CI Security Job — Summary
|
|
|
|
**One-liner:** Dedicated `security` CI job (gitleaks always + audit/outdated code-gated) wired into the `gate` aggregator with an individual `needs.security.result` success check.
|
|
|
|
## What Was Built
|
|
|
|
A new `security` job was added to `.gitea/workflows/ci.yml`, placed between `harness` and `gate` in the file order (runs in parallel with `fast-checks`). The job:
|
|
|
|
- Runs on every PR (`if: github.event_name == 'pull_request'`), `needs: [changes]`
|
|
- Uses `actions/checkout@v4` with `fetch-depth: 0` (Pitfall 3 — base.sha must be locally present)
|
|
- Has a "Probe PR base/head SHA" step that reads `github.event.pull_request.base.sha` and falls back to `git merge-base origin/${{ github.base_ref }} HEAD` if empty (Assumption A2 / OQ-1), exporting `BASE_SHA` and `HEAD_SHA` to `$GITHUB_ENV`
|
|
- Installs gitleaks v8.30.1 from GitHub releases (pinned, no `actions/cache` per D-PROBE-04), then runs `gitleaks git --log-opts="--no-merges ${BASE_SHA}..${HEAD_SHA}" --config .gitleaks.toml --baseline-path scripts/gitleaks-baseline.json --exit-code 1` — both gitleaks steps have **no `if:`** (D-12: blocking on every PR)
|
|
- The pnpm setup-node / corepack / install / check-audit / check-outdated steps each carry `if: needs.changes.outputs.code == 'true'` (step-level, so gitleaks still runs on doc-only PRs)
|
|
|
|
The `gate` aggregator was updated:
|
|
- `needs:` expanded to `[fast-checks, changes, api, harness, security]`
|
|
- An individual `if [ "${{ needs.security.result }}" != "success" ]` check was inserted between the fast-checks check and the api/harness for loop
|
|
- Security is **not** folded into the for loop — it must always succeed (cannot be skipped)
|
|
|
|
## Commits
|
|
|
|
| Hash | Message | Files |
|
|
|------|---------|-------|
|
|
| 61b7586 | ci(16-05): add security job (gitleaks always; audit/outdated code-gated) | .gitea/workflows/ci.yml |
|
|
| f0f7d8a | ci(16-05): wire security job into gate aggregator | .gitea/workflows/ci.yml |
|
|
|
|
## Deviations from Plan
|
|
|
|
None — plan executed exactly as written.
|
|
|
|
The task described a "Probe PR base/head SHA" step as a separate explicit step (per PLAN.md acceptance criteria A2/OQ-1). This matches the PLAN.md requirement and was implemented accordingly. The PATTERNS.md skeleton showed a simpler inline version; the PLAN.md explicitly required the probe step with fallback, so the PLAN.md was authoritative.
|
|
|
|
## Threat Coverage
|
|
|
|
| Threat | Mitigation | Status |
|
|
|--------|-----------|--------|
|
|
| T-16-15 — secret introduced in PR diff | gitleaks runs unconditionally, gate blocks on non-success | Mitigated |
|
|
| T-16-16 — unwaived High/Critical advisory merges to main | check-audit.mjs code-gated, gate blocks | Mitigated |
|
|
| T-16-17 — gitleaks scans nothing (empty range) | fetch-depth:0 + base.sha probe + merge-base fallback | Mitigated |
|
|
| T-16-SC — gitleaks binary substitution | version pinned to 8.30.1 from gitleaks/gitleaks official releases | Accepted residual (no checksum) |
|
|
|
|
## Known Stubs
|
|
|
|
None.
|
|
|
|
## Threat Flags
|
|
|
|
None — this plan adds only CI workflow steps and does not introduce new network endpoints, auth paths, or schema changes.
|
|
|
|
## Self-Check: PASSED
|
|
|
|
- `.gitea/workflows/ci.yml` — FOUND
|
|
- Commit 61b7586 (add security job) — FOUND
|
|
- Commit f0f7d8a (wire gate) — FOUND
|
|
- `16-05-SUMMARY.md` — FOUND
|