OpenWriterControle/docs/maintenance/repository-recovery
Darren Hinde 2deecb9fc4
ci(security): validate fork/internal workflow behavior and close gaps (Task 09) (#339)
Evidence-based validation of the hardened workflows (no GitHub test state
created; no branch or worktree created or deleted). All six fork-safety
claims were independently re-derived and CONFIRMED:

- No live pull_request_target trigger (the only match is Task 02's warning
  comment; validate-registry.yml parses to pull_request + workflow_dispatch).
- Fork-reachable surface is exactly 5 workflows, each with top-level
  contents: read and no job-level override.
- Zero secret references in any fork-reachable workflow.
- Every secret-bearing workflow is unreachable from a fork (push /
  workflow_dispatch, or issue_comment gated to OWNER/MEMBER).
- Internal validation: PR #334's failed Build & Validate blocked the PR
  Checks Summary (exit 1); #336's 7 checks all executed and passed.

Gaps found and closed:
- Add persist-credentials: false to the 7 checkouts missing it
  (installer-checks 6, validate-test-suites 1), so all 11 checkouts across
  the fork-reachable surface now avoid persisting the token to .git/config.
- Remove validate-test-suites.yml's failure-path PR comment step. It called
  issues.createComment, which needs issues: write. This was a regression
  introduced by Task 05: the workflow previously had no permissions block
  and inherited the repository's write default, so the step worked; adding
  the correct contents: read broke it. Deleted rather than granting write to
  a fork-reachable workflow — for fork PRs GitHub forces a read-only token,
  so the step could never work there anyway. Failures stay visible via the
  red check and the uploaded report.

Repository setting changed (approved, read-back verified, recorded in the
doc): default_workflow_permissions write -> read and
can_approve_pull_request_reviews true -> false, so future workflows without
an explicit permissions block default to read-only. No current workflow
relied on the write default.
2026-07-15 00:32:03 +01:00
..
action-pin-inventory.md ci(security): phase-1 CI hardening — affected-area tests, least privilege, action pinning, dependency governance (#336) 2026-07-15 00:19:28 +01:00
ci-threat-model-and-baseline.md ci(security): harden pull request validation (#332) 2026-07-14 16:29:20 +01:00
fork-and-internal-workflow-validation.md ci(security): validate fork/internal workflow behavior and close gaps (Task 09) (#339) 2026-07-15 00:32:03 +01:00
private-vulnerability-reporting-checklist.md ci(security): phase-1 CI hardening — affected-area tests, least privilege, action pinning, dependency governance (#336) 2026-07-15 00:19:28 +01:00
private-vulnerability-reporting-evidence.md ci(security): phase-1 CI hardening — affected-area tests, least privilege, action pinning, dependency governance (#336) 2026-07-15 00:19:28 +01:00