GitHub announced on July 28, 2026 that GitHub Actions can hold potentially malicious workflow runs for approval before they start. The changelog connects the change to supply-chain attacks in which compromised GitHub credentials are used to push workflows that steal CI/CD credentials or perform additional actions. An approval hold can add an important human checkpoint, but it does not by itself prove that a workflow is safe, that the actor is trusted, or that the repository configuration is correct.
This checklist separates what GitHub documents from what an operator should test using a disposable or low-risk repository. CodeRiskTools did not test GitHub’s hosted control in a customer organization. Do not treat an approval prompt, a successful run, or a workflow log as a security guarantee. Inspect the exact diff, trigger, permissions, referenced actions, secrets boundary, and expected output before allowing a consequential run.
What the approval hold changes
The documented feature changes the starting condition for certain workflow runs: a run that matches GitHub’s risk criteria can wait for approval instead of executing immediately. That delay is useful because it creates time to inspect a newly introduced or suspicious workflow before it receives the permissions available to the job. The precise eligibility rules, repository settings, and user-interface behavior remain GitHub-controlled and can change; read the current changelog and repository documentation rather than relying on a copied screenshot.
The hold is a control-plane checkpoint, not a replacement for workflow design. If a repository grants broad GITHUB_TOKEN permissions, exposes deployment credentials to many jobs, or runs untrusted pull-request content in a privileged context, the approval decision must account for those facts. A reviewer who only reads the workflow name can approve a dangerous change without seeing the real execution boundary.
Map the run before approving it
| Review question | Evidence to capture | Decision use |
|---|---|---|
| What triggered the run? | Event, actor, branch, tag, pull request, schedule, or manual dispatch | Classify whether the input is maintainer-controlled, contributor-controlled, or mixed. |
| What changed? | Exact commit, workflow diff, referenced action revisions, scripts, and reusable workflows | Reject approvals that are detached from the final reviewed revision. |
| What can the job access? | Job-level permissions, secrets, environments, cloud identity, artifacts, and write APIs | Confirm least privilege before execution. |
| What will it do? | Checkout behavior, install commands, shell steps, uploads, deployments, and external calls | Look for credential exposure, untrusted code execution, and unexpected side effects. |
| How is the decision recorded? | Approver, timestamp, revision, reason, and rollback owner | Make the approval auditable and reversible. |
Use a seven-step approval workflow
- Identify the source. Record who pushed or requested the run, whether the actor can influence workflow files, and whether the event came from a fork, issue, comment, schedule, or external automation.
- Bind the revision. Review the exact commit SHA and compare the workflow file at that revision with the expected change. Do not approve a moving branch reference.
- Read the complete workflow graph. Include called reusable workflows, composite actions, scripts, action references, and setup steps. A short top-level YAML file can still invoke a large privileged chain.
- Inventory permissions. Check the workflow and each job for explicit
permissions:. Identify tokens, environments, cloud federation, package credentials, and write access. Reduce scope before approval where possible. - Test a harmless path. In a disposable repository, exercise the same trigger with no production secrets and a read-only outcome. Preserve the run identifier and expected result.
- Verify the hold and denial path. Confirm a held run does not execute steps before approval, and that denial or cancellation prevents the consequential action. Test what happens when the workflow changes while a review is pending.
- Approve narrowly or stop. Approve only when the revision, actor, trigger, permissions, and intended output match the review record. If evidence is missing, leave the run held and escalate rather than widening permissions to make it pass.
Keep untrusted inputs outside privileged jobs
Workflow approval should not be used to normalize unsafe trigger design. Pull-request titles, bodies, issue comments, repository files from contributors, and downloaded artifacts can all carry attacker-controlled data. Keep parsing and testing of untrusted content in a job with no deployment credentials and minimal token permissions. Make the privileged job consume a bounded, reviewed output rather than rerunning arbitrary contributor code.
- Separate validation jobs from deployment jobs.
- Give
id-token: writeonly to the job that needs cloud federation. - Pin third-party actions to reviewed immutable references where practical.
- Use environment protection and required reviewers for production targets.
- Do not pass secrets to a job until the code and trigger boundary are known.
- Keep logs free of tokens, private paths, customer data, and secret-bearing command output.
Approval evidence is not execution evidence
Capture the approval decision separately from the run result. The approval tells you that a person allowed a particular run at a particular time; it does not prove that the workflow produced the expected artifact or that no later step accessed an unintended resource. After execution, reconcile the run logs, changed files, artifact digests, deployment record, and external provider audit trail. Treat missing logs or a changed revision as a failed evidence gate.
Failure modes to catch before production
| Symptom | Question | Safe response |
|---|---|---|
| Approval request has little context | Can the reviewer see the exact revision, diff, actor, and permissions? | Stop until the review record is complete. |
| A held run executes unexpectedly | Did another trigger, reusable workflow, or branch start a separate run? | Trace all run IDs and isolate the trigger before retrying. |
| Workflow asks for broad write access | Which step needs each permission? | Reduce permissions and split privileged work into a separate job. |
| Approval survives a material change | Is the approval bound to the current commit and workflow graph? | Invalidate the decision and review the new revision. |
| Logs contain sensitive output | Were tokens or private inputs printed before masking? | Stop, rotate affected credentials if needed, and restrict the evidence. |
FAQ
Does a workflow approval make the workflow safe?
No. It adds a checkpoint before execution for matching runs. The reviewer still needs to inspect the exact code, permissions, trigger, actions, secrets, and expected side effects.
Should every held run be approved by an administrator?
Use the repository’s ownership and deployment policy. The approver should have enough context and authority for the requested scope, but approval should not become a substitute for least privilege or separation of duties.
What if a pending workflow changes?
Reconcile the pending run’s commit and workflow graph. If the reviewed revision is no longer the executed revision, treat the prior approval as stale and require a new review.
Can I test this with production secrets?
Do not start there. Use a disposable or low-risk repository, a read-only operation, synthetic inputs, and no production credentials. Add real access only after the boundary and logs pass review.
Official sources and next step
- GitHub Changelog: GitHub Actions holds potentially malicious workflows for approval — the July 28, 2026 feature announcement.
- GitHub Docs: Security hardening for GitHub Actions — security guidance for workflow execution.
- GitHub Docs: Events that trigger workflows — trigger and event context.
- GitHub Docs: Assigning permissions to jobs — least-privilege permissions.
- GitHub Docs: Using workflow run logs — post-run evidence review.
For a compact AI-generated-change review, start with the free 5-point AI code review checklist. For a local, intent-bound review before merge, see the documented scope of the AI Change Firewall. Use the single CodeRiskTools comparison hub for scope context; none of these resources replaces GitHub controls or human judgment.
Approve the evidence, not just the prompt
Bind the approval to the exact revision, trigger, actor, permissions, workflow graph, expected output, and rollback owner. If any of those are unclear, leave the run held until the missing evidence is resolved.

