Skip to content

[CI Integrity] Run repository gates on exact PR contributor heads #522

Description

@seonghobae

Buyer/control problem

The repository-native Server Tests workflow currently leaves both actions/checkout steps on the default pull_request ref. GitHub documents that an open mergeable pull_request sets GITHUB_REF to refs/pull/<number>/merge and GITHUB_SHA to the synthetic merge commit; actions/checkout therefore checks out that merge ref by default.

Observed ScopeWeave job evidence matches the documented behavior. For PR #521 contributor head 67dd5e70ec6bb273e4d9ff1967a09be0f305cb08, unit-and-api fetched and executed synthetic merge 250b24a31e5be818dfe63d036a12611f0f3723ba. Earlier PR #519 Server Tests did the same with its own synthetic merge. A green result therefore does not prove the unchanged contributor head executed.

This is a commercial CI evidence-integrity defect: review, coverage, security, and merge decisions can otherwise attribute test evidence to a SHA that the job never checked out.

Narrow remediation

  1. In both Server Tests jobs, set checkout ref to the exact PR contributor SHA, falling back to github.sha for the protected develop push path.
  2. Immediately after checkout, compare git rev-parse HEAD with that expected SHA and fail closed on mismatch.
  3. Add a repository regression contract that proves every Server Tests checkout declares the exact-head ref and every job verifies the resulting checkout; register that contract in normal unit CI.
  4. Keep pull_request rather than changing to pull_request_target; do not add secrets, elevated token permissions, merge-ref synthesis, temporary workflows, or gate bypasses.
  5. Record the control rationale and primary GitHub documentation under docs/doctoring/ and CHANGELOG.md.

Verified extension: Dependency Review must satisfy the same revision boundary

Fresh inspection of PR #523 exact head 2304fb64bfeccadf588db52e5d9b4bd2051af3dc found that .github/workflows/dependency-review.yml still violates the intended evidence contract even though Server Tests, Fuzz, CodeQL, and OSV have been hardened.

Current defects are independently reproducible:

  • the Dependency Review checkout has persist-credentials: false but no explicit contributor-head ref, so a normal pull_request run checks out GitHub's synthetic merge ref;
  • the job does not attest git rev-parse HEAD against ${{ github.event.pull_request.head.sha || github.sha }};
  • its comparison probe trusts historical ${{ github.event.pull_request.base.sha }} instead of independently resolving the current protected base branch tip;
  • HTTP 403/404 from the comparison API are converted into supported=false plus exit 0, so an unavailable pull-request dependency gate can become green; and
  • the dependency-review action is not explicitly bound to the independently resolved live base SHA and exact contributor head SHA.

Hosted evidence proves the first point. On PR #500 contributor head 84d0177307573dbdf59ad0f91bf03cd731dee29f, Dependency Review run 32470711048, job 96736697153, fetched and scanned synthetic merge commit 5c1e9b3c..., while the same job environment identified the intended candidate as HEAD_SHA=84d017... and base as BASE_SHA=2c328....

The smallest ScopeWeave-owned repair is to extend the already-registered exact-head workflow contract rather than add a parallel test lane: require exact-head checkout plus runtime SHA attestation, resolve the live named base ref for PR comparisons, fail closed when PR comparison support is unavailable, and pass explicit base-ref/head-ref SHAs to dependency-review. Keep the unprivileged pull_request boundary and do not weaken or delete the gate.

Current governance dependency

An attempted normal repair write to the existing #523 contributor branch was rejected by GitHub with Changes must be made through a pull request, naming inherited central required workflows. Two separate child-branch creation attempts from the unchanged exact #523 head/base were then rejected with Reference update failed, and fresh branch searches proved neither ref existed. Equivalent write retries are therefore not an acceptable repair strategy.

The organization-control owner path is ContextualWisdomLab/.github#1200. It records the live ScopeWeave canary and an independently verified central-audit defect: the central ruleset audit checks that ~DEFAULT_BRANCH is present but does not reject additional unintended ref_name.include targets. The central writer must verify the actual live inherited ruleset scope and repair that owner boundary if needed. ScopeWeave must not bypass or weaken the inherited ruleset; after owner integration, regenerate the exact-head canary and then land the repository-owned Dependency Review repair normally.

Acceptance evidence

  • realistic RED contract fails while the current workflow still has default checkout behavior;
  • after the narrow workflow repair, a new PR run log shows the actual checkout SHA equals the PR contributor head, not refs/pull/<n>/merge;
  • both unit-and-api and cloud-e2e enforce the Server Tests invariant;
  • Dependency Review independently resolves the live protected base, scans the exact contributor head, and fails closed on unavailable PR comparison evidence;
  • protected-develop push still checks out github.sha exactly;
  • no workflow permissions are broadened and persist-credentials: false remains intact;
  • current-head dependency/security gates run normally;
  • a normal non-default proposal branch can again be created/updated through reviewed PR flow after the central owner repair, without weakening protected develop; and
  • protected integration still requires the live independent-review/ruleset gates.

Primary references (APA 7)

GitHub. (n.d.). Events that trigger workflows. GitHub Docs. https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows

GitHub. (n.d.). actions/checkout. GitHub. https://github.com/actions/checkout

GitHub. (n.d.). Reviewing dependency changes in a pull request. GitHub Docs. https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/reviewing-dependency-changes-in-a-pull-request

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: dependenciesDependency or lockfile maintenancearea: securitySecurity boundary, hardening, or vulnerability preventionbugSomething isn't workingenhancementNew feature or requestpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: bugDefect or incorrect behaviortype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions