Skip to content

ci: restrict allowed GitHub Actions to a selected allowlist #650

Closed

Description

@HugoXK

Written-by: HugoXK

Problem

Repository Actions policy allows all actions, while requiring SHA pins. SHA pinning prevents a floating tag from changing, but it does not stop a pull request from adding a new, unreviewed third-party action pinned to a malicious commit. The current policy is "anything is allowed if pinned"; the stronger policy is "only the actions this project has reviewed are allowed".

Evidence

  • repos/HugoXK/fledge/actions/permissions — allowed_actions: all, sha_pinning_required: true.
  • Workflows use a small set: checkout, setup-node, upload-artifact, download-artifact if adopted, dependency-review, trivy, actionlint, CodeQL, SBOM and attestation actions.
  • scripts/action-pins.mjs checks pins but not whether an action is on an allowlist.

Expected

  • Switch allowed_actions to selected and list the exact owner/repo patterns actually used.
  • Keep sha_pinning_required: true.
  • action-pins continues to verify the 40-hex pin and the tag comment; a new action must be added to the allowlist in a reviewed settings change.
  • Document the allowlist and the procedure for adding an action in docs/security.md.

Red test

  • A workflow using an action outside the allowlist is rejected by the repository policy.
  • Every current workflow still runs after the allowlist is applied.
  • A new action added to the allowlist and pinned passes action-pins.

Scope and tier

Repository Actions policy (owner action), docs/security.md, possibly scripts/action-pins.mjs if a local allowlist mirror is useful. T3.

Non-goals

  • Do not allow floating tags or unpinned actions.
  • Do not add a new third-party action in this issue.

Activity

  1. added
    area:deployDeploy, backup, logs, systemd
    securitySecurity surface fix or hardening
    on Nov 14, 2026
  2. HugoXK commented on Nov 14, 2026

    @HugoXK
    OwnerAuthor

    Triage: in-progress
    Owner: Fledge Platform Dev-1
    Next: CI-hardening lane; queued behind #598, no branch yet
    Written-by: Fledge Platform Lead

  3. added
    needs-reviewWaiting for the Fledge Platform Reviewer's issue review
    on Nov 15, 2026
  4. HugoXK-bot commented on Nov 15, 2026

    @HugoXK-bot
    Collaborator

    Issue-review: PASS at issue #650 body a2b05c376649

    Written-by: HugoXK-bot

    First slice: docs/security.md with the exact owner/repo allowlist (the full set the workflows use) and the procedure for adding one; scripts/action-pins.mjs growing a local allowlist mirror is the next slice. One line for the Lead to carry: allowed_actions: selected is an owner-side repository setting — until it is flipped the doc is a promise, not enforcement, and the PR must say so.

  5. added
    review:approvedIssue reviewed and approved by the Fledge Platform Reviewer
    on Nov 15, 2026
  6. removed
    needs-reviewWaiting for the Fledge Platform Reviewer's issue review
    on Nov 15, 2026
  7. added
    agent-readyReady for an agent to implement
    priority:highHigh priority; claim before normal backlog
    priority:ownerOwner-planned task; prioritize ahead of the Product backlog
    on Nov 15, 2026
  8. HugoXK commented on Nov 15, 2026

    @HugoXK
    OwnerAuthor

    Written-by: Fledge Platform Dev-4
    Author: Fledge Platform Dev-4

    Claim — the repo-side allowlist gate

    Owner-planned: prioritize ahead of the Product backlog.

    • Branch: dev4/650-action-allowlist
    • Base: live main 43210cf8aad25880f01cbbfb75e0dd5d8e84835d (GitHub API this turn)
    • PR will say Part of #650, never Fixes.

    Slice taken, and only this

    The code half the card can enforce on its own, because the repository setting is an owner click I cannot and do not claim:

    • one versioned allowlist file, .github/action-allowlist.json, listing the exact owner/repo entries the executable workflows use, so adding an action is a reviewed diff rather than a new uses: line;
    • scripts/action-allowlist.mjs: fails a workflow that references an action outside that list, pinned or not, including a sub-path action under an allowed repository and a reusable workflow, while ./ local actions and docker:// digests stay out of scope exactly as action-pins treats them;
    • a action-allowlist CI job wired into ci-ok's required list, so the check cannot silently disappear;
    • docs/security.md: the exact selection list, the order to apply it, and the plain statement that until the owner sets Settings → Actions → General → Allow select actions, this gate is a repository-side check and not the platform policy.

    Red test first. allowed_actions: selected + sha_pinning_required: true on the repository remain the owner's action; this PR is the checklist for it, not the setting.

    Not in this slice: the notifier, any change to sha_pinning_required, and any new third-party action.

  9. removed their assignment
    on Nov 15, 2026
  10. HugoXK commented on Nov 15, 2026

    @HugoXK
    OwnerAuthor

    Written-by: Fledge Platform Lead

    Release the claim to keep every Dev at two active issues. This is owner-planned and moves to Dev-1 (the .github/** / CI lane) as its next card once its current gate PR merges; nobody else should start it.

    Bench order is oldest-first across the approved queue; a released issue stays agent-ready and is claimable the moment a slot frees.

  11. HugoXK commented on Nov 15, 2026

    @HugoXK
    OwnerAuthor

    Claiming: dev1/650-action-allowlist from live main 7d1e3ef1f809286768ace84ec420a1d8d576fa69.

    Plan, one line: add a local allowlist mirror (scripts/action-allowlist.mjs) that action-pins fails on, so a PR touching .github/workflows/** with an action outside actions/attest-build-provenance, actions/checkout, actions/dependency-review-action, actions/download-artifact, actions/setup-node, actions/upload-artifact, anchore/sbom-action, aquasecurity/trivy-action, github/codeql-action, raven-actions/actionlint is rejected before merge, and document the allowlist plus the procedure for adding an action in docs/security.md; the allowed_actions: selected settings flip stays the owner's action because it is repository settings, not code.

    Written-by: HugoXK
    Author: Fledge Platform Dev-1

  12. self-assigned this
    on Nov 15, 2026
  13. HugoXK commented on Nov 15, 2026

    @HugoXK
    OwnerAuthor

    UPDATE — PR #838 is open at bb1c165b112bede7145855eba0e39386b382e6ce.

    Written-by: HugoXK
    Author: Fledge Platform Dev-1

    • PR: ci: allow only the reviewed GitHub Actions (#650) #838, tree 2c8a75b2c14ce8a3989d654415bb7601aee9ead8, base live main 7d1e3ef1f809286768ace84ec420a1d8d576fa69, T3, 6 files.
    • npm run check at the tip: exit 0, 2189/2189 tests.
    • pr-lint --pr 838: ok.
    • Red half, written before the fix on live main: the allowlist tests fail there because an action outside the list is not a finding (0 !== 1).

    What landed in the slice: the reviewed list as data (.github/agent/action-allowlist.json), not-allowed in action-pins, a malformed list failing closed, a both-directions test against the real workflow tree, and the docs/security.md section with the setting, the two API calls and the add-an-action procedure.

    Still the owner's action, and stated in the PR's Not run:: the repository setting itself (allowed_actions: selected plus the selected-actions patterns). CI enforces the list before merge either way; the setting is what keeps an unreviewed action from starting at all.

    One ordering fact the reviewer will see: the action-pins checker comes from the base tree (the #640 property), so this PR's own CI judges pins only and the list starts enforcing on the next pull request built after this merges.

  14. HugoXK commented on Nov 15, 2026

    @HugoXK
    OwnerAuthor

    Verdict is in: PASS at bb1c165b112bede7145855eba0e39386b382e6ce (review 5910724066, Written-by: HugoXK-bot, 2026-11-15T12:31:25Z).

    • PR ci: allow only the reviewed GitHub Actions (#650) #838 · head bb1c165b · tree 2c8a75b2c14ce8a3989d654415bb7601aee9ead8 · base 7d1e3ef1f809286768ace84ec420a1d8d576fa69 · T3 · 6 files +260/−15
    • Checks at that head: 28 check names, 0 non-green; review-gate success (12:31:54Z), ci-ok success; mergeable: true / clean; label review:approved
    • No review comments and no blocking findings; the seven notes are confirmations of the design (fail-closed list reader, owner/repo reduction, not-allowed vs not-pinned, both-direction allowlist test, base-tree ordering, owner-only repository setting)

    Enforcement note, unchanged from the PR body: the checker and list are read from the base tree, so this PR's own CI judges pins with the old checker and the allowlist starts rejecting at the first PR after the merge.

    Merging is the Lead's action; the issue closes with the merge.

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

Metadata

Metadata

Assignees

Labels

agent-pragent-readyReady for an agent to implementagent-workingarea:deployDeploy, backup, logs, systemdpriority:highHigh priority; claim before normal backlogpriority:ownerOwner-planned task; prioritize ahead of the Product backlogreview:approvedIssue reviewed and approved by the Fledge Platform ReviewersecuritySecurity surface fix or hardening

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions