docs(16-05): complete security job + gate wiring plan
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
---
|
||||
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
|
||||
Reference in New Issue
Block a user