GitHub Actions workflows can control important parts of a software delivery process, from running tests to publishing packages and deploying applications. As repositories and teams grow, simply defining permissions inside individual workflow files is often not enough.
GitHub now provides workflow execution protections that let administrators control who can trigger workflows and which events are allowed to start them. These policies can be applied at the enterprise, organization, and repository level. GitHub also provides Evaluate mode, which allows teams to test a policy before enforcing it.
This is especially useful when introducing a new policy to repositories that already have dozens or hundreds of workflows. Instead of immediately blocking runs, you can first see which workflows would be affected and fix legitimate exceptions.
Why Test a Workflow Rule First?
A security rule can look simple:
Only maintainers can manually run deployment workflows.
But the actual environment may be more complicated.
A repository might have:
developers triggering test workflows manually
Dependabot starting dependency workflows
GitHub Apps starting automation
scheduled workflows
deployment workflows using
workflow_dispatchpull request workflows
reusable workflows called by other workflows
A policy that works perfectly for one repository may block legitimate automation in another.
GitHub's Evaluate mode addresses this by running the policy in a non-enforcing state. The rule is evaluated against workflow activity, and policy insights show workflow runs that would have been blocked.
The rollout can therefore look like this:
Create rule
|
v
Evaluate
|
v
Review affected runs
|
v
Fix legitimate cases
|
v
Enable enforcement
|
v
Monitor
This is much safer than enabling a restrictive policy immediately.
What Can Workflow Execution Rules Control?
GitHub's workflow execution protections currently focus on two important dimensions:
Actors
Events
GitHub also supports targeting specific workflow files, which allows different policies to be applied to different workflows in the same repository.
Actor Rules
Actor rules control who is allowed to trigger a workflow.
Depending on the policy, this can include users, repository roles, GitHub Apps, Copilot, and Dependabot.
For example, an organization might decide that only maintainers should manually start a release workflow.
Event Rules
Event rules control which GitHub Actions events are permitted.
Common examples include:
on:
push:
pull_request:
workflow_dispatch:
Other events, such as pull_request_target, can also be controlled through event policies.
This distinction is important because restricting a user and restricting an event solve different problems.
What Does Evaluate Mode Actually Do?
Evaluate mode is essentially a shadow test for your workflow policy.
Suppose you create this policy:
Policy: Restrict Manual Deployments
Allowed actor:
Maintainers
Allowed event:
workflow_dispatch
When the policy is active, a workflow that does not meet the rule can be blocked.
When the policy is in Evaluate mode, GitHub records the cases where the rule would have restricted workflow execution without applying the restriction. Policy insights can then be used to review those cases.
Conceptually:
Workflow Run
|
v
Evaluate Policy
|
+-------+-------+
| |
Allowed Would Block
| |
v v
Run normally Record insight
This makes Evaluate mode useful for discovering the real impact of a proposed policy.
Step 1: Inventory Your Existing Workflows
Before creating a rule, understand what already exists.
Start by reviewing the .github/workflows directory.
For example:
.github/
└── workflows/
├── build.yml
├── test.yml
├── release.yml
├── deploy-production.yml
└── dependency-update.yml
Do not assume these workflows all have the same security requirements.
Create a simple inventory:
Workflow | Main Purpose | Trigger | Sensitive Access |
|---|---|---|---|
| Build application |
| Low |
| Run tests |
| Low |
| Publish package |
| High |
| Production deployment |
| High |
| Dependency maintenance | Automated | Medium |
The exact classification will depend on the repository, but the exercise helps identify which workflows need stricter controls.
Step 2: Identify the Actors
Next, determine who or what actually triggers your workflows.
For a manual deployment workflow, you might have:
name: Production Deployment
on:
workflow_dispatch:
Possible users could include:
repository administrators
maintainers
developers
automation identities
GitHub Apps
GitHub notes that users with write access can generally trigger workflows unless actor restrictions are applied. Actor rules can separate the ability to contribute code from the ability to execute workflows.
This distinction is valuable for sensitive workflows.
A developer may need to push code but should not automatically receive permission to manually start a production deployment.
Step 3: Review the Events
Look at every on: declaration.
For example:
on:
push:
pull_request:
workflow_dispatch:
Then ask what each event means for your repository.
A push workflow might represent normal CI.
A pull_request workflow may run against proposed changes.
A workflow_dispatch workflow may represent an intentionally manual operation.
A pull_request_target workflow deserves additional scrutiny because of its access to the base repository context and potentially sensitive resources. GitHub is introducing a default protection against pull_request_target in affected public repositories, initially through Evaluate mode, with enforcement scheduled for November 2, 2026.
Step 4: Create the Policy in Evaluate Mode
GitHub provides workflow execution policies under the Actions policy settings.
At the repository or organization level, the workflow is configured through:
Settings
|
+-- Actions
|
+-- Policies
At the enterprise level, Actions policies are managed from the enterprise policy area. GitHub's documentation identifies repository administrators, organization owners, and enterprise owners as users who can manage these protections.
When creating the policy, choose Evaluate where the option is available.
GitHub currently documents Evaluate mode as available for GitHub Enterprise Cloud.
Step 5: Target the Correct Workflows
One of the useful additions to general availability is workflow file targeting.
Suppose your repository contains:
.github/workflows/
├── ci.yml
├── tests.yml
├── release.yml
└── production-deploy.yml
You may not want the same execution policy applied to all four workflows.
For example:
CI workflows
-> broad access
Release workflow
-> restricted actors
Production deployment
-> restricted actors + restricted events
GitHub's workflow execution protections allow policies to be scoped to specific workflow files.
This makes testing more precise because you can see the impact of the rule on the workflows that actually matter.
Step 6: Let Normal Automation Run
After the policy is configured in Evaluate mode, do not immediately start changing workflows just to make the policy pass.
Instead, allow normal development activity to continue.
For example:
A developer opens a pull request.
CI starts.
A maintainer manually starts a release workflow.
Dependabot creates an update.
A scheduled workflow executes.
A GitHub App starts automation.
The goal is to observe actual behavior.
This gives you more useful information than testing only one manually selected workflow run.
Step 7: Review Policy Insights
After enough workflow activity has occurred, review the policy insights.
GitHub provides insights showing workflow runs that would have been blocked by Evaluate policies. For active policies, the insights can show runs that were actually blocked.
Look for patterns such as:
Would Block
-----------
release.yml
Actor: developer
Event: workflow_dispatch
Would Block
-----------
dependency-update.yml
Actor: dependabot
Event: workflow_dispatch
The second case might be legitimate automation that needs to be added to the policy.
Do not treat every "would block" result as a problem. Some results may represent exactly the behavior you intended to prevent.
Step 8: Separate Expected Blocks From Unexpected Blocks
This is one of the most important parts of testing.
Create two groups:
Expected
These are workflow executions you intentionally want the policy to prevent.
Example:
Developer
|
+-- workflow_dispatch
|
+-- production-deploy.yml
If your policy is designed to prevent developers from manually deploying production, this is an expected block.
Unexpected
These are legitimate workflows that the new policy would interfere with.
Example:
Dependabot
|
+-- dependency workflow
|
+-- Would be blocked
If the repository depends on that automation, the policy needs to account for it.
This classification prevents teams from weakening a useful security policy simply because it reports blocked activity.
Testing workflow_dispatch
Manual workflows are a good starting point because their execution path is easy to understand.
Consider:
name: Release
on:
workflow_dispatch:
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build package
run: dotnet pack
- name: Publish package
run: ./publish.sh
The workflow may have access to publishing credentials or other sensitive resources.
A policy could restrict who can trigger it.
Before enforcement, test:
Developer -> workflow_dispatch
Maintainer -> workflow_dispatch
Release automation -> workflow_dispatch
Then inspect the policy insights.
This provides a concrete view of whether your actor rule matches the actual workflow usage.
Testing pull_request_target
This trigger deserves special attention.
A simplified example is:
name: Pull Request Automation
on:
pull_request_target:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Run checks
run: ./scripts/check.sh
The security concern is not simply the trigger itself. The risk depends on how the workflow handles untrusted pull request content, credentials, scripts, permissions, and repository resources.
GitHub has been adding protections around this area, including safer actions/checkout behavior and a new default execution policy for public repositories.
If your organization has legitimate use cases for pull_request_target, Evaluate mode provides a way to identify affected workflows before a restrictive event policy is enforced.
Testing Actor and Event Rules Together
Actor and event rules can interact.
Consider:
Allowed Actor:
Maintainers
Allowed Event:
workflow_dispatch
A workflow execution is acceptable only when both conditions are satisfied.
Actor | Event | Result Under Policy |
|---|---|---|
Maintainer |
| Allowed |
Developer |
| Blocked |
Maintainer |
| Blocked |
Developer |
| Blocked |
This is why testing only one dimension can give you an incomplete picture.
Always test the combinations that occur in your repositories.
Common Mistakes During Testing
Enabling Enforcement Too Early
The most obvious mistake is switching directly to enforcement without reviewing the impact.
Evaluate first when available.
Testing Only One Workflow
A policy that works for build.yml may cause problems for release.yml.
Test across the workflows included in the policy scope.
Ignoring Automated Actors
Do not test only human users.
Review automation such as Dependabot and GitHub Apps when those identities are part of your workflow architecture. GitHub specifically documents that identities associated with GitHub features may need to be included as allowed actors when custom workflows need to run under those identities.
Assuming a Block Is Always a Configuration Error
Some blocked executions are the desired result.
The purpose of the test is to determine whether the policy blocks the right things.
Making the Policy Too Broad
If only a deployment workflow requires strict protection, consider targeting that workflow instead of restricting every workflow in the repository.
Best Practices for Safe Rollout
Start With High-Risk Workflows
Begin with workflows that:
deploy production systems
publish packages
modify infrastructure
use sensitive credentials
perform administrative operations
Use Small, Focused Policies
GitHub recommends creating multiple clearly defined policies and layering protections rather than building one large policy for an entire account.
For example:
Policy 1
Production deployments
Policy 2
Manual release workflows
Policy 3
Pull request event restrictions
This is easier to reason about than one complicated rule.
Keep an Exception List
During evaluation, document legitimate cases that require special handling.
For example:
Workflow:
dependency-update.yml
Actor:
dependabot[bot]
Required event:
workflow_dispatch
Reason:
Automated dependency release process
This makes the eventual policy configuration easier to review.
Re-Test After Changes
If you change the workflow or policy during evaluation, continue observing the results.
Do not assume the first evaluation reflects the final state.
Advantages and Disadvantages
Advantages | Disadvantages |
|---|---|
Lets teams see potential impact before enforcement | Requires time to review workflow activity |
Helps identify legitimate automation | Evaluate mode availability depends on GitHub plan |
Reduces unexpected CI/CD disruption | Large organizations can generate many insights |
Supports targeted workflow policies | Policies can become complicated if poorly structured |
Useful for security and governance reviews | Requires ongoing maintenance as workflows change |
A Practical Testing Checklist
Before enabling a workflow execution policy, verify the following:
[ ] All affected workflows have been inventoried
[ ] Workflow triggers have been reviewed
[ ] Sensitive workflows have been identified
[ ] Human actors have been identified
[ ] Automated actors have been identified
[ ] Evaluate mode has been enabled where available
[ ] Policy insights have been reviewed
[ ] Expected blocks have been separated from unexpected blocks
[ ] Legitimate exceptions have been documented
[ ] Workflow targeting has been reviewed
[ ] pull_request_target workflows have been checked
[ ] Production workflows have been tested separately
[ ] Enforcement impact has been reviewed
Summary
Testing GitHub Actions workflow rules before enforcement is mainly about understanding real workflow behavior before changing the security boundary.
Evaluate mode provides a practical way to do this. Instead of immediately blocking workflow runs, teams can observe which executions would be affected and use policy insights to determine whether the result matches the intended security policy.
The most reliable approach is to inventory existing workflows, identify their actors and events, create focused policies, evaluate them against normal workflow activity, and investigate the resulting insights.
This is particularly important for production deployments, release automation, workflow_dispatch, and pull_request_target.
A workflow policy should ultimately block the executions you consider unsafe while allowing the automation your development and delivery process genuinely depends on. Testing the policy first gives teams a safer way to reach that balance.

Join the conversation! Your thoughts help the community grow.