Skip to content

fix(pr-pipeline): hold an unpinned uses: a composite action gains #10771

Open

Description

@kyle-sexton

Problem

The merge gate's workflow checks in babysit_risk.py read only .github/workflows/*.yml and *.yaml (_WORKFLOWS, is_workflow_path; plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:807 and :928 on #10743's head). A composite action outside that directory, such as .github/actions/<name>/action.yml, can gain a uses: of a third-party action at an unpinned ref (@main, @v1), a new secret input, or a model leg. No base-against-head check reads it, so the change is held only if its path is on the floor or a review finds it. The same gap applies to secret-exposure-review, agent-surface-review, permission-widening-review and privileged-trigger-review, which read workflow paths only.

The independent security review of #10743 found this. It was pre-existing and left out of that PR's scope.

Evidence

  • _WORKFLOWS = (".github/workflows/*.yml", ".github/workflows/*.yaml"), which _cost_reasons uses to decide whether a file gets the workflow checks.
  • runner-policy and zizmor run in CI over composite actions, but neither feeds the merge gate's person holds.

Proposed fix

Treat .github/actions/**/action.y{,a}ml as workflow text for the net-added uses: checks. Hold for a person when an added uses: is not pinned to a 40-character SHA, and apply the existing secret and model-leg gains there too.

Refs: #10743

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 28, 2026
  2. github-actions commented on Oct 28, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Medium
    Complexity: Medium
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Understood: the babysit merge gate's workflow checks (babysit_risk.py) read only .github/workflows/*.y{,a}ml, so a composite action under .github/actions/**/action.y{,a}ml can gain an unpinned uses:, a new secret input or a model leg without a person hold. The proposal is to treat those action files as workflow text for the net-added uses: check (hold unless pinned to a 40-character SHA) and for the existing secret and model-leg checks, and to cover the four sibling review checks too. The scope and approach are clear from the issue. I found no duplicate among the open issues.

    Automated triage, applied by the lanes App.

  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 28, 2026
  4. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Oct 28, 2026
  5. melodic-automation-lanes commented on Oct 28, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane: no trusted-human acceptance criteria: a listed human must put the confirmed - [ ] criteria in the body or post them as their own comment, or, on an issue a listed human filed, intake's newest refinement comment must hold them unedited. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).

  6. melodic-automation-lanes commented on Oct 28, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: admission moved the issue to status: confirmed; its comment says why.

  7. melodic-automation-lanes commented on Oct 28, 2026

    @melodic-automation-lanes
    Contributor

    Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.

    Intended outcome: Composite action files under .github/actions/**/action.y{,a}ml get the same net-added uses:, secret and model-leg checks as workflow files, and an added uses: not pinned to a 40-character SHA holds for a person.

    Related work

    Open questions

    1. Should this wait for #​10743 to merge? The base checkout has no unpinned-uses check and no permission-widening-review or privileged-trigger-review codes in babysit_risk.py, so those checks must come from #​10743.
      RECOMMENDED: Yes. Make #​10743 a dependency and implement against its merged code, adding the action globs to the shared workflow-path predicate. Basis: plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:749
    2. Which checks are in scope? The body names the unpinned uses:, secret and model-leg checks, and also says the permission-widening and privileged-trigger reviews read workflow paths only.
      RECOMMENDED: Cover the unpinned uses:, secret and model-leg checks. Include permission-widening and privileged-trigger only if they exist after #​10743, and only where the key is meaningful in a composite action. Basis: judgment
    3. Should the cost-only checks (runs-on, cron, timeouts, retention, new runners) also apply to action files, or stay workflow-only?
      RECOMMENDED: Keep them workflow-only. Composite actions have no runs-on, cron or job timeouts, and _cost_reasons at babysit_risk.py:1007 and :1025 applies all of them under one workflow flag, so the change must split that flag. Basis: plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:1025

    Sources read

    • plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:760: _WORKFLOWS is only .github/workflows/*.yml and *.yaml
    • plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:881: is_workflow_path matches only _WORKFLOWS
    • plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:1007: _cost_reasons gates secret and model-leg checks on is_workflow_path
    • plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:935: _net_added helper compares matches gained over removed lines
    • plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:749: only secret-exposure-review and agent-surface-review codes exist in the base

    To answer, post a comment that starts with this line:

    **Decision recorded.** <answer>
    

    Automated refinement by the lanes App. Answer with a comment whose first line is **Decision recorded.**.

  8. changed the title [-]fix(pr-pipeline): hold an unpinned uses: a composite action gains[/-] [+]fix(pr-pipeline): hold an unpinned uses: a composite action gains (hardening deferred)[/+] on Oct 30, 2026
  9. kyle-sexton commented on Oct 30, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded. Hardening deferred, closed as not planned under owner standing direction §10: "Phase: maximum throughput until open issues and open PRs both reach 0. Hardening (re-adding holds, pins, reviews) is deferred to after that, as configuration edits."

    This issue adds a hold, a pin or a check that guards against our own actors, and none of its gaps can leak a token or secret, compromise the owner accounts or bill. §10 counts only those as a §3 boundary. Secret-leak scanning (gitleaks) stays on, as do both review lanes and ci-status (owner Q15).

    Reopen trigger: open issues = 0 and open PRs = 0. The hardening pass finds this with is:issue is:closed reason:"not planned" in:title "hardening deferred".

  10. kyle-sexton commented on Oct 31, 2026

    @kyle-sexton
    MemberAuthor

    Reopening into the After zero milestone. Remaining value: correct this hold before holds return. Owner decision Q15 keeps path holds off, so this is tracked, not built now. Closed as deferred; the owner rule of 2026-10-31 keeps work with value open and cordoned.

  11. added this to the After zero milestone on Oct 31, 2026
  12. changed the title [-]fix(pr-pipeline): hold an unpinned uses: a composite action gains (hardening deferred)[/-] [+]fix(pr-pipeline): hold an unpinned uses: a composite action gains[/+] on Oct 31, 2026
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

    priority: mediumReal value, no hard deadline; normal backlog flow.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions